[Commits] [SCM] claws branch, master, updated. 3.9.2-13-gb5b6975

holger at claws-mail.org holger at claws-mail.org
Tue Jun 11 23:30:59 CEST 2013


The branch master of project "claws" (Claws Mail) has been updated
       via  b5b69753f875f9515fc61216899dbc8a51660b7a (commit)
       via  67df492152493bec7f3c645403d7efd3415df6ae (commit)
       via  dd677bd0e6fe5d7082640032f18deffb2ca778b0 (commit)
       via  75722552afbdbb82f35b90ce2aef74e648b9634f (commit)
      from  7be9b13b35cf265f9b64657c6dfd6515f3d6f46a (commit)


- Log -----------------------------------------------------------------
commit b5b69753f875f9515fc61216899dbc8a51660b7a
Author: Holger Berndt <hb at claws-mail.org>
Date:   Tue Jun 11 23:27:28 2013 +0200

    Python plugin: Improve error reporting during plugin init

diff --git a/src/plugins/python/clawsmailmodule.c b/src/plugins/python/clawsmailmodule.c
index e0a3a5d..c34283e 100644
--- a/src/plugins/python/clawsmailmodule.c
+++ b/src/plugins/python/clawsmailmodule.c
@@ -519,7 +519,7 @@ static gboolean get_message_list_for_move_or_copy(PyObject *messagelist, PyObjec
 {
   Py_ssize_t size, iEl;
   FolderItem *folderitem;
-  
+
   *list = NULL;
 
   folderitem = clawsmail_folder_get_item(folder);
@@ -537,17 +537,17 @@ static gboolean get_message_list_for_move_or_copy(PyObject *messagelist, PyObjec
       PyErr_SetString(PyExc_TypeError, "Argument must be a list of MessageInfo objects.");
       return FALSE;
     }
-    
+
     msginfo = clawsmail_messageinfo_get_msginfo(element);
     if(!msginfo) {
       PyErr_SetString(PyExc_LookupError, "Broken MessageInfo object.");
       return FALSE;
     }
-   
+
     procmsg_msginfo_set_to_folder(msginfo, folderitem);
     *list = g_slist_prepend(*list, msginfo);
   }
- 
+
   return TRUE;
 }
 
