Logo Search packages:      
Sourcecode: papaya version File versions  Download package

PythonPlugin.cpp

#if !defined (__MINGW32__)

/**
 * PythonPlugin is in part derived from the python plugin included as part
 * of mcl (http://www.andreasen.org/mcl/) which is distributed under the GPL.
 * Most of the mcl-derived code was rewritten or removed during the writing
 * of this module, but some of it probably still exists.
 *
 * PythonPlugin is also distributed under the GPL and was authored by
 * Catherine Allen (mango@turf.org).
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <regex.h>

#include <algorithm>

#ifdef WIN32
#define R_OK 0
#else
#include <dlfcn.h>
#endif

#ifdef USE_PYGTK
#include <pygtk/pygtk.h>
#endif

#include "Win32PluginAPI.cpp"
#include "PythonPlugin.h"

static PythonPlugin * py;

/* These lists have to be defined here and NOT in PythonPlugin.h, else
 * TurfProtocol gets a copy of them too, and trying to free them twice
 * results in the big bang.
 */

std::list<char *> outputFunctions;
typedef std::list<char *> OutputFunctionList;

std::list<char *> inputFunctions;
typedef std::list<char *> InputFunctionList;

std::list<char *> promptFunctions;
typedef std::list<char *> PromptFunctionList;

std::list<char *> eventFunctions;
typedef std::list<char *> EventFunctionList;

std::list<char *> turfFunctions;
typedef std::list<char *> TurfFunctionList;

#define MAJOR "1"
#define MINOR "2"

extern "C" G_MODULE_EXPORT void * python_get_python() {
  return (void *)py;
}

extern "C" G_MODULE_EXPORT char * plugin_query_name() {
  return "PythonPlugin";
}

extern "C" G_MODULE_EXPORT char * plugin_query_description() {
  return _("Allows execution of Python scripts as plugins.");
}

extern "C" G_MODULE_EXPORT char * plugin_query_major() {
  return MAJOR;
}

extern "C" G_MODULE_EXPORT char * plugin_query_minor() {
  return MINOR;
}

extern "C" G_MODULE_EXPORT void plugin_init(plugin_address_table_t * pat) {
      plugin_address_table_init(pat);
    py = new PythonPlugin();
}

extern "C" G_MODULE_EXPORT void plugin_cleanup(void) {
  delete py;
}

