Clean all ‘… warning: "_POSIX_C_SOURCE" redefined’
[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 "foldertype.h"
24 #include "folderpropertiestype.h"
25 #include "messageinfotype.h"
26 #include "mailboxtype.h"
27
28 #include <glib/gi18n.h>
29
30 #include <structmember.h>
31
32
33 typedef struct {
34     PyObject_HEAD
35     PyObject *properties;
36     FolderItem *folderitem;
37 } clawsmail_FolderObject;
38
39
40 static void Folder_dealloc(clawsmail_FolderObject* self)
41 {
42   Py_XDECREF(self->properties);
43   self->ob_type->tp_free((PyObject*)self);
44 }
45
46 static int Folder_init(clawsmail_FolderObject *self, PyObject *args, PyObject *kwds)
47 {
48   const char *ss = NULL;
49   FolderItem *folderitem = NULL;
50   char create = 0;
51
52   /* optional constructor argument: folderitem id string */
53   if(!PyArg_ParseTuple(args, "|sb", &ss, &create))
54     return -1;
55
56   if(ss) {
57     if(create == 0) {
58       folderitem = folder_find_item_from_identifier(ss);
59       if(!folderitem) {
60         PyErr_SetString(PyExc_ValueError, "A folder with that path does not exist, and the create parameter was False.");
61         return -1;
62       }
63     }
64     else {
65       folderitem = folder_get_item_from_identifier(ss);
66       if(!folderitem) {
67         PyErr_SetString(PyExc_IOError, "A folder with that path does not exist, and could not be created.");
68         return -1;
69       }
70     }
71   }
72
73   self->folderitem = folderitem;
74   if(folderitem)
75     self->properties = clawsmail_folderproperties_new(folderitem->prefs);
76   else {
77     Py_INCREF(Py_None);
78     self->properties = Py_None;
79   }
80
81   return 0;
82 }
83
84 static PyObject* Folder_str(clawsmail_FolderObject *self)
85 {
86   return PyString_FromFormat("Folder: %s", self->folderitem->name);
87 }
88
89 static PyObject* Folder_get_identifier(clawsmail_FolderObject *self, PyObject *args)
90 {
91   PyObject *obj;
92   gchar *id;
93   if(!self->folderitem)
94     return NULL;
95   id = folder_item_get_identifier(self->folderitem);
96   obj = Py_BuildValue("s", id);
97   g_free(id);
98   return obj;
99 }
100
101 static PyObject* Folder_get_messages(clawsmail_FolderObject *self, PyObject *args)
102 {
103   GSList *msglist, *walk;
104   PyObject *retval;
105   Py_ssize_t pos;
106
107   if(!self->folderitem)
108     return NULL;
109
110   msglist = folder_item_get_msg_list(self->folderitem);
111   retval = PyTuple_New(g_slist_length(msglist));
112   if(!retval) {
113     procmsg_msg_list_free(msglist);
114     Py_INCREF(Py_None);
115     return Py_None;
116   }
117
118   for(pos = 0, walk = msglist; walk; walk = walk->next, ++pos) {
119     PyObject *msg;
120     msg = clawsmail_messageinfo_new(walk->data);
121     PyTuple_SET_ITEM(retval, pos, msg);
122   }
123   procmsg_msg_list_free(msglist);
124
125   return retval;
126 }
127
128 static PyObject* get_name(clawsmail_FolderObject *self, void *closure)
129 {
130   if(self->folderitem && self->folderitem->name)
131     return PyString_FromString(self->folderitem->name);
132   Py_RETURN_NONE;
133 }
134
135 static PyObject* get_mailbox_name(clawsmail_FolderObject *self, void *closure)
136 {
137   if(self->folderitem && self->folderitem->folder && self->folderitem->folder->name)
138     return PyString_FromString(self->folderitem->folder->name);
139   Py_RETURN_NONE;
140 }
141
142 static PyObject* get_mailbox(clawsmail_FolderObject *self, void *closure)
143 {
144   if(self->folderitem && self->folderitem->folder)
145     return clawsmail_mailbox_new(self->folderitem->folder);
146   Py_RETURN_NONE;
147 }
148
149
150 static PyObject* get_identifier(clawsmail_FolderObject *self, void *closure)
151 {
152   if(self->folderitem) {
153     gchar *id;
154     id = folder_item_get_identifier(self->folderitem);
155     if(id) {
156       PyObject *retval;
157       retval = PyString_FromString(id);
158       g_free(id);
159       return retval;
160     }
161   }
162   Py_RETURN_NONE;
163 }
164
165 static PyObject* get_path(clawsmail_FolderObject *self, void *closure)
166 {
167   if(self->folderitem) {
168     gchar *path;
169     path = folder_item_get_path(self->folderitem);
170     if(path) {
171       PyObject *retval;
172       retval = PyString_FromString(path);
173       g_free(path);
174       return retval;
175     }
176   }
177   Py_RETURN_NONE;
178 }
179
180
181 static PyObject* get_properties(clawsmail_FolderObject *self, void *closure)
182 {
183   Py_INCREF(self->properties);
184   return self->properties;
185 }
186
187 static PyObject* get_num_messages(clawsmail_FolderObject *self, void *closure)
188 {
189   if(self && self->folderitem)
190     return PyInt_FromLong(self->folderitem->total_msgs);
191   Py_RETURN_NONE;
192 }
193
194 static PyObject* get_num_new_messages(clawsmail_FolderObject *self, void *closure)
195 {
196   if(self && self->folderitem)
197     return PyInt_FromLong(self->folderitem->new_msgs);
198   Py_RETURN_NONE;
199 }
200
201 static PyObject* get_num_unread_messages(clawsmail_FolderObject *self, void *closure)
202 {
203   if(self && self->folderitem)
204     return PyInt_FromLong(self->folderitem->unread_msgs);
205   Py_RETURN_NONE;
206 }
207
208 static PyObject* get_num_marked_messages(clawsmail_FolderObject *self, void *closure)
209 {
210   if(self && self->folderitem)
211     return PyInt_FromLong(self->folderitem->marked_msgs);
212   Py_RETURN_NONE;
213 }
214
215 static PyObject* get_num_locked_messages(clawsmail_FolderObject *self, void *closure)
216 {
217   if(self && self->folderitem)
218     return PyInt_FromLong(self->folderitem->locked_msgs);
219   Py_RETURN_NONE;
220 }
221
222 static PyObject* get_num_unread_marked_messages(clawsmail_FolderObject *self, void *closure)
223 {
224   if(self && self->folderitem)
225     return PyInt_FromLong(self->folderitem->unreadmarked_msgs);
226   Py_RETURN_NONE;
227 }
228
229 static PyObject* get_num_ignored_messages(clawsmail_FolderObject *self, void *closure)
230 {
231   if(self && self->folderitem)
232     return PyInt_FromLong(self->folderitem->ignored_msgs);
233   Py_RETURN_NONE;
234 }
235
236 static PyObject* get_num_watched_messages(clawsmail_FolderObject *self, void *closure)
237 {
238   if(self && self->folderitem)
239     return PyInt_FromLong(self->folderitem->watched_msgs);
240   Py_RETURN_NONE;
241 }
242
243 static PyObject* get_num_replied_messages(clawsmail_FolderObject *self, void *closure)
244 {
245   if(self && self->folderitem)
246     return PyInt_FromLong(self->folderitem->replied_msgs);
247   Py_RETURN_NONE;
248 }
249
250 static PyObject* get_num_forwarded_messages(clawsmail_FolderObject *self, void *closure)
251 {
252   if(self && self->folderitem)
253     return PyInt_FromLong(self->folderitem->forwarded_msgs);
254   Py_RETURN_NONE;
255 }
256
257 static PyMethodDef Folder_methods[] = {
258     {"get_identifier", (PyCFunction)Folder_get_identifier, METH_NOARGS,
259      "get_identifier() - get identifier\n"
260      "\n"
261      "Get identifier for folder as a string (e.g. #mh/foo/bar).\n\n"
262      "DEPRECATED: Use identifier property instead."},
263
264     {"get_messages", (PyCFunction)Folder_get_messages, METH_NOARGS,
265      "get_messages() - get a tuple of messages in folder\n"
266      "\n"
267      "Get a tuple of MessageInfos for the folder."},
268
269      {NULL}
270 };
271
272 static PyGetSetDef Folder_getset[] = {
273     {"name", (getter)get_name, (setter)NULL,
274      "name - name of folder", NULL},
275
276     {"path", (getter)get_path, (setter)NULL,
277      "path - path of folder", NULL},
278
279     {"identifier", (getter)get_identifier, (setter)NULL,
280      "identifier - identifier of folder", NULL},
281
282     {"mailbox", (getter)get_mailbox, (setter)NULL,
283      "mailbox - corresponding mailbox", NULL},
284
285     {"mailbox_name", (getter)get_mailbox_name, (setter)NULL,
286      "mailbox_name - name of the corresponding mailbox\n\n"
287      "DEPRECATED: Use folder.mailbox.name instead", NULL},
288
289     {"properties", (getter)get_properties, (setter)NULL,
290      "properties - folder properties object", NULL},
291
292     {"num_messages", (getter)get_num_messages, (setter)NULL,
293      "num_messages - total number of messages in folder", NULL},
294
295     {"num_new_messages", (getter)get_num_new_messages, (setter)NULL,
296      "num_new_messages - number of new messages in folder", NULL},
297
298     {"num_unread_messages", (getter)get_num_unread_messages, (setter)NULL,
299      "num_unread_messages - number of unread messages in folder", NULL},
300
301     {"num_marked_messages", (getter)get_num_marked_messages, (setter)NULL,
302      "num_marked_messages - number of marked messages in folder", NULL},
303
304     {"num_locked_messages", (getter)get_num_locked_messages, (setter)NULL,
305      "num_locked_messages - number of locked messages in folder", NULL},
306
307     {"num_unread_marked_messages", (getter)get_num_unread_marked_messages, (setter)NULL,
308      "num_unread_marked_messages - number of unread marked messages in folder", NULL},
309
310     {"num_ignored_messages", (getter)get_num_ignored_messages, (setter)NULL,
311      "num_ignored_messages - number of ignored messages in folder", NULL},
312
313     {"num_watched_messages", (getter)get_num_watched_messages, (setter)NULL,
314      "num_watched_messages - number of watched messages in folder", NULL},
315
316     {"num_replied_messages", (getter)get_num_replied_messages, (setter)NULL,
317      "num_replied_messages - number of replied messages in folder", NULL},
318
319     {"num_forwarded_messages", (getter)get_num_forwarded_messages, (setter)NULL,
320      "num_forwarded_messages - number of forwarded messages in folder", NULL},
321
322     {NULL}
323 };
324
325
326 static PyTypeObject clawsmail_FolderType = {
327     PyObject_HEAD_INIT(NULL)
328     0,                         /* ob_size*/
329     "clawsmail.Folder",        /* tp_name*/
330     sizeof(clawsmail_FolderObject), /* tp_basicsize*/
331     0,                         /* tp_itemsize*/
332     (destructor)Folder_dealloc, /* tp_dealloc*/
333     0,                         /* tp_print*/
334     0,                         /* tp_getattr*/
335     0,                         /* tp_setattr*/
336     0,                         /* tp_compare*/
337     0,                         /* tp_repr*/
338     0,                         /* tp_as_number*/
339     0,                         /* tp_as_sequence*/
340     0,                         /* tp_as_mapping*/
341     0,                         /* tp_hash */
342     0,                         /* tp_call*/
343     (reprfunc)Folder_str,      /* tp_str*/
344     0,                         /* tp_getattro*/
345     0,                         /* tp_setattro*/
346     0,                         /* tp_as_buffer*/
347     Py_TPFLAGS_DEFAULT,        /* tp_flags*/
348     "Folder objects.\n\n"      /* tp_doc */
349     "The __init__ function takes two optional arguments:\n"
350     "folder = Folder(identifier, [create_if_not_existing=False])\n"
351     "The identifier is an id string (e.g. '#mh/Mail/foo/bar'),"
352     "create_if_not_existing is a boolean expression.",
353     0,                         /* tp_traverse */
354     0,                         /* tp_clear */
355     0,                         /* tp_richcompare */
356     0,                         /* tp_weaklistoffset */
357     0,                         /* tp_iter */
358     0,                         /* tp_iternext */
359     Folder_methods,            /* tp_methods */
360     0,                         /* tp_members */
361     Folder_getset,             /* tp_getset */
362     0,                         /* tp_base */
363     0,                         /* tp_dict */
364     0,                         /* tp_descr_get */
365     0,                         /* tp_descr_set */
366     0,                         /* tp_dictoffset */
367     (initproc)Folder_init,     /* tp_init */
368     0,                         /* tp_alloc */
369     0,                         /* tp_new */
370 };
371
372 gboolean cmpy_add_folder(PyObject *module)
373 {
374   clawsmail_FolderType.tp_new = PyType_GenericNew;
375   if(PyType_Ready(&clawsmail_FolderType) < 0)
376     return FALSE;
377
378   Py_INCREF(&clawsmail_FolderType);
379   return (PyModule_AddObject(module, "Folder", (PyObject*)&clawsmail_FolderType) == 0);
380 }
381
382 PyObject* clawsmail_folder_new(FolderItem *folderitem)
383 {
384   clawsmail_FolderObject *ff;
385   PyObject *arglist;
386   gchar *id;
387
388   if(!folderitem)
389     return NULL;
390
391   id = folder_item_get_identifier(folderitem);
392   if(id) {
393     arglist = Py_BuildValue("(s)", id);
394     g_free(id);
395     ff = (clawsmail_FolderObject*) PyObject_CallObject((PyObject*) &clawsmail_FolderType, arglist);
396     Py_DECREF(arglist);
397     return (PyObject*)ff;
398   }
399   Py_RETURN_NONE;
400 }
401
402 FolderItem* clawsmail_folder_get_item(PyObject *self)
403 {
404   return ((clawsmail_FolderObject*)self)->folderitem;
405 }
406
407 PyTypeObject* clawsmail_folder_get_type_object()
408 {
409   return &clawsmail_FolderType;
410 }
411
412 gboolean clawsmail_folder_check(PyObject *self)
413 {
414   return (PyObject_TypeCheck(self, &clawsmail_FolderType) != 0);
415 }