@@ -557,23 +557,23 @@ static PyObject* move_or_copy_messages(PyObject *self, PyObject *args, gboolean
   PyObject *folder;
   int retval;
   GSList *list = NULL;
-  
+
   retval = PyArg_ParseTuple(args, "O!O!",
     &PyList_Type, &messagelist,
     clawsmail_folder_get_type_object(), &folder);
   if(!retval )
-    return NULL;  
+    return NULL;
 
   folder_item_update_freeze();
-  
+
   if(!get_message_list_for_move_or_copy(messagelist, folder, &list))
     goto err;
-  
-  if(move)   
+
+  if(move)
     procmsg_move_messages(list);
   else
     procmsg_copy_messages(list);
-      
+
   folder_item_update_thaw();
   g_slist_free(list);
   Py_RETURN_NONE;
@@ -602,7 +602,7 @@ static PyMethodDef ClawsMailMethods[] = {
      "\n"
      "Returns the gtk.ActionGroup for the main window."},
 
-    {"get_mainwindow_ui_manager",  get_mainwindow_ui_manager, METH_NOARGS, 
+    {"get_mainwindow_ui_manager",  get_mainwindow_ui_manager, METH_NOARGS,
      "get_mainwindow_ui_manager() - get ui manager of main window\n"
      "\n"
      "Returns the gtk.UIManager for the main window."},
@@ -705,8 +705,9 @@ static PyMethodDef ClawsMailMethods[] = {
     {NULL, NULL, 0, NULL}
 };
 
-static void initmiscstuff(PyObject *module)
+static gboolean add_miscstuff(PyObject *module)
 {
+  gboolean retval;
   PyObject *dict;
   PyObject *res;
   const char *cmd =
@@ -719,14 +720,15 @@ static void initmiscstuff(PyObject *module)
       "\n";
   dict = PyModule_GetDict(module);
   res = PyRun_String(cmd, Py_file_input, dict, dict);
+  retval = (res != NULL);
   Py_XDECREF(res);
+  return retval;
 }
 
 
-void claws_mail_python_init(void)
+PyMODINIT_FUNC initclawsmail(void)
 {
-  if (!Py_IsInitialized())
-      Py_Initialize();
+  gboolean ok = TRUE;
 
   /* create module */
   cm_module = Py_InitModule3("clawsmail", ClawsMailMethods,
@@ -740,17 +742,19 @@ void claws_mail_python_init(void)
       "The interface to Claws Mail in this module is extended on a 'as-needed' basis.\n"
       "If you're missing something specific, try contacting the author.");
 
+  /* add module member "compose_window" set to None */
+  Py_INCREF(Py_None);
+  PyModule_AddObject(cm_module, "compose window", Py_None);
+
   /* initialize classes */
-  initnode(cm_module);
-  initcomposewindow(cm_module);
-  initfolder(cm_module);
-  initmessageinfo(cm_module);
+  ok = ok && cmpy_add_node(cm_module);
+  ok = ok && cmpy_add_composewindow(cm_module);
+  ok = ok && cmpy_add_folder(cm_module);
+  ok = ok && cmpy_add_messageinfo(cm_module);
 
   /* initialize misc things */
-  initmiscstuff(cm_module);
-
-  PyRun_SimpleString("import clawsmail\n");
-  PyRun_SimpleString("clawsmail.compose_window = None\n");
+  if(ok)
+    add_miscstuff(cm_module);
 }
 
 
diff --git a/src/plugins/python/clawsmailmodule.h b/src/plugins/python/clawsmailmodule.h
index 21846a6..1f1056f 100644
--- a/src/plugins/python/clawsmailmodule.h
+++ b/src/plugins/python/clawsmailmodule.h
@@ -24,8 +24,11 @@
 
 #include "compose.h"
 
+#ifndef PyMODINIT_FUNC
+# define PyMODINIT_FUNC void
+#endif
 
-void claws_mail_python_init(void);
+PyMODINIT_FUNC initclawsmail(void);
 
 PyObject* get_gobj_from_address(gpointer addr);
 void put_composewindow_into_module(Compose *compose);
diff --git a/src/plugins/python/composewindowtype.c b/src/plugins/python/composewindowtype.c
index 59ebeea..110296b 100644
--- a/src/plugins/python/composewindowtype.c
+++ b/src/plugins/python/composewindowtype.c
@@ -585,14 +585,14 @@ static PyTypeObject clawsmail_ComposeWindowType = {
     0,                         /* tp_new */
 };
 
-PyMODINIT_FUNC initcomposewindow(PyObject *module)
+gboolean cmpy_add_composewindow(PyObject *module)
 {
-    clawsmail_ComposeWindowType.tp_new = PyType_GenericNew;
-    if(PyType_Ready(&clawsmail_ComposeWindowType) < 0)
-        return;
+  clawsmail_ComposeWindowType.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&clawsmail_ComposeWindowType) < 0)
+    return FALSE;
 
-    Py_INCREF(&clawsmail_ComposeWindowType);
-    PyModule_AddObject(module, "ComposeWindow", (PyObject*)&clawsmail_ComposeWindowType);
+  Py_INCREF(&clawsmail_ComposeWindowType);
+  return (PyModule_AddObject(module, "ComposeWindow", (PyObject*)&clawsmail_ComposeWindowType) == 0);
 }
 
 PyObject* clawsmail_compose_new(PyObject *module, Compose *compose)
diff --git a/src/plugins/python/composewindowtype.h b/src/plugins/python/composewindowtype.h
index 4d7b422..9de8546 100644
--- a/src/plugins/python/composewindowtype.h
+++ b/src/plugins/python/composewindowtype.h
@@ -18,15 +18,13 @@
 #ifndef COMPOSEWINDOWTYPE_H
 #define COMPOSEWINDOWTYPE_H
 
+#include <glib.h>
 #include <Python.h>
 
 #include "compose.h"
 
-#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
 
-PyMODINIT_FUNC initcomposewindow(PyObject *module);
+gboolean cmpy_add_composewindow(PyObject *module);
 
 PyObject* clawsmail_compose_new(PyObject *module, Compose *compose);
 
