Explicitely pass a pointer on mapistore context for mapistore_new_subscription
[jelmer/openchange.git] / pyopenchange / mapistore / context.c
1 /*
2    OpenChange MAPI implementation.
3
4    Python interface to mapistore context
5
6    Copyright (C) Julien Kerihuel 2010-2011.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <Python.h>
23 #include "pyopenchange/mapistore/pymapistore.h"
24
25 static void py_MAPIStoreContext_dealloc(PyObject *_self)
26 {
27         PyMAPIStoreContextObject *self = (PyMAPIStoreContextObject *) _self;
28
29         mapistore_del_context(self->mstore_ctx, self->context_id);
30         Py_XDECREF(self->parent);
31         PyObject_Del(_self);
32 }
33
34 static PyObject *py_MAPIStoreContext_open(PyMAPIStoreContextObject *self, PyObject *args)
35 {
36         PyMAPIStoreFolderObject         *folder;
37
38         folder = PyObject_New(PyMAPIStoreFolderObject, &PyMAPIStoreFolder);
39         
40         folder->context = self;
41         folder->folder_object = NULL;
42         folder->fid = self->fid;
43         
44         Py_INCREF(self);
45         return (PyObject *)folder;
46 }
47
48 static PyObject *py_MAPIStoreContext_register_subscription(PyMAPIStoreContextObject *self, PyObject *args)
49 {
50         int                                             ret;
51         struct mapistore_mgmt_notif                     n;
52         const char                                      *mapistoreURI;
53         bool                                            WholeStore;
54         uint16_t                                        NotificationFlags;
55         uint64_t                                        FolderID;
56         bool                                            softdeleted;
57         struct mapistore_subscription_list              *subscription_list;
58         struct mapistore_subscription                   *subscription;
59         struct mapistore_object_subscription_parameters subscription_params;
60         uint32_t                                        random_int;
61
62         if (!PyArg_ParseTuple(args, "sbh", &mapistoreURI, &WholeStore, &NotificationFlags)) {
63                 return NULL;
64         }
65
66         n.WholeStore = WholeStore;
67         n.NotificationFlags = NotificationFlags;
68
69         if (WholeStore == true) {
70                 n.FolderID = 0;
71                 n.MessageID = 0;
72                 n.MAPIStoreURI = NULL;
73         } else {
74                 /* Retrieve folderID from mapistoreURI in openchange.ldb */
75                 ret = openchangedb_get_fid(self->parent->ocdb_ctx, mapistoreURI, &FolderID);
76                 if (ret != MAPISTORE_SUCCESS) {
77                         /* Try to retrieve URI from user indexing.tdb */
78                         ret = mapistore_indexing_record_get_fmid(self->mstore_ctx, 
79                                                                  self->mstore_ctx->conn_info->username,
80                                                                  mapistoreURI, false, &FolderID, &softdeleted);
81                         if (ret != MAPISTORE_SUCCESS || softdeleted == true) {
82                                 return PyBool_FromLong(false);
83                         }
84                 }
85
86                 n.FolderID = FolderID;
87                 n.MessageID = 0;
88                 n.MAPIStoreURI = mapistoreURI;
89         }
90         
91
92         ret = mapistore_mgmt_interface_register_subscription(self->mstore_ctx->conn_info, &n);
93
94         /* Upon success attach subscription to session object using
95          * existing mapistore_notification.c implementation */
96         if (ret == MAPISTORE_SUCCESS) {
97                 subscription_list = talloc_zero(self->mstore_ctx, struct mapistore_subscription_list);
98                 DLIST_ADD(self->mstore_ctx->subscriptions, subscription_list);
99
100                 subscription_params.folder_id = n.FolderID;
101                 subscription_params.object_id = n.MessageID;
102                 subscription_params.whole_store = n.WholeStore;
103
104                 /* In OpenChange server, we use handle_id of the
105                  * object, just use rand for now in bindings */
106                 random_int = rand();
107
108                 subscription = mapistore_new_subscription(subscription_list, 
109                                                           self->mstore_ctx,
110                                                           self->mstore_ctx->conn_info->username,
111                                                           random_int, n.NotificationFlags, 
112                                                           &subscription_params);
113                 subscription_list->subscription = subscription;
114         }
115
116         return PyInt_FromLong(!ret ? random_int : -1);
117 }
118
119 static PyObject *py_MAPIStoreContext_unregister_subscription(PyMAPIStoreContextObject *self, PyObject *args)
120 {
121         int                                     ret;
122         struct mapistore_mgmt_notif             n;
123         const char                              *mapistoreURI;
124         bool                                    WholeStore;
125         uint16_t                                NotificationFlags;
126         uint64_t                                FolderID;
127         uint32_t                                identifier;
128
129         if (!PyArg_ParseTuple(args, "sbhi", &mapistoreURI, &WholeStore, &NotificationFlags, &identifier)) {
130                 return NULL;
131         }
132
133         n.WholeStore = WholeStore;
134         n.NotificationFlags = NotificationFlags;
135
136         if (WholeStore == true) {
137                 n.FolderID = 0;
138                 n.MessageID = 0;
139                 n.MAPIStoreURI = NULL;
140         } else {
141                 /* Retrieve folderID from mapistoreURI in openchange.ldb */
142                 ret = openchangedb_get_fid(self->parent->ocdb_ctx, mapistoreURI, &FolderID);
143                 if (ret != MAPISTORE_SUCCESS) {
144                         /* Try to retrieve URI from user indexing.tdb */
145                 }
146
147                 n.FolderID = FolderID;
148                 n.MessageID = 0;
149                 n.MAPIStoreURI = mapistoreURI;
150         }
151         
152
153         ret = mapistore_mgmt_interface_unregister_subscription(self->mstore_ctx->conn_info, &n);
154
155         /* Remove matching notifications from mapistore_notification system */
156         if (ret == MAPISTORE_SUCCESS) {
157                 ret = mapistore_delete_subscription(self->mstore_ctx, identifier, NotificationFlags);
158         }
159
160         return PyBool_FromLong(!ret ? true : false);
161 }
162
163 static PyObject *py_MAPIStoreContext_get_notifications(PyMAPIStoreContextObject *self, PyObject *args)
164 {
165         int                                     ret;
166         struct mapistore_subscription_list      *sel;
167         struct mapistore_notification_list      *nlist;
168
169         for (sel = self->mstore_ctx->subscriptions; sel; sel = sel->next) {
170                 ret = mapistore_get_queued_notifications(self->mstore_ctx, sel->subscription, &nlist);
171                 if (ret == MAPISTORE_SUCCESS) {
172                         while (nlist) {
173                                 printf("notification FolderID: 0x%llx\n", 
174                                        nlist->notification->parameters.object_parameters.folder_id);
175                                 printf("notification MessageID: 0x%llx\n", 
176                                        nlist->notification->parameters.object_parameters.object_id);
177                                 nlist = nlist->next;
178                         }
179                         talloc_free(nlist);
180                 }
181         }
182
183         if (ret != MAPISTORE_SUCCESS) {
184                 return Py_None;
185         }
186         return Py_None;
187 }
188
189 static PyMethodDef mapistore_context_methods[] = {
190         { "open", (PyCFunction)py_MAPIStoreContext_open, METH_VARARGS },
191         { "add_subscription", (PyCFunction)py_MAPIStoreContext_register_subscription, METH_VARARGS },
192         { "delete_subscription", (PyCFunction)py_MAPIStoreContext_unregister_subscription, METH_VARARGS },
193         { "get_notifications", (PyCFunction)py_MAPIStoreContext_get_notifications, METH_VARARGS },
194         { NULL },
195 };
196
197 static PyGetSetDef mapistore_context_getsetters[] = {
198         { NULL }
199 };
200
201 PyTypeObject PyMAPIStoreContext = {
202         PyObject_HEAD_INIT(NULL) 0,
203         .tp_name = "mapistore context",
204         .tp_basicsize = sizeof (PyMAPIStoreContextObject),
205         .tp_methods = mapistore_context_methods,
206         .tp_getset = mapistore_context_getsetters,
207         .tp_doc = "mapistore context object",
208         .tp_dealloc = (destructor)py_MAPIStoreContext_dealloc,
209         .tp_flags = Py_TPFLAGS_DEFAULT,
210 };