Python plugin: Add folder properties
[claws.git] / src / plugins / python / foldertype.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 "foldertype.h"
26 #include "folderpropertiestype.h"
27 #include "messageinfotype.h"
28
29 #include <structmember.h>
30
31
32 typedef struct {
33     PyObject_HEAD
34     PyObject *name;
35     PyObject *path;
36     PyObject *mailbox_name;
37     PyObject *properties;
38     FolderItem *folderitem;
39 } clawsmail_FolderObject;
40
41
42 static void Folder_dealloc(clawsmail_FolderObject* self)
43 {
44   Py_XDECREF(self->name);
45   Py_XDECREF(self->path);
46   Py_XDECREF(self->mailbox_name);
47   Py_XDECREF(self->properties);
48   self->ob_type->tp_free((PyObject*)self);
49 }
50
51 #define FOLDERITEM_STRING_TO_PYTHON_FOLDER_MEMBER(self,fis, pms)    \
52   do {                                                              \
53     if(fis) {                                                       \
54       PyObject *str;                                                \
55       str = PyString_FromString(fis);                               \
56       if(str) {                                                     \
57         int retval;                                                 \
58         retval = PyObject_SetAttrString((PyObject*)self, pms, str); \
59         Py_DECREF(str);                                             \
60         if(retval == -1)                                            \
61           goto err;                                                 \
62       }                                                             \
63     }                                                               \
64   } while(0)
65
66 static int Folder_init(clawsmail_FolderObject *self, PyObject *args, PyObject *kwds)
67 {
68   const char *ss = NULL;
69   FolderItem *folderitem = NULL;
70   char create = 0;
71
72   /* optional constructor argument: folderitem id string */
73   if(!PyArg_ParseTuple(args, "|sb", &ss, &create))
74     return -1;
75
76   Py_INCREF(Py_None);
77   self->name = Py_None;
78
79   Py_INCREF(Py_None);
80   self->path = Py_None;
81
82   Py_INCREF(Py_None);
83   self->mailbox_name = Py_None;
84
85   if(ss) {
86     if(create == 0) {
87       folderitem = folder_find_item_from_identifier(ss);
88       if(!folderitem) {
89         PyErr_SetString(PyExc_ValueError, "A folder with that path does not exist, and the create parameter was False.");
90         return -1;
91       }
92     }
93     else {
94       folderitem = folder_get_item_from_identifier(ss);
95       if(!folderitem) {
96         PyErr_SetString(PyExc_IOError, "A folder with that path does not exist, and could not be created.");
97         return -1;
98       }
99     }
100   }
101
102   if(folderitem) {
103     FOLDERITEM_STRING_TO_PYTHON_FOLDER_MEMBER(self, folderitem->name, "name");
104     FOLDERITEM_STRING_TO_PYTHON_FOLDER_MEMBER(self, folderitem->path, "path");
105     FOLDERITEM_STRING_TO_PYTHON_FOLDER_MEMBER(self, folderitem->folder->name, "mailbox_name");
106     self->folderitem = folderitem;
107     self->properties = clawsmail_folderproperties_new(folderitem->prefs);
108   }
109   else {
110     Py_INCREF(Py_None);
111     self->properties = Py_None;
112   }
113
114   return 0;
115
116  err:
117   return -1;
118 }
119
120 static PyObject* Folder_str(PyObject *self)
121 {
122   PyObject *str;
123   str = PyString_FromString("Folder: ");
124   PyString_ConcatAndDel(&str, PyObject_GetAttrString(self, "name"));
125   return str;
126 }
127
128 static PyObject* Folder_get_identifier(clawsmail_FolderObject *self, PyObject *args)
129 {
130   PyObject *obj;
131   gchar *id;
132   if(!self->folderitem)
133     return NULL;
134   id = folder_item_get_identifier(self->folderitem);
135   obj = Py_BuildValue("s", id);
136   g_free(id);
137   return obj;
138 }
139
140 static PyObject* Folder_get_messages(clawsmail_FolderObject *self, PyObject *args)
141 {
142   GSList *msglist, *walk;
143   PyObject *retval;
144   Py_ssize_t pos;
145
146   if(!self->folderitem)
147     return NULL;
148
149   msglist = folder_item_get_msg_list(self->folderitem);
150   retval = PyTuple_New(g_slist_length(msglist));
151   if(!retval) {
152     procmsg_msg_list_free(msglist);
153     Py_INCREF(Py_None);
154     return Py_None;
155   }
156
157   for(pos = 0, walk = msglist; walk; walk = walk->next, ++pos) {
158     PyObject *msg;
159     msg = clawsmail_messageinfo_new(walk->data);
160     PyTuple_SET_ITEM(retval, pos, msg);
161   }
162   procmsg_msg_list_free(msglist);
163
164   return retval;
165 }
166
167 static PyObject* get_properties(clawsmail_FolderObject *self, void *closure)
168 {
169   Py_INCREF(self->properties);
170   return self->properties;
171 }
172
173 static PyMethodDef Folder_methods[] = {
174     {"get_identifier", (PyCFunction)Folder_get_identifier, METH_NOARGS,
175      "get_identifier() - get identifier\n"
176      "\n"
177      "Get identifier for folder as a string (e.g. #mh/foo/bar)."},
178     {"get_messages", (PyCFunction)Folder_get_messages, METH_NOARGS,
179      "get_messages() - get a tuple of messages in folder\n"
180      "\n"
181      "Get a tuple of MessageInfos for the folder."},
182     {NULL}
183 };
184
185 static PyMemberDef Folder_members[] = {
186   {"name", T_OBJECT_EX, offsetof(clawsmail_FolderObject, name), 0,
187    "name - name of folder"},
188
189   {"path", T_OBJECT_EX, offsetof(clawsmail_FolderObject, path), 0,
190    "path - path of folder"},
191
192   {"mailbox_name", T_OBJECT_EX, offsetof(clawsmail_FolderObject, mailbox_name), 0,
193    "mailbox_name - name of the corresponding mailbox"},
194
195   {NULL}
196 };
197
198 static PyGetSetDef Folder_getset[] = {
199     {"properties", (getter)get_properties, (setter)NULL,
200      "properties - folder properties object", NULL},
201
202     {NULL}
203 };
204
205
206 static PyTypeObject clawsmail_FolderType = {
207     PyObject_HEAD_INIT(NULL)
208     0,                         /* ob_size*/
209     "clawsmail.Folder",        /* tp_name*/
210     sizeof(clawsmail_FolderObject), /* tp_basicsize*/
211     0,                         /* tp_itemsize*/
212     (destructor)Folder_dealloc, /* tp_dealloc*/
213     0,                         /* tp_print*/
214     0,                         /* tp_getattr*/
215     0,                         /* tp_setattr*/
216     0,                         /* tp_compare*/
217     0,                         /* tp_repr*/
218     0,                         /* tp_as_number*/
219     0,                         /* tp_as_sequence*/
220     0,                         /* tp_as_mapping*/
221     0,                         /* tp_hash */
222     0,                         /* tp_call*/
223     Folder_str,                /* tp_str*/
224     0,                         /* tp_getattro*/
225     0,                         /* tp_setattro*/
226     0,                         /* tp_as_buffer*/
227     Py_TPFLAGS_DEFAULT,        /* tp_flags*/
228     "Folder objects.\n\n"      /* tp_doc */
229     "The __init__ function takes two optional arguments:\n"
230     "folder = Folder(identifier, [create_if_not_existing=False])\n"
231     "The identifier is an id string (e.g. '#mh/Mail/foo/bar'),"
232     "create_if_not_existing is a boolean expression.",
233     0,                         /* tp_traverse */
234     0,                         /* tp_clear */
235     0,                         /* tp_richcompare */
236     0,                         /* tp_weaklistoffset */
237     0,                         /* tp_iter */
238     0,                         /* tp_iternext */
239     Folder_methods,            /* tp_methods */
240     Folder_members,            /* tp_members */
241     Folder_getset,             /* tp_getset */
242     0,                         /* tp_base */
243     0,                         /* tp_dict */
244     0,                         /* tp_descr_get */
245     0,                         /* tp_descr_set */
246     0,                         /* tp_dictoffset */
247     (initproc)Folder_init,     /* tp_init */
248     0,                         /* tp_alloc */
249     0,                         /* tp_new */
250 };
251
252 gboolean cmpy_add_folder(PyObject *module)
253 {
254   clawsmail_FolderType.tp_new = PyType_GenericNew;
255   if(PyType_Ready(&clawsmail_FolderType) < 0)
256     return FALSE;
257
258   Py_INCREF(&clawsmail_FolderType);
259   return (PyModule_AddObject(module, "Folder", (PyObject*)&clawsmail_FolderType) == 0);
260 }
261
262 PyObject* clawsmail_folder_new(FolderItem *folderitem)
263 {
264   clawsmail_FolderObject *ff;
265   PyObject *arglist;
266   gchar *id;
267
268   if(!folderitem)
269     return NULL;
270
271   id = folder_item_get_identifier(folderitem);
272   arglist = Py_BuildValue("(s)", id);
273   g_free(id);
274   ff = (clawsmail_FolderObject*) PyObject_CallObject((PyObject*) &clawsmail_FolderType, arglist);
275   Py_DECREF(arglist);
276   return (PyObject*)ff;
277 }
278
279 FolderItem* clawsmail_folder_get_item(PyObject *self)
280 {
281   return ((clawsmail_FolderObject*)self)->folderitem;
282 }
283
284 PyTypeObject* clawsmail_folder_get_type_object()
285 {
286   return &clawsmail_FolderType;
287 }
288
289 gboolean clawsmail_folder_check(PyObject *self)
290 {
291   return (PyObject_TypeCheck(self, &clawsmail_FolderType) != 0);
292 }