diff --git a/src/plugins/python/foldertype.c b/src/plugins/python/foldertype.c
index 3d36223..ccf5806 100644
--- a/src/plugins/python/foldertype.c
+++ b/src/plugins/python/foldertype.c
@@ -20,7 +20,6 @@
 #include "claws-features.h"
 #endif
 
-#include <glib.h>
 #include <glib/gi18n.h>
 
 #include "foldertype.h"
@@ -70,10 +69,10 @@ static int Folder_init(clawsmail_FolderObject *self, PyObject *args, PyObject *k
   /* optional constructor argument: folderitem id string */
   if(!PyArg_ParseTuple(args, "|sb", &ss, &create))
     return -1;
-  
+
   Py_INCREF(Py_None);
   self->name = Py_None;
-  
+
   Py_INCREF(Py_None);
   self->path = Py_None;
 
@@ -146,14 +145,14 @@ static PyObject* Folder_get_messages(clawsmail_FolderObject *self, PyObject *arg
     Py_INCREF(Py_None);
     return Py_None;
   }
-  
+
   for(pos = 0, walk = msglist; walk; walk = walk->next, ++pos) {
     PyObject *msg;
     msg = clawsmail_messageinfo_new(walk->data);
     PyTuple_SET_ITEM(retval, pos, msg);
   }
   procmsg_msg_list_free(msglist);
-  
+
   return retval;
 }
 
@@ -172,10 +171,10 @@ static PyMethodDef Folder_methods[] = {
 static PyMemberDef Folder_members[] = {
   {"name", T_OBJECT_EX, offsetof(clawsmail_FolderObject, name), 0,
    "name - name of folder"},
-  
+
   {"path", T_OBJECT_EX, offsetof(clawsmail_FolderObject, path), 0,
    "path - path of folder"},
-  
+
   {"mailbox_name", T_OBJECT_EX, offsetof(clawsmail_FolderObject, mailbox_name), 0,
    "mailbox_name - name of the corresponding mailbox"},
 
@@ -228,14 +227,14 @@ static PyTypeObject clawsmail_FolderType = {
     0,                         /* tp_new */
 };
 
-PyMODINIT_FUNC initfolder(PyObject *module)
+gboolean cmpy_add_folder(PyObject *module)
 {
-    clawsmail_FolderType.tp_new = PyType_GenericNew;
-    if(PyType_Ready(&clawsmail_FolderType) < 0)
-        return;
+  clawsmail_FolderType.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&clawsmail_FolderType) < 0)
+    return FALSE;
 
-    Py_INCREF(&clawsmail_FolderType);
-    PyModule_AddObject(module, "Folder", (PyObject*)&clawsmail_FolderType);
+  Py_INCREF(&clawsmail_FolderType);
+  return (PyModule_AddObject(module, "Folder", (PyObject*)&clawsmail_FolderType) == 0);
 }
 
 PyObject* clawsmail_folder_new(FolderItem *folderitem)
diff --git a/src/plugins/python/foldertype.h b/src/plugins/python/foldertype.h
index 7a913b1..d85d483 100644
--- a/src/plugins/python/foldertype.h
+++ b/src/plugins/python/foldertype.h
@@ -18,15 +18,14 @@
 #ifndef FOLDERTYPE_H
 #define FOLDERTYPE_H
 
+#include <glib.h>
 #include <Python.h>
 
 #include "folder.h"
 
-#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
 
-PyMODINIT_FUNC initfolder(PyObject *module);
+
+gboolean cmpy_add_folder(PyObject *module);
 
 PyObject* clawsmail_folder_new(FolderItem *folderitem);
 FolderItem* clawsmail_folder_get_item(PyObject *self);
diff --git a/src/plugins/python/messageinfotype.c b/src/plugins/python/messageinfotype.c
index 766b29a..77d5724 100644
--- a/src/plugins/python/messageinfotype.c
+++ b/src/plugins/python/messageinfotype.c
@@ -20,7 +20,6 @@
 #include "claws-features.h"
 #endif
 
-#include <glib.h>
 #include <glib/gi18n.h>
 
 #include "messageinfotype.h"
@@ -374,14 +373,14 @@ static PyTypeObject clawsmail_MessageInfoType = {
     0,                         /* tp_new */
 };
 
