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