Python plugin: Let Account objects compare equal if they refer to the same account
[claws.git] / src / plugins / python / accounttype.c
1 /* Python plugin for Claws-Mail
2  * Copyright (C) 2013 Holger Berndt <hb@claws-mail.org>
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 "accounttype.h"
24
25 #include <structmember.h>
26
27 typedef struct {
28     PyObject_HEAD
29     PyObject *account_name;
30     PyObject *address;
31     PrefsAccount *account;
32 } clawsmail_AccountObject;
33
34 static int Account_init(clawsmail_AccountObject *self, PyObject *args, PyObject *kwds)
35 {
36   Py_INCREF(Py_None);
37   self->account_name = Py_None;
38
39   Py_INCREF(Py_None);
40   self->address = Py_None;
41
42   self->account = NULL;
43   return 0;
44 }
45
46
47 static void Account_dealloc(clawsmail_AccountObject* self)
48 {
49   Py_XDECREF(self->account_name);
50   Py_XDECREF(self->address);
51
52   self->ob_type->tp_free((PyObject*)self);
53 }
54
55 static int Account_compare(clawsmail_AccountObject *obj1, clawsmail_AccountObject *obj2)
56 {
57   if(obj1->account->account_id < obj2->account->account_id)
58     return -1;
59   else if(obj1->account->account_id > obj2->account->account_id)
60     return 1;
61   else
62     return 0;
63 }
64
65 static PyObject* Account_str(PyObject *self)
66 {
67   PyObject *str;
68   str = PyString_FromString("Account: ");
69   if(str == NULL)
70     return NULL;
71   PyString_ConcatAndDel(&str, PyObject_GetAttrString(self, "account_name"));
72
73   return str;
74 }
75
76 static PyObject* get_account_name(clawsmail_AccountObject *self, void *closure)
77 {
78   Py_INCREF(self->account_name);
79   return self->account_name;
80 }
81
82 static PyObject* get_address(clawsmail_AccountObject *self, void *closure)
83 {
84   Py_INCREF(self->address);
85   return self->address;
86 }
87
88 static PyObject* get_is_default(clawsmail_AccountObject *self, void *closure)
89 {
90   if(self->account->is_default)
91     Py_RETURN_TRUE;
92   else
93     Py_RETURN_FALSE;
94 }
95
96 static PyGetSetDef Account_getset[] = {
97     {"account_name", (getter)get_account_name, (setter)NULL,
98       "account_name - name of the account", NULL},
99
100     {"address", (getter)get_address, (setter)NULL,
101      "address - address of the account", NULL},
102
103     {"is_default", (getter)get_is_default, (setter)NULL,
104      "is_default - whether this account is the default account", NULL},
105
106     {NULL}
107 };
108
109 static PyTypeObject clawsmail_AccountType = {
110     PyObject_HEAD_INIT(NULL)
111     0,                         /* ob_size*/
112     "clawsmail.Account",       /* tp_name*/
113     sizeof(clawsmail_AccountObject), /* tp_basicsize*/
114     0,                         /* tp_itemsize*/
115     (destructor)Account_dealloc, /* tp_dealloc*/
116     0,                         /* tp_print*/
117     0,                         /* tp_getattr*/
118     0,                         /* tp_setattr*/
119     (cmpfunc)Account_compare,  /* tp_compare*/
120     0,                         /* tp_repr*/
121     0,                         /* tp_as_number*/
122     0,                         /* tp_as_sequence*/
123     0,                         /* tp_as_mapping*/
124     0,                         /* tp_hash */
125     0,                         /* tp_call*/
126     Account_str,               /* tp_str*/
127     0,                         /* tp_getattro*/
128     0,                         /* tp_setattro*/
129     0,                         /* tp_as_buffer*/
130     Py_TPFLAGS_DEFAULT,        /* tp_flags*/
131     "Account objects.\n\n"     /* tp_doc */
132     "Do not construct objects of this type yourself.",
133     0,                         /* tp_traverse */
134     0,                         /* tp_clear */
135     0,                         /* tp_richcompare */
136     0,                         /* tp_weaklistoffset */
137     0,                         /* tp_iter */
138     0,                         /* tp_iternext */
139     0,                         /* tp_methods */
140     0,                         /* tp_members */
141     Account_getset,            /* tp_getset */
142     0,                         /* tp_base */
143     0,                         /* tp_dict */
144     0,                         /* tp_descr_get */
145     0,                         /* tp_descr_set */
146     0,                         /* tp_dictoffset */
147     (initproc)Account_init,    /* tp_init */
148     0,                         /* tp_alloc */
149     0,                         /* tp_new */
150 };
151
152
153 gboolean cmpy_add_account(PyObject *module)
154 {
155   clawsmail_AccountType.tp_new = PyType_GenericNew;
156   if(PyType_Ready(&clawsmail_AccountType) < 0)
157     return FALSE;
158
159   Py_INCREF(&clawsmail_AccountType);
160   return (PyModule_AddObject(module, "Account", (PyObject*)&clawsmail_AccountType) == 0);
161 }
162
163 static gboolean update_members(clawsmail_AccountObject *self, PrefsAccount *account)
164 {
165   if(account->account_name) {
166     Py_XDECREF(self->account_name);
167     self->account_name = PyString_FromString(account->account_name);
168     if(!self->account_name)
169       goto err;
170   }
171
172   if(account->address) {
173     Py_XDECREF(self->address);
174     self->address = PyString_FromString(account->address);
175     if(!self->address)
176       goto err;
177   }
178
179   self->account = account;
180
181   return TRUE;
182 err:
183   Py_XDECREF(self->account_name);
184   Py_XDECREF(self->address);
185   return FALSE;
186 }
187
188 PyObject* clawsmail_account_new(PrefsAccount *account)
189 {
190   clawsmail_AccountObject *ff;
191
192   if(!account)
193     return NULL;
194
195   ff = (clawsmail_AccountObject*) PyObject_CallObject((PyObject*) &clawsmail_AccountType, NULL);
196   if(!ff)
197     return NULL;
198
199   if(update_members(ff, account))
200     return (PyObject*)ff;
201   else {
202     Py_XDECREF(ff);
203     return NULL;
204   }
205 }