-PyMODINIT_FUNC initmessageinfo(PyObject *module)
+gboolean cmpy_add_messageinfo(PyObject *module)
 {
-    clawsmail_MessageInfoType.tp_new = PyType_GenericNew;
-    if(PyType_Ready(&clawsmail_MessageInfoType) < 0)
-        return;
+  clawsmail_MessageInfoType.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&clawsmail_MessageInfoType) < 0)
+    return FALSE;
 
-    Py_INCREF(&clawsmail_MessageInfoType);
-    PyModule_AddObject(module, "MessageInfo", (PyObject*)&clawsmail_MessageInfoType);
+  Py_INCREF(&clawsmail_MessageInfoType);
+  return (PyModule_AddObject(module, "MessageInfo", (PyObject*)&clawsmail_MessageInfoType) == 0);
 }
 
 #define MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(fis, pms)     \
diff --git a/src/plugins/python/messageinfotype.h b/src/plugins/python/messageinfotype.h
index 1beb37a..df3c217 100644
--- a/src/plugins/python/messageinfotype.h
+++ b/src/plugins/python/messageinfotype.h
@@ -18,15 +18,12 @@
 #ifndef MESSAGEINFOTYPE_H
 #define MESSAGEINFOTYPE_H
 
+#include <glib.h>
 #include <Python.h>
 
 #include "procmsg.h"
 
-#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-
-PyMODINIT_FUNC initmessageinfo(PyObject *module);
+gboolean cmpy_add_messageinfo(PyObject *module);
 
 PyObject* clawsmail_messageinfo_new(MsgInfo *msginfo);
 MsgInfo* clawsmail_messageinfo_get_msginfo(PyObject *self);
diff --git a/src/plugins/python/nodetype.c b/src/plugins/python/nodetype.c
index 8bf8b65..60425f8 100644
--- a/src/plugins/python/nodetype.c
+++ b/src/plugins/python/nodetype.c
@@ -20,15 +20,16 @@
 #include "claws-features.h"
 #endif
 
-#include <glib.h>
 #include <glib/gi18n.h>
 
 #include "nodetype.h"
 
 #include <structmember.h>
 
-PyMODINIT_FUNC initnode(PyObject *module)
+/* returns true on success, false if an exception was thrown */
+gboolean cmpy_add_node(PyObject *module)
 {
+  gboolean retval;
   PyObject *dict;
   PyObject *res;
   const char *cmd =
@@ -85,9 +86,13 @@ PyMODINIT_FUNC initnode(PyObject *module)
     PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
 
   res = PyRun_String(cmd, Py_file_input, dict, dict);
+
+  retval = (res != NULL);
   Py_XDECREF(res);
+  return retval;
 }
 
+
 PyObject* clawsmail_node_new(PyObject *module)
 {
   PyObject *class, *dict;
diff --git a/src/plugins/python/nodetype.h b/src/plugins/python/nodetype.h
index cb437e6..03daa31 100644
--- a/src/plugins/python/nodetype.h
+++ b/src/plugins/python/nodetype.h
@@ -18,13 +18,12 @@
 #ifndef NODETYPE_H
 #define NODETYPE_H
 
+#include <glib.h>
+
 #include <Python.h>
 
-#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
 
-PyMODINIT_FUNC initnode(PyObject *module);
+gboolean cmpy_add_node(PyObject *module);
 
 PyObject* clawsmail_node_new(PyObject *module);
 
diff --git a/src/plugins/python/python-hooks.c b/src/plugins/python/python-hooks.c
index 24822b6..f022890 100644
--- a/src/plugins/python/python-hooks.c
+++ b/src/plugins/python/python-hooks.c
@@ -122,37 +122,38 @@ is_blacklisted(void)
 }
 #endif // ENABLE_PYTHON
 
