Python plugin: Improve error reporting during plugin init
[claws.git] / src / plugins / python / nodetype.c
1 /* Python plugin for Claws-Mail
2  * Copyright (C) 2009 Holger Berndt
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #ifdef HAVE_CONFIG_H
19 #  include "config.h"
20 #include "claws-features.h"
21 #endif
22
23 #include <glib/gi18n.h>
24
25 #include "nodetype.h"
26
27 #include <structmember.h>
28
29 /* returns true on success, false if an exception was thrown */
30 gboolean cmpy_add_node(PyObject *module)
31 {
32   gboolean retval;
33   PyObject *dict;
34   PyObject *res;
35   const char *cmd =
36       "class Node(object):\n"
37       "    \"\"\"A general purpose tree container type\"\"\"\n"
38       "\n"
39       "    def __init__(self):\n"
40       "        self.data = None\n"
41       "        self.children = []\n"
42       "\n"
43       "    def __str__(self):\n"
44       "        return '\\n'.join(self.get_str_list(0))\n"
45       "\n"
46       "    def get_str_list(self, level):\n"
47       "        \"\"\"get_str_list(level) - get a list of string-representations of the tree data\n"
48       "        \n"
49       "        The nesting of the tree elements is represented by various levels of indentation.\"\"\"\n"
50       "        str = []\n"
51       "        indent = '  '*level\n"
52       "        if self.data:\n"
53       "            str.append(indent + self.data.__str__())\n"
54       "        else:\n"
55       "            str.append(indent + 'None')\n"
56       "        for child in self.children:\n"
57       "            str.extend(child.get_str_list(level+1))\n"
58       "        return str\n"
59       "\n"
60       "    def traverse(self, callback, arg=None):\n"
61       "        \"\"\"traverse(callback [, arg=None]) - traverse the tree\n"
62       "        \n"
63       "        Traverse the tree, calling the callback function for each node element,\n"
64       "        with optional arg as user-data. The expected callback function signature is\n"
65       "        callback(node_data [, arg]).\"\"\"\n"
66       "        if self.data:\n"
67       "            if arg is not None:\n"
68       "                callback(self.data, arg)\n"
69       "            else:\n"
70       "                callback(self.data)\n"
71       "        for child in self.children:\n"
72       "            child.traverse(callback, arg)\n"
73       "\n"
74       "    def flat_list(self):\n"
75       "        \"\"\"flat_list() - get a flat list of the tree\n"
76       "        \n"
77       "        Returns a flat list of the tree, disregarding the nesting structure.\"\"\"\n"
78       "        flat_list = []\n"
79       "        self.traverse(lambda data,list: list.append(data), flat_list)\n"
80       "        return flat_list\n"
81       "\n";
82
83   dict = PyModule_GetDict(module);
84
85   if(PyDict_GetItemString(dict, "__builtins__") == NULL)
86     PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
87
88   res = PyRun_String(cmd, Py_file_input, dict, dict);
89
90   retval = (res != NULL);
91   Py_XDECREF(res);
92   return retval;
93 }
94
95
96 PyObject* clawsmail_node_new(PyObject *module)
97 {
98   PyObject *class, *dict;
99
100   dict = PyModule_GetDict(module);
101   class = PyDict_GetItemString(dict, "Node");
102   return PyObject_CallObject(class, NULL);
103 }