1 /* Python plugin for Claws-Mail
2 * Copyright (C) 2009-2012 Holger Berndt
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.
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.
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/>.
20 #include "claws-features.h"
24 #include <glib/gi18n.h>
26 #include "messageinfotype.h"
28 #include "common/tags.h"
29 #include "mainwindow.h"
30 #include "summaryview.h"
32 #include <structmember.h>
43 } clawsmail_MessageInfoObject;
46 static void MessageInfo_dealloc(clawsmail_MessageInfoObject* self)
48 Py_XDECREF(self->from);
50 Py_XDECREF(self->subject);
51 Py_XDECREF(self->msgid);
52 self->ob_type->tp_free((PyObject*)self);
55 static int MessageInfo_init(clawsmail_MessageInfoObject *self, PyObject *args, PyObject *kwds)
64 self->subject = Py_None;
67 self->msgid = Py_None;
72 static PyObject* MessageInfo_str(PyObject *self)
75 str = PyString_FromString("MessageInfo: ");
76 PyString_ConcatAndDel(&str, PyObject_GetAttrString(self, "From"));
77 PyString_ConcatAndDel(&str, PyString_FromString(" / "));
78 PyString_ConcatAndDel(&str, PyObject_GetAttrString(self, "Subject"));
82 static PyObject *py_boolean_return_value(gboolean val)
94 static PyObject *is_new(PyObject *self, PyObject *args)
96 return py_boolean_return_value(MSG_IS_NEW(((clawsmail_MessageInfoObject*)self)->msginfo->flags));
99 static PyObject *is_unread(PyObject *self, PyObject *args)
101 return py_boolean_return_value(MSG_IS_UNREAD(((clawsmail_MessageInfoObject*)self)->msginfo->flags));
104 static PyObject *is_marked(PyObject *self, PyObject *args)
106 return py_boolean_return_value(MSG_IS_MARKED(((clawsmail_MessageInfoObject*)self)->msginfo->flags));
109 static PyObject *is_replied(PyObject *self, PyObject *args)
111 return py_boolean_return_value(MSG_IS_REPLIED(((clawsmail_MessageInfoObject*)self)->msginfo->flags));
114 static PyObject *is_locked(PyObject *self, PyObject *args)
116 return py_boolean_return_value(MSG_IS_LOCKED(((clawsmail_MessageInfoObject*)self)->msginfo->flags));
119 static PyObject *is_forwarded(PyObject *self, PyObject *args)
121 return py_boolean_return_value(MSG_IS_FORWARDED(((clawsmail_MessageInfoObject*)self)->msginfo->flags));
124 static PyObject* get_tags(PyObject *self, PyObject *args)
128 PyObject *tags_tuple;
130 tags_list = ((clawsmail_MessageInfoObject*)self)->msginfo->tags;
131 num_tags = g_slist_length(tags_list);
133 tags_tuple = PyTuple_New(num_tags);
134 if(tags_tuple != NULL) {
136 PyObject *tag_object;
140 for(walk = tags_list; walk; walk = walk->next) {
141 tag_object = Py_BuildValue("s", tags_get_tag(GPOINTER_TO_INT(walk->data)));
142 if(tag_object == NULL) {
143 Py_DECREF(tags_tuple);
146 PyTuple_SET_ITEM(tags_tuple, iTag++, tag_object);
154 static PyObject* add_or_remove_tag(PyObject *self, PyObject *args, gboolean add)
162 retval = PyArg_ParseTuple(args, "s", &tag_str);
166 tag_id = tags_get_id_for_str(tag_str);
168 PyErr_SetString(PyExc_ValueError, "Tag does not exist");
172 msginfo = ((clawsmail_MessageInfoObject*)self)->msginfo;
175 /* raise KeyError if tag is not set */
176 if(!g_slist_find(msginfo->tags, GINT_TO_POINTER(tag_id))) {
177 PyErr_SetString(PyExc_KeyError, "Tag is not set on this message");
182 procmsg_msginfo_update_tags(msginfo, add, tag_id);
185 mainwin = mainwindow_get_mainwindow();
187 summary_redisplay_msg(mainwin->summaryview);
194 static PyObject* add_tag(PyObject *self, PyObject *args)
196 return add_or_remove_tag(self, args, TRUE);
200 static PyObject* remove_tag(PyObject *self, PyObject *args)
202 return add_or_remove_tag(self, args, FALSE);
206 static PyMethodDef MessageInfo_methods[] = {
207 {"is_new", is_new, METH_NOARGS,
208 "is_new() - checks if the message is new\n"
210 "Returns True if the new flag of the message is set."},
212 {"is_unread", is_unread, METH_NOARGS,
213 "is_unread() - checks if the message is unread\n"
215 "Returns True if the unread flag of the message is set."},
217 {"is_marked", is_marked, METH_NOARGS,
218 "is_marked() - checks if the message is marked\n"
220 "Returns True if the marked flag of the message is set."},
222 {"is_replied", is_replied, METH_NOARGS,
223 "is_replied() - checks if the message has been replied to\n"
225 "Returns True if the replied flag of the message is set."},
227 {"is_locked", is_locked, METH_NOARGS,
228 "is_locked() - checks if the message has been locked\n"
230 "Returns True if the locked flag of the message is set."},
232 {"is_forwarded", is_forwarded, METH_NOARGS,
233 "is_forwarded() - checks if the message has been forwarded\n"
235 "Returns True if the forwarded flag of the message is set."},
237 {"get_tags", get_tags, METH_NOARGS,
238 "get_tags() - get message tags\n"
240 "Returns a tuple of tags that apply to this message."},
242 {"add_tag", add_tag, METH_VARARGS,
243 "add_tag(tag) - add a tag to this message\n"
245 "Add a tag to this message. If the tag is already set, nothing is done.\n"
246 "If the tag does not exist, a ValueError exception is raised."},
248 {"remove_tag", remove_tag, METH_VARARGS,
249 "remove_tag(tag) - remove a tag from this message\n"
251 "Remove a tag from this message. If the tag is not set, a KeyError exception is raised.\n"
252 "If the tag does not exist, a ValueError exception is raised."},
257 static PyMemberDef MessageInfo_members[] = {
258 {"From", T_OBJECT_EX, offsetof(clawsmail_MessageInfoObject, from), 0,
259 "From - the From header of the message"},
261 {"To", T_OBJECT_EX, offsetof(clawsmail_MessageInfoObject, to), 0,
262 "To - the To header of the message"},
264 {"Subject", T_OBJECT_EX, offsetof(clawsmail_MessageInfoObject, subject), 0,
265 "Subject - the subject header of the message"},
267 {"MessageID", T_OBJECT_EX, offsetof(clawsmail_MessageInfoObject, msgid), 0,
268 "MessageID - the Message-ID header of the message"},
270 {"FilePath", T_OBJECT_EX, offsetof(clawsmail_MessageInfoObject, filepath), 0,
271 "FilePath - path and filename of the message"},
276 static PyTypeObject clawsmail_MessageInfoType = {
277 PyObject_HEAD_INIT(NULL)
279 "clawsmail.MessageInfo", /* tp_name*/
280 sizeof(clawsmail_MessageInfoObject), /* tp_basicsize*/
282 (destructor)MessageInfo_dealloc, /* tp_dealloc*/
289 0, /* tp_as_sequence*/
290 0, /* tp_as_mapping*/
293 MessageInfo_str, /* tp_str*/
297 Py_TPFLAGS_DEFAULT, /* tp_flags*/
298 "A MessageInfo represents" /* tp_doc */
302 0, /* tp_richcompare */
303 0, /* tp_weaklistoffset */
306 MessageInfo_methods, /* tp_methods */
307 MessageInfo_members, /* tp_members */
311 0, /* tp_descr_get */
312 0, /* tp_descr_set */
313 0, /* tp_dictoffset */
314 (initproc)MessageInfo_init,/* tp_init */
319 PyMODINIT_FUNC initmessageinfo(PyObject *module)
321 clawsmail_MessageInfoType.tp_new = PyType_GenericNew;
322 if(PyType_Ready(&clawsmail_MessageInfoType) < 0)
325 Py_INCREF(&clawsmail_MessageInfoType);
326 PyModule_AddObject(module, "MessageInfo", (PyObject*)&clawsmail_MessageInfoType);
329 #define MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(fis, pms) \
333 str = PyString_FromString(fis); \
336 retval = PyObject_SetAttrString((PyObject*)ff, pms, str); \
344 static gboolean update_members(clawsmail_MessageInfoObject *ff, MsgInfo *msginfo)
348 MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(msginfo->from, "From");
349 MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(msginfo->to, "To");
350 MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(msginfo->subject, "Subject");
351 MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(msginfo->msgid, "MessageID");
353 filepath = procmsg_get_message_file_path(msginfo);
355 MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER(filepath, "FilePath");
359 MSGINFO_STRING_TO_PYTHON_MESSAGEINFO_MEMBER("", "FilePath");
367 PyObject* clawsmail_messageinfo_new(MsgInfo *msginfo)
369 clawsmail_MessageInfoObject *ff;
374 ff = (clawsmail_MessageInfoObject*) PyObject_CallObject((PyObject*) &clawsmail_MessageInfoType, NULL);
378 ff->msginfo = msginfo;
380 if(update_members(ff, msginfo))
381 return (PyObject*)ff;
388 PyTypeObject* clawsmail_messageinfo_get_type_object()
390 return &clawsmail_MessageInfoType;
393 MsgInfo* clawsmail_messageinfo_get_msginfo(PyObject *self)
395 return ((clawsmail_MessageInfoObject*)self)->msginfo;