-void
-parasite_python_init(void)
+int
+parasite_python_init(char **error)
 {
 #ifdef ENABLE_PYTHON
-    int res;
     struct sigaction old_sigint;
     PyObject *pygtk;
 
-    if (is_blacklisted())
-        return;
+    if (is_blacklisted()) {
+      *error = g_strdup("Application is blacklisted");
+      return 0;
+    }
 
     /* This prevents errors such as "undefined symbol: PyExc_ImportError" */
     if (!dlopen(PYTHON_SHARED_LIB, RTLD_NOW | RTLD_GLOBAL))
     {
-        g_error("%s\n", dlerror());
-        return;
+        *error = g_strdup_printf("Parasite: Error on dlopen(): %s\n", dlerror());
+        return 0;
     }
 
     captured_stdout = g_string_new("");
     captured_stderr = g_string_new("");
 
     /* Back up and later restore SIGINT so Python doesn't steal it from us. */
-    res = sigaction(SIGINT, NULL, &old_sigint);
+    sigaction(SIGINT, NULL, &old_sigint);
 
     if (!Py_IsInitialized())
         Py_Initialize();
 
-    res = sigaction(SIGINT, &old_sigint, NULL);
+    sigaction(SIGINT, &old_sigint, NULL);
 
     Py_InitModule("parasite", parasite_python_methods);
-    PyRun_SimpleString(
+    if(PyRun_SimpleString(
         "import parasite\n"
         "import sys\n"
         "\n"
@@ -176,10 +177,11 @@ parasite_python_init(void)
         "    def flush(self):\n"
         "        pass\n"
         "\n"
-    );
+    ) == -1)
+      return 0;
 
     if (!pygobject_init(-1, -1, -1))
-        return;
+        return 0;
 
     pygtk = PyImport_ImportModule("gtk");
 
@@ -198,18 +200,18 @@ parasite_python_init(void)
                 _PyGtk_API = (struct _PyGtk_FunctionStruct*)
                 PyCObject_AsVoidPtr(cobject);
             else {
-                PyErr_SetString(PyExc_RuntimeError,
-                                "could not find _PyGtk_API object");
-                return;
+              *error = g_strdup("Parasite: Could not find _PyGtk_API object");
+                return 0;
             }
         }
     } else {
-        PyErr_SetString(PyExc_ImportError, "could not import gtk");
-        return;
+        *error = g_strdup("Parasite: Could not import gtk");
+        return 0;
     }
 
     python_enabled = TRUE;
 #endif // ENABLE_PYTHON
+    return !0;
 }
 
 void
diff --git a/src/plugins/python/python-hooks.h b/src/plugins/python/python-hooks.h
index d6bf1bd..2744fc3 100644
--- a/src/plugins/python/python-hooks.h
+++ b/src/plugins/python/python-hooks.h
@@ -28,7 +28,7 @@
 
 typedef void (*ParasitePythonLogger)(const char *text, gpointer user_data);
 
-void parasite_python_init(void);
+int parasite_python_init(char **error);
 void parasite_python_run(const char *command,
                          ParasitePythonLogger stdout_logger,
                          ParasitePythonLogger stderr_logger,
diff --git a/src/plugins/python/python_plugin.c b/src/plugins/python/python_plugin.c
index 7becb93..4cdba31 100644
--- a/src/plugins/python/python_plugin.c
+++ b/src/plugins/python/python_plugin.c
@@ -160,11 +160,12 @@ static void run_script_file(const gchar *filename, Compose *compose)
   FILE *fp;
   fp = fopen(filename, "r");
   if(!fp) {
-    g_print("Error: Could not open file '%s'\n", filename);
+    debug_print("Error: Could not open file '%s'\n", filename);
     return;
   }
   put_composewindow_into_module(compose);
-  PyRun_SimpleFile(fp, filename);
+  if(PyRun_SimpleFile(fp, filename) == 0)
+    debug_print("Problem running script file '%s'\n", filename);
   fclose(fp);
 }
 
@@ -297,9 +298,9 @@ static void migrate_scripts_out_of_base_dir(void)
       gchar *dest_file;
       dest_file = g_strconcat(dest_dir, G_DIR_SEPARATOR_S, filename, NULL);
       if(move_file(filepath, dest_file, FALSE) == 0)
-        g_print("Python plugin: Moved file '%s' to %s subdir\n", filename, PYTHON_SCRIPTS_MAIN_DIR);
+        debug_print("Python plugin: Moved file '%s' to %s subdir\n", filename, PYTHON_SCRIPTS_MAIN_DIR);
       else