extern "C" PyObject * PythonPlugin_Send(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_SendTo(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_EventAdd(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_PromptAdd(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_OutputAdd(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_InputAdd(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_TurfAdd(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_PromptRemove(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_OutputRemove(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_InputRemove(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_EventRemove(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_TurfRemove(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_Message(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_TurfProtocolAdd(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_VTAppend(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_AddMenu(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_AddToTray(PyObject * self, PyObject * args);
extern "C" PyObject * PythonPlugin_RemoveFromTray(PyObject * self, PyObject * args);


static struct PyMethodDef methods[] = {
  { "send",              PythonPlugin_Send,            METH_VARARGS },
  { "sendto",            PythonPlugin_SendTo,          METH_VARARGS },
  { "event_add",         PythonPlugin_EventAdd,        METH_VARARGS },
  { "prompt_add",        PythonPlugin_PromptAdd,       METH_VARARGS },
  { "output_add",        PythonPlugin_OutputAdd,       METH_VARARGS },
  { "input_add",         PythonPlugin_InputAdd,        METH_VARARGS },
  { "turf_add",          PythonPlugin_TurfAdd,         METH_VARARGS },
  { "event_remove",      PythonPlugin_EventRemove,     METH_VARARGS },
  { "prompt_remove",     PythonPlugin_PromptRemove,    METH_VARARGS },
  { "output_remove",     PythonPlugin_OutputRemove,    METH_VARARGS },
  { "input_remove",      PythonPlugin_InputRemove,     METH_VARARGS },
  { "turf_remove",       PythonPlugin_TurfRemove,      METH_VARARGS },
  { "message",           PythonPlugin_Message,         METH_VARARGS },
  { "turf_protocol_add", PythonPlugin_TurfProtocolAdd, METH_VARARGS },
  { "vt_append",         PythonPlugin_VTAppend,        METH_VARARGS },
  { "add_menu",          PythonPlugin_AddMenu,         METH_VARARGS },
  { "add_to_tray",       PythonPlugin_AddToTray,       METH_VARARGS },
  { "remove_from_tray",  PythonPlugin_RemoveFromTray,  METH_VARARGS },
  { NULL,      NULL }
};

PythonPlugin::PythonPlugin() {
  version = 0.1;
  name = strdup("Python interpreter.");

  char ** argv = (char **)malloc(16);
  argv[0] = NULL;

  Py_Initialize();
  PySys_SetArgv(0, argv);
  module = PyImport_AddModule("__main__");
  globals = PyModule_GetDict(module);
  Py_INCREF(globals);

  Py_InitModule("papaya", methods);
  if (PyErr_Occurred())
    printf("Couldn't initialize module.\n");

  if (loadFile("init.py", false)) {
    free(argv);
    return;
  }

  register_plugin(this, VERSION);
  plugin_handler_add_input_filter(get_plugin_handler(), this);
  plugin_handler_add_output_filter(get_plugin_handler(), this);
  plugin_handler_add_prompt_filter(get_plugin_handler(), this);

  free(argv);

}

PythonPlugin::~PythonPlugin() {
  Py_DECREF(globals);
  Py_Finalize();

  unregister_plugin(this);
}

static int FunctionCmp(char * c1, char * c2) {
  if (!c1)
    return 1;

  if (!c2)
    return 0;

  return 0;
}

void python_turf_callback(Connection * c, char * buf, void * data) {

  char * callback = strdup((char *)data);
  char * argument;
  char result[16384];

  argument = strchr(callback, ':');
  if (!argument) {
    printf("PythonPlugin: error discerning user_data and callback function.\n");
    free(callback);
    return;
  }

  *argument = '\0';
  argument++;

  py->set("papaya_connection", connection_get_name(c));
  py->runFunction(callback, buf, argument, result);
  py->set("papaya_connection", "");

  free(callback);

  // We now need to free data since TP no longer does this.
  if (!buf) // Last TP callback
    free(data);
}

extern "C" PyObject * PythonPlugin_TurfProtocolAdd(PyObject * self, PyObject * args) {

  char * command;
  char * callback;
  char * argument;
  if (!PyArg_ParseTuple(args, "sss", &command, &callback, &argument)) {
    printf("papaya.turf_protocol_add: syntax: papaya.turf_protocol_add(command, callback, argument)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Figure out which connection to send this to.
  char * conn = py->getString("papaya_connection");
  
  Connection * c = get_connection_by_name(conn);
  if (!c) {
    printf("PythonPlugin: papaya.turf_protocol_add: unable to find active connection.\n");
    return Py_BuildValue("i", 0);
  }

  if (!turf_protocol_is_supported(c)) {
    printf("papaya.turf_protocol_add: TurfProtocol is not currently enabled or loaded, so this python plugin may not function correctly.\n");
    return Py_BuildValue("i", 0);
  }

  char * callback_argument = (char *)malloc(strlen(callback) + strlen(argument) + 2);
  snprintf(callback_argument, strlen(callback) + strlen(argument) + 2,
         "%s:%s", callback, argument);

  turf_protocol_add_command(c, command, (void *)python_turf_callback, (void *)callback_argument);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_AddToTray(PyObject * self, PyObject * args) {
#ifdef USE_PYGTK
  PyGObject * object;
  // PyGtk 1.x
  //  PyGtk_Object * object;
  GtkWidget * widget;
  GtkWidget * frame = NULL;

  if (!PyArg_ParseTuple(args, "O", &object)) {
    printf ("PythonPlugin: papaya.add_to_tray(widget)\n");
    return Py_BuildValue("i", 0);
  }
  
  /* Convert a PyGtk_Object to GtkWidget */
  widget = GTK_WIDGET(pygobject_get(object));
  //  widget = GTK_WIDGET (PyGtk_Get (object));

  // Figure out the current connection
  char * conn = py->getString("papaya_connection");
  Connection * c = get_connection_by_name(conn);
  if (!c) {
    printf("PythonPlugin: papaya.add_to_tray: unable to find active connection.\n");
    return Py_BuildValue("i", 0);
  }
  
  vt_add_to_tray(connection_get_vt(c), widget, &frame);

  // @@ Arrange to return the frame's memory address.
  //  return PyGtk_New((GtkObject *)frame);
#endif
  return Py_BuildValue("i", 0);
}

extern "C" PyObject * PythonPlugin_RemoveFromTray(PyObject * self, PyObject * args) {
#ifdef USE_PYGTK
  PyGObject * wid_object;
  //  PyGtk_Object * wid_object;
  GtkWidget * widget;

  if (!PyArg_ParseTuple(args, "O", &wid_object)) {
    printf ("PythonPlugin: papaya.remove_from_tray(widget)\n");
    return Py_BuildValue("i", 0);
  }

  widget = GTK_WIDGET(pygobject_get(wid_object));
  //  widget = GTK_WIDGET(PyGtk_Get(wid_object));
  
  char * conn = py->getString("papaya_connection");
  Connection * c = get_connection_by_name(conn);
  if (!c) {
    printf("PythonPlugin: papaya.remove_from_tray: unable to find active connection.\n");
    return Py_BuildValue("i", 0);
  }

  // @@ We need to figure out which is the frame for this widget.
  GtkWidget * frame = NULL;
  vt_remove_from_tray(connection_get_vt(c), widget, frame);
#endif
  return Py_BuildValue("i", 1);
}

extern "C" void PythonPlugin_MenuCallback(GtkWidget * widget, gpointer data, gint foo) {

  char * callback = (char *) data;
  if (!callback) {
    printf ("PythonPlugin_MenuCallback: menu item selected, but no callback function");
    return;
  }

  char result[16384];
  result[0] = '\0';

  py->set("papaya_connection", connection_get_name(main_window_get_current_connection(get_main_window())));
  py->runFunction(callback, NULL, NULL);
  py->set("papaya_connection", "");

}

extern "C" PyObject * PythonPlugin_AddMenu(PyObject * self, PyObject * args) {

  char * menu_name, * shortcut, * python_callback, * special;

  if (!PyArg_ParseTuple(args, "ssss", &menu_name, &shortcut, &python_callback, &special)) {
    printf("papaya.add_menu: syntax: papaya.add_menu(string path, string shortcut, string callback, string special)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Sanitise our arguments.
  if (shortcut && *shortcut == '\0')
    shortcut = NULL;

  GtkItemFactory * factory = main_window_get_item_factory(get_main_window());

  // If special is set, then no callback
  GtkItemFactoryEntry entry = { menu_name, shortcut, *special != '\0' ? NULL : (GtkItemFactoryCallback) PythonPlugin_MenuCallback, 0, special };
  gtk_item_factory_create_item(factory, &entry, python_callback ? strdup(python_callback) : NULL, 2);

  return Py_BuildValue("i", 1);

  // @@ How do we remove a menu?

  /*  
  GtkItemFactoryEntry turf_entry = { TURF_MENU, NULL, NULL, 0, "<Branch>" };
  GtkItemFactoryEntry connect_four_entry = { C4_MENU, "<control>4", (GtkItemFactoryCallback)c4_get_players, 0 };

  gtk_item_factory_create_item(factory, &turf_entry, NULL, 2);
  gtk_item_factory_create_item(factory, &connect_four_entry, NULL, 2);
*/
}

extern "C" PyObject * PythonPlugin_VTAppend(PyObject * self, PyObject * args) {

  char * text;

  if (!PyArg_ParseTuple(args, "s", &text)) {
    printf("papaya.vt_append: syntax: papaya.vt_append(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  char * conn = py->getString("papaya_connection");
  Connection * c = get_connection_by_name(conn);
  if (!c) {
    printf("PythonPlugin: papaya.vt_append: unable to find active connection.\n");
    return Py_BuildValue("i", 0);
  }

  vt_append(connection_get_vt(c), text);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_Message(PyObject * self, PyObject * args) {

  char * title;
  char * message;

  if (!PyArg_ParseTuple(args, "ss", &title, &message)) {
    printf("papaya.message: syntax: papaya.message(title, message)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  message_new(title, message, false);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_EventRemove(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("papaya.event_remove: syntax: papaya.event_remove(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  EventFunctionList::iterator i = std::lower_bound(eventFunctions.begin(),
                                       eventFunctions.end(),
                                       function,
                                       FunctionCmp);
  if (i == eventFunctions.end() || strcmp((*i), function))
    return Py_BuildValue("i", 0);

  eventFunctions.erase(i);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_TurfRemove(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("papaya.event_remove: syntax: papaya.turf_remove(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  TurfFunctionList::iterator i = std::lower_bound(turfFunctions.begin(),
                                       turfFunctions.end(),
                                       function,
                                       FunctionCmp);
  if (i == turfFunctions.end() || strcmp((*i), function))
    return Py_BuildValue("i", 0);

  turfFunctions.erase(i);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_OutputRemove(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("papaya.event_remove: syntax: papaya.output_remove(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  OutputFunctionList::iterator i = std::lower_bound(outputFunctions.begin(),
                                       outputFunctions.end(),
                                       function,
                                       FunctionCmp);
  if (i == outputFunctions.end() || strcmp((*i), function))
    return Py_BuildValue("i", 0);

  outputFunctions.erase(i);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_InputRemove(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("papaya.event_remove: syntax: papaya.input_remove(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  InputFunctionList::iterator i = std::lower_bound(inputFunctions.begin(),
                                       inputFunctions.end(),
                                       function,
                                       FunctionCmp);
  if (i == eventFunctions.end() || strcmp((*i), function))
    return Py_BuildValue("i", 0);

  inputFunctions.erase(i);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_PromptRemove(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("papaya.event_remove: syntax: papaya.event_remove(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  PromptFunctionList::iterator i = std::lower_bound(promptFunctions.begin(),
                                       promptFunctions.end(),
                                       function,
                                       FunctionCmp);
  if (i == eventFunctions.end() || strcmp((*i), function))
    return Py_BuildValue("i", 0);

  promptFunctions.erase(i);
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_EventAdd(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("PythonPlugin: event_add has bad arguments.\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Add this function to the list of functions.
  EventFunctionList::iterator i = std::lower_bound(eventFunctions.begin(),
                                       eventFunctions.end(),
                                       function,
                                       FunctionCmp);
  eventFunctions.insert(i, function);

  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_TurfAdd(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("PythonPlugin: turf_add has bad arguments.\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Add this function to the list of functions.
  TurfFunctionList::iterator i = std::lower_bound(turfFunctions.begin(),
                                      turfFunctions.end(),
                                      function,
                                      FunctionCmp);
  turfFunctions.insert(i, function);

  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_PromptAdd(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("PythonPlugin: output_add has bad arguments.\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Add this function to the list of functions.
  PromptFunctionList::iterator i = std::lower_bound(promptFunctions.begin(),
                                        promptFunctions.end(),
                                        function,
                                        FunctionCmp);
  promptFunctions.insert(i, function);

  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_OutputAdd(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("PythonPlugin: output_add has bad arguments.\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Add this function to the list of functions.
  OutputFunctionList::iterator i = std::lower_bound(outputFunctions.begin(),
                                    outputFunctions.end(),
                                    function,
                                    FunctionCmp);
  outputFunctions.insert(i, function);

  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_InputAdd(PyObject * self, PyObject * args) {
  char * function;

  if (!PyArg_ParseTuple(args, "s", &function)) {
    printf("PythonPlugin: output_add has bad arguments.\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // Add this function to the list of functions.
  InputFunctionList::iterator i = std::lower_bound(inputFunctions.begin(),
                                    inputFunctions.end(),
                                    function,
                                    FunctionCmp);
  inputFunctions.insert(i, function);

  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_SendTo(PyObject * self, PyObject * args) {
  char * to;
  char * string;

  if (!PyArg_ParseTuple(args, "ss", &to, &string)) {
    printf("papaya.sendto: syntax: papaya.sendto(string, string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  Connection * c = get_connection_by_name(to);
  if (!c) {
    printf("papaya.sendto: %s is not a valid connection.\n", to);
    return Py_BuildValue("i", 0);
  }

  socket_write(connection_get_socket(c), string, strlen(string));
  socket_write(connection_get_socket(c), "\n", 1);
  
  return Py_BuildValue("i", 1);
}

extern "C" PyObject * PythonPlugin_Send(PyObject * self, PyObject * args) {
  char * string;

  if (!PyArg_ParseTuple(args, "s", &string)) {
    printf("PythonPlugin: Syntax: papaya.send(string)\n");
    PyErr_Print();
    return Py_BuildValue("i", 0);
  }

  // The send function should be able to figure out which Connection is
  // active.
  char * conn = py->getString("papaya_connection");

  Connection * c = get_connection_by_name(conn);
  if (!c) {
    printf("PythonPlugin: papaya.send: unable to find active connection.\n");
    return Py_BuildValue("i", 0);
  }

  socket_write(connection_get_socket(c), string, strlen(string));
  socket_write(connection_get_socket(c), "\n", 1);

  return Py_BuildValue("i", 1);
}

extern Prefs * preferences;

char * PythonPlugin::getDescription() {
  return "Execution of Python scripts on MUD events.";
}

void PythonPlugin::onEvent(Event * e, Connection * c) {

  char buf[1024];

  snprintf(buf, 1024, "%s", event_get_type(e) == EvConnect ? "connect" : "disconnect");

  for (EventFunctionList::iterator i = eventFunctions.begin(); i != eventFunctions.end(); ++i) {
    set("papaya_connection", connection_get_name(c));
    runFunction((*i), buf, NULL);
  }

  set("papaya_connection", "");
}

/**
 * Input from the user.
 */

void PythonPlugin::input(Connection * c, char * str) {
  char result[16384];

  if (!strncasecmp(str, "python ", 7)) {
      char * file = str + 7;
    set("papaya_connection", connection_get_name(c));
    loadFile(file, false);
    set("papaya_connection", "");
    str[0] = '\0';
    return;
  }

  snprintf(result, 16384, "%s", str);

  for (InputFunctionList::iterator i = inputFunctions.begin(); i != inputFunctions.end(); ++i) {

    set("papaya_connection", connection_get_name(c));
    runFunction((*i), result, result);
  }

  if (strcmp(result, str))
    sprintf(str, "%s", result);

  set("papaya_connection", "");
}


/**
 * Output from the MUD.
 */

void PythonPlugin::output(Connection * c, char * str) {
  char result[16384];

  snprintf(result, 16384, "%s", str);
  // Find out if there are any loaded python functions to do output processing.
  for (OutputFunctionList::iterator i = outputFunctions.begin(); i != outputFunctions.end(); ++i) {
    set("papaya_connection", connection_get_name(c));
    runFunction((*i), result, result);
  }

  if (strcmp(result, str))
    sprintf(str, "%s", result);

  set("papaya_connection", "");
}

/**
 * Prompt from the MUD.
 */

void PythonPlugin::prompt(Connection * c, char * str) {
  char result[16384];

  snprintf(result, 16384, "%s", str);

  // Find out if there are any loaded python functions to do output processing.

  for (PromptFunctionList::iterator i = promptFunctions.begin(); i != promptFunctions.end(); ++i) {
    set("papaya_connection", connection_get_name(c));
    runFunction((*i), result, result);
  }

  set("papaya_connection", "");
  if (strcmp(result, str))
    sprintf(str, "%s", result);

}

/**
 * Turf Client Protocol messages.
 */

void PythonPlugin::clientMessage(Connection * c, char * str) {
  char result[16384];

  snprintf(result, 16384, "%s", str);

  for (TurfFunctionList::iterator i = turfFunctions.begin(); i != turfFunctions.end(); ++i) {
    set("papaya_connection", connection_get_name(c));
    runFunction((*i), result, result);
  }

  set("papaya_connection", "");
  if (strcmp(result, str))
    sprintf(str, "%s", result);

}

void PythonPlugin::set(const char * name, long value) {
  PyObject * obj = Py_BuildValue("l", value);
  
  if (!obj) {
    PyErr_Print();
    return;
  }

  PyDict_SetItemString(globals, (char *)name, obj);
  Py_DECREF(obj);
}

void PythonPlugin::set(const char * name, int value) {

  PyObject * obj = Py_BuildValue("i", value);
  
  if (!obj) {
    PyErr_Print();
    return;
  }

  PyDict_SetItemString(globals, (char *)name, obj);
  Py_DECREF(obj);
}

void PythonPlugin::set(const char * name, const char * value) {
  PyObject * obj = Py_BuildValue("s", value);

  if (!obj) {
    PyErr_Print();
    return;
  }

  PyDict_SetItemString(globals, (char *)name, obj);
  Py_DECREF(obj);
}

long PythonPlugin::getLong(const char * name) {

  PyObject * obj = PyDict_GetItemString(globals, (char *)name);
  long i;

  if (!obj) {
    PyErr_Print();
    return 0;
  }

  PyArg_Parse(obj, "l", &i);
  return i;
}

int PythonPlugin::getInt(const char * name) {

  PyObject * obj = PyDict_GetItemString(globals, (char *)name);
  int i;

  if (!obj) {
    PyErr_Print();
    return 0;
  }

  PyArg_Parse(obj, "i", &i);
  return i;
}

char * PythonPlugin::getString(const char * name) {
  
  PyObject * obj = PyDict_GetItemString(globals, (char *)name);
  char * str;

  if (!obj) {
    PyErr_Print();
    return NULL;
  }

  PyArg_Parse(obj, "s", &str);
  return str;
}

PyObject * PythonPlugin::getFunction(const char * name) {
  return PyDict_GetItemString(globals, (char *)name);
}

PyObject * PythonPlugin::codeCompile(const char * code) {
  PyObject * code_obj;

  if (!(code_obj = Py_CompileString((char *)code, "<string>", Py_file_input)))
    PyErr_Print();
  return code_obj;
}

bool PythonPlugin::runFunction(const char * function, const char * args, char * result) {

  PyObject * func = getFunction(function);
  PyObject * func_args, * res;
  PyObject * pValue = NULL;

  if (!func)
    return false;

  if (args) {
    func_args = PyTuple_New(1);
    pValue = PyString_FromString(args);
    PyTuple_SetItem(func_args, 0, pValue);
  } else {
    func_args = PyTuple_New(0);
  }
  
  res = PyEval_CallObject(func, func_args);
  if (!res) {
    PyErr_Print();
    return false;
  }

  // Retrieve the result of the function.
  if (result)
    snprintf(result, 16384, "%s", PyString_AsString(res));

  Py_DECREF(func_args);
  Py_DECREF(res);
  return true;
}

bool PythonPlugin::runFunction(const char * function, const char * args, const char * extra_arg, char * result) {

  PyObject * func = getFunction(function);
  PyObject * func_args, * res;

  /*
  if (!isEnabled(function))
    return false;
  */

  if (!func) {
      char * str = (char *)malloc(strlen(function) + 4);
    sprintf(str, "%s.py", function);
    if (!loadFile(str, false) && !(func = getFunction(function))) {
      printf("Could not find function '%s' anywhere.\n", function);
      /*
      disable_function(function);
      */
        free(str);
      return false;
    }
      free(str);
  }

  func_args = PyTuple_New(2);

  if (args) {
    PyObject * pValue = PyString_FromString(args);
    PyTuple_SetItem(func_args, 0, pValue);
    pValue = PyString_FromString(extra_arg);
    PyTuple_SetItem(func_args, 1, pValue);
  } else {
    Py_INCREF(Py_None);
    PyTuple_SetItem(func_args, 0, Py_None);
    PyObject * pValue = PyString_FromString(extra_arg);
    PyTuple_SetItem(func_args, 1, pValue);
  }
  
  res = PyEval_CallObject(func, func_args);
  if (!res) {
    PyErr_Print();
    return false;
  }

  //  snprintf(result, 16384, "%s", PyString_AsString(res));

  Py_DECREF(func_args);
  Py_DECREF(res);
  return true;
}

char * PythonPlugin::findFile(const char * filename, const char * suffix) {

  static char file[1024];
  static char full[1024];

  struct stat statbuf;
  
  // Add suffix if not there already
  if (strlen(filename) < strlen(suffix)
      || strcmp(filename + strlen(filename) - strlen(suffix), suffix))
    snprintf(file, 1024, "%s%s", filename, suffix);
  else
    snprintf(file, 1024, "%s", filename);

  if (file[0] != '/') {
#ifndef WIN32
        snprintf(full, 1024, "%s/.papaya/%s", getenv("HOME"), file);
#else
        snprintf(full, 1024, "python/%s", file);
#endif

        if (stat(full, &statbuf) == 0)
              return full;

#ifdef WIN32
    snprintf(full, 1024, "%s/python/%s", get_prefix(), file);
#else
      snprintf(full, 1024, "%s/share/papaya/python/%s", get_prefix(), file);
#endif

    if (stat(full, &statbuf) == 0)
            return full;
  }
 
  if (stat(file, &statbuf) == 0)
        return file;
  
  return NULL;
}

bool PythonPlugin::loadFile(const char * file, bool suppress) {

  FILE *script = NULL;
  PyObject *obj;
  const char *fullname = findFile(file, ".py");

  fullname = findFile(file, ".py");
  if (!fullname) {
    return false;
  }
  
  script = fopen(fullname, "r");
  if (!script) {
    printf ("Unable to open %s for execution by Python.\n", fullname);
    return false;
  }
  
  printf ("Now trying to run %s.\n", fullname);
#ifdef WIN32
  char contents[65536];
  struct stat statbuf;
  
  stat(fullname, &statbuf);
  if (statbuf.st_size > 65535) {
    printf ("PythonPlugin: Cannot load plugin, greater than 65535 bytes in length.\n");
    fclose(script);
    return false;
  }
  
  fread(contents, 1, statbuf.st_size, script);
  contents[statbuf.st_size] = '\0';
  if (!(obj = PyRun_String(contents, Py_file_input, globals, globals))) {
    PyErr_Print();
    fclose(script);
    return false;
  }
#else
  if(!(obj = PyRun_File(script, (char*)fullname, Py_file_input, globals, globals))) {
    if (!suppress)
      PyErr_Print();
    fclose(script);
    return false;
  }
#endif
  Py_DECREF(obj);
  
  fclose(script);
  return true;
}

extern "C" int python_alias_exec(char * body, void * data, void * arg) {
  Connection * c = (Connection *)data;
  char * args = (char *)arg;

  py->set("papaya_connection", connection_get_name(c));
  py->set("args", args);

  return PyRun_SimpleString(body);
  py->set("args", "");
  py->set("papaya_connection", "");
}


#endif // MINGW32

Generated by  Doxygen 1.6.0   Back to index