-        g_print("Python plugin: Warning: Could not move file '%s' to %s subdir\n", filename, PYTHON_SCRIPTS_MAIN_DIR);
+        debug_print("Python plugin: Warning: Could not move file '%s' to %s subdir\n", filename, PYTHON_SCRIPTS_MAIN_DIR);
       g_free(dest_file);
     }
     g_free(filepath);
@@ -429,7 +430,7 @@ static void refresh_scripts_in_dir(const gchar *subdir, ToolbarType toolbar_type
   g_free(scripts_dir);
 
   if(!dir) {
-    g_print("Could not open directory '%s': %s\n", subdir, error->message);
+    debug_print("Could not open directory '%s': %s\n", subdir, error->message);
     g_error_free(error);
     return;
   }
@@ -506,12 +507,16 @@ static GtkActionEntry mainwindow_tools_python_actions[] = {
     {"Tools/PythonScripts/---", NULL, "---" },
 };
 
-static void python_menu_init(void)
+static int python_menu_init(char **error)
 {
   MainWindow *mainwin;
   guint id;
 
   mainwin =  mainwindow_get_mainwindow();
+  if(!mainwin) {
+    *error = g_strdup("Could not get main window");
+    return 0;
+  }
 
   gtk_action_group_add_toggle_actions(mainwin->action_group, mainwindow_tools_python_toggle, 1, mainwin);
   gtk_action_group_add_actions(mainwin->action_group, mainwindow_tools_python_actions, 3, mainwin);
@@ -537,6 +542,8 @@ static void python_menu_init(void)
   menu_id_list = g_slist_prepend(menu_id_list, GUINT_TO_POINTER(id));
 
   refresh_python_scripts_menus(NULL, NULL);
+
+  return !0;
 }
 
 static void python_menu_done(void)
@@ -560,8 +567,81 @@ static void python_menu_done(void)
   }
 }
 
+
+static PyObject *get_StringIO_instance(void)
+{
+  PyObject *module_StringIO = NULL;
+  PyObject *class_StringIO = NULL;
+  PyObject *inst_StringIO = NULL;
+
+  module_StringIO = PyImport_ImportModule("cStringIO");
+  if(!module_StringIO) {
+    debug_print("Error getting traceback: Could not import module cStringIO\n");
+    goto done;
+  }
+
+  class_StringIO = PyObject_GetAttrString(module_StringIO, "StringIO");
+  if(!class_StringIO) {
+    debug_print("Error getting traceback: Could not get StringIO class\n");
+    goto done;
+  }
+
+  inst_StringIO = PyObject_CallObject(class_StringIO, NULL);
+  if(!inst_StringIO) {
+    debug_print("Error getting traceback: Could not create an instance of the StringIO class\n");
+    goto done;
+  }
+
+done:
+  Py_XDECREF(module_StringIO);
+  Py_XDECREF(class_StringIO);
+
+  return inst_StringIO;
+}
+
+static char* get_exception_information(PyObject *inst_StringIO)
+{
+  char *retval = NULL;
+  PyObject *meth_getvalue = NULL;
+  PyObject *result_getvalue = NULL;
+
+  if(!inst_StringIO)
+    goto done;
+
+  if(PySys_SetObject("stderr", inst_StringIO) != 0) {
+    debug_print("Error getting traceback: Could not set sys.stderr to a StringIO instance\n");
+    goto done;
+  }
+
+  meth_getvalue = PyObject_GetAttrString(inst_StringIO, "getvalue");
+  if(!meth_getvalue) {
+    debug_print("Error getting traceback: Could not get the getvalue method of the StringIO instance\n");
+    goto done;
+  }
+
+  PyErr_Print();
+
+  result_getvalue = PyObject_CallObject(meth_getvalue, NULL);
+  if(!result_getvalue) {
+    debug_print("Error getting traceback: Could not call the getvalue method of the StringIO instance\n");
+    goto done;
+  }
+
+  retval = g_strdup(PyString_AsString(result_getvalue));
+
+done:
+
+  Py_XDECREF(meth_getvalue);
+  Py_XDECREF(result_getvalue);
+
+  return retval ? retval : g_strdup("Unspecified error occured");
+}
+
+
 gint plugin_init(gchar **error)
 {
+  PyObject *inst_StringIO = NULL;
+
   /* Version check */
   if(!check_plugin_version(MAKE_NUMERIC_VERSION(3,7,6,9), VERSION_NUMERIC, _("Python"), error))
     return -1;
@@ -575,25 +655,49 @@ gint plugin_init(gchar **error)
 
   /* script directories */
   if(!make_sure_directories_exist(error))
-    return -1;
+    goto err;
 
   /* initialize python interpreter */
   Py_Initialize();
 
-  /* initialize python interactive shell */
-  parasite_python_init();
+  /* The Python C API only offers to print an exception to sys.stderr. In order to catch it
+   * in a string, a StringIO object is created, to which sys.stderr can be redirected in case
+   * an error occured. */
+  inst_StringIO = get_StringIO_instance();
 
   /* initialize Claws Mail Python module */
-  claws_mail_python_init();
+  initclawsmail();
+  if(PyErr_Occurred()) {
+    *error = get_exception_information(inst_StringIO);
+    goto err;
+  }
+
+  if(PyRun_SimpleString("import clawsmail") == -1) {
+    *error = g_strdup("Error importing the clawsmail module");
+    goto err;
+  }
+
+  /* initialize python interactive shell */
+  if(!parasite_python_init(error)) {
+    goto err;
+  }
 
   /* load menu options */
-  python_menu_init();
+  if(!python_menu_init(error)) {
+    goto err;
+  }
 
+  /* problems here are not fatal */
   run_auto_script_file_if_it_exists(PYTHON_SCRIPTS_AUTO_STARTUP, NULL);
 
   debug_print("Python plugin loaded\n");
 
   return 0;
+
+err:
+  hooks_unregister_hook(COMPOSE_CREATED_HOOKLIST, hook_compose_create);
+  Py_XDECREF(inst_StringIO);
+  return -1;
 }
 
 gboolean plugin_done(void)

commit 67df492152493bec7f3c645403d7efd3415df6ae
Author: Holger Berndt <hb at claws-mail.org>
Date:   Mon Jun 10 23:05:19 2013 +0200

    Python plugin: Make some functions static

diff --git a/src/plugins/python/python_plugin.c b/src/plugins/python/python_plugin.c
index fb015f9..7becb93 100644
--- a/src/plugins/python/python_plugin.c
+++ b/src/plugins/python/python_plugin.c
@@ -506,7 +506,7 @@ static GtkActionEntry mainwindow_tools_python_actions[] = {
     {"Tools/PythonScripts/---", NULL, "---" },
 };
 
-void python_menu_init(void)
+static void python_menu_init(void)
 {
   MainWindow *mainwin;
   guint id;
@@ -539,7 +539,7 @@ void python_menu_init(void)
   refresh_python_scripts_menus(NULL, NULL);
 }
 
-void python_menu_done(void)
+static void python_menu_done(void)
 {
   MainWindow *mainwin;
 

commit dd677bd0e6fe5d7082640032f18deffb2ca778b0
Author: Holger Berndt <hb at claws-mail.org>
Date:   Sun Jun 9 20:38:23 2013 +0200

    Python plugin: Better error reporting during directory creation

diff --git a/src/plugins/python/python_plugin.c b/src/plugins/python/python_plugin.c
index a0f4650..fb015f9 100644
--- a/src/plugins/python/python_plugin.c
+++ b/src/plugins/python/python_plugin.c
@@ -25,6 +25,8 @@
 
 #include <Python.h>
 
+#include <errno.h>
+
 #include "common/hooks.h"
 #include "common/plugin.h"
 #include "common/version.h"
@@ -228,23 +230,40 @@ static void compose_toolbar_callback(gpointer parent, const gchar *item_name, gp
   g_free(filename);
 }
 
-static void make_sure_script_directory_exists(const gchar *subdir)
+static char* make_sure_script_directory_exists(const gchar *subdir)
 {
   char *dir;
+  char *retval = NULL;
   dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, PYTHON_SCRIPTS_BASE_DIR, G_DIR_SEPARATOR_S, subdir, NULL);
   if(!g_file_test(dir, G_FILE_TEST_IS_DIR)) {
     if(g_mkdir(dir, 0777) != 0)
-      debug_print("Python plugin: Could not create directory '%s'\n", dir);
+      retval = g_strdup_printf("Could not create directory '%s': %s", dir, g_strerror(errno));
   }
   g_free(dir);
+  return retval;
 }
 
-static void make_sure_directories_exist(void)
+static int make_sure_directories_exist(char **error)
 {
-  make_sure_script_directory_exists("");
-  make_sure_script_directory_exists(PYTHON_SCRIPTS_MAIN_DIR);
-  make_sure_script_directory_exists(PYTHON_SCRIPTS_COMPOSE_DIR);
-  make_sure_script_directory_exists(PYTHON_SCRIPTS_AUTO_DIR);
+  const char* dirs[] = {
+      ""
+      , PYTHON_SCRIPTS_MAIN_DIR
+      , PYTHON_SCRIPTS_COMPOSE_DIR
+      , PYTHON_SCRIPTS_AUTO_DIR
+      , NULL
+  };
+  const char **dir = dirs;
+
+  *error = NULL;
+
+  while(*dir) {
+    *error = make_sure_script_directory_exists(*dir);
+    if(*error)
+      break;
+    dir++;
+  }
+
+  return (*error == NULL);
 }
 
 static void migrate_scripts_out_of_base_dir(void)
@@ -544,8 +563,7 @@ void python_menu_done(void)
 gint plugin_init(gchar **error)
 {
   /* Version check */
-  if(!check_plugin_version(MAKE_NUMERIC_VERSION(3,7,6,9),
-			   VERSION_NUMERIC, _("Python"), error))
+  if(!check_plugin_version(MAKE_NUMERIC_VERSION(3,7,6,9), VERSION_NUMERIC, _("Python"), error))
     return -1;
 
   /* load hooks */
@@ -556,7 +574,8 @@ gint plugin_init(gchar **error)
   }
 
   /* script directories */
-  make_sure_directories_exist();
+  if(!make_sure_directories_exist(error))
+    return -1;
 
   /* initialize python interpreter */
   Py_Initialize();

commit 75722552afbdbb82f35b90ce2aef74e648b9634f
Author: Holger Berndt <hb at claws-mail.org>
Date:   Sun Jun 9 20:38:08 2013 +0200

    Python plugin: Add explicit cast for function argument

diff --git a/src/plugins/python/python_plugin.c b/src/plugins/python/python_plugin.c
index 9c34538..a0f4650 100644
--- a/src/plugins/python/python_plugin.c
+++ b/src/plugins/python/python_plugin.c
@@ -452,7 +452,7 @@ static void browse_python_scripts_dir(GtkAction *action, gpointer data)
   launch_context = gdk_app_launch_context_new();
   gdk_app_launch_context_set_screen(launch_context, gtk_widget_get_screen(mainwin->window));
   uri = g_strconcat("file://", get_rc_dir(), G_DIR_SEPARATOR_S, PYTHON_SCRIPTS_BASE_DIR, G_DIR_SEPARATOR_S, NULL);
-  g_app_info_launch_default_for_uri(uri, launch_context, &error);
+  g_app_info_launch_default_for_uri(uri, G_APP_LAUNCH_CONTEXT(launch_context), &error);
 
   if(error) {
       debug_print("Could not open scripts dir browser: '%s'\n", error->message);

-----------------------------------------------------------------------

Summary of changes:
 src/plugins/python/clawsmailmodule.c   |   50 +++++-----
 src/plugins/python/clawsmailmodule.h   |    5 +-
 src/plugins/python/composewindowtype.c |   12 +-
 src/plugins/python/composewindowtype.h |    6 +-
 src/plugins/python/foldertype.c        |   25 +++---
 src/plugins/python/foldertype.h        |    7 +-
 src/plugins/python/messageinfotype.c   |   13 +--
 src/plugins/python/messageinfotype.h   |    7 +-
 src/plugins/python/nodetype.c          |    9 ++-
 src/plugins/python/nodetype.h          |    7 +-
 src/plugins/python/python-hooks.c      |   36 ++++---
 src/plugins/python/python-hooks.h      |    2 +-
 src/plugins/python/python_plugin.c     |  167 +++++++++++++++++++++++++++----
 13 files changed, 237 insertions(+), 109 deletions(-)


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list