69bcd26c5a512541a222187f535d08c2dd3b1f70
[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 <inttypes.h>
24 #include "pyopenchange/mapistore/pymapistore.h"
25
26 static void py_MAPIStoreContext_dealloc(PyObject *_self)
27 {
28         PyMAPIStoreContextObject *self = (PyMAPIStoreContextObject *) _self;
29
30         mapistore_del_context(self->mstore_ctx, self->context_id);
31         Py_XDECREF(self->parent);
32         PyObject_Del(_self);
33 }
34
35 static PyObject *py_MAPIStoreContext_open(PyMAPIStoreContextObject *self, PyObject *args)
36 {
37         PyMAPIStoreFolderObject         *folder;
38
39         folder = PyObject_New(PyMAPIStoreFolderObject, &PyMAPIStoreFolder);
40         
41         folder->context = self;
42         folder->folder_object = self->folder_object;
43         folder->fid = self->fid;
44         
45         Py_INCREF(self);
46         return (PyObject *)folder;
47 }
48
49 static PyObject *py_MAPIStoreContext_register_subscription(PyMAPIStoreContextObject *self, PyObject *args)
50 {
51         int                                             ret;
52         struct mapistore_mgmt_notif                     n;
53         const char                                      *mapistoreURI;
54         bool                                            WholeStore;
55         uint16_t                                        NotificationFlags;
56         uint64_t                                        FolderID;
57         bool                                            softdeleted;
58         struct mapistore_subscription_list              *subscription_list;
59         struct mapistore_subscription                   *subscription;
60         struct mapistore_object_subscription_parameters subscription_params;
61         uint32_t                                        random_int;
62
63         if (!PyArg_ParseTuple(args, "sbh", &mapistoreURI, &WholeStore, &NotificationFlags)) {
64                 return NULL;
65         }
66
67         n.WholeStore = WholeStore;
68         n.NotificationFlags = NotificationFlags;
69
70         if (WholeStore == true) {
71                 n.FolderID = 0;
72                 n.MessageID = 0;
73                 n.MAPIStoreURI = NULL;
74         } else {
75                 /* Retrieve folderID from mapistoreURI in openchange.ldb */
76                 ret = openchangedb_get_fid(self->parent->ocdb_ctx, mapistoreURI, &FolderID);
77                 if (ret != MAPISTORE_SUCCESS) {
78                         /* Try to retrieve URI from user indexing.tdb */
79                         ret = mapistore_indexing_record_get_fmid(self->mstore_ctx, 
80                                                                  self->mstore_ctx->conn_info->username,
81                                                                  mapistoreURI, false, &FolderID, &softdeleted);
82                         if (ret != MAPISTORE_SUCCESS || softdeleted == true) {
83                                 return PyBool_FromLong(false);
84                         }
85                 }
86
87                 n.FolderID = FolderID;
88                 n.MessageID = 0;
89                 n.MAPIStoreURI = mapistoreURI;
90         }
91         
92
93         ret = mapistore_mgmt_interface_register_subscription(self->mstore_ctx->conn_info, &n);
94
95         /* Upon success attach subscription to session object using
96          * existing mapistore_notification.c implementation */
97         if (ret == MAPISTORE_SUCCESS) {
98                 subscription_list = talloc_zero(self->mstore_ctx, struct mapistore_subscription_list);
99                 DLIST_ADD(self->mstore_ctx->subscriptions, subscription_list);
100
101                 subscription_params.folder_id = n.FolderID;
102                 subscription_params.object_id = n.MessageID;
103                 subscription_params.whole_store = n.WholeStore;
104
105                 /* In OpenChange server, we use handle_id of the
106                  * object, just use rand for now in bindings */
107                 random_int = rand();
108
109                 subscription = mapistore_new_subscription(subscription_list, 
110                                                           self->mstore_ctx,
111                                                           self->mstore_ctx->conn_info->username,
112                                                           random_int, n.NotificationFlags, 
113                                                           &subscription_params);
114                 subscription_list->subscription = subscription;
115         }
116
117         return PyInt_FromLong(!ret ? random_int : -1);
118 }
119
120 static PyObject *py_MAPIStoreContext_unregister_subscription(PyMAPIStoreContextObject *self, PyObject *args)
121 {
122         int                                     ret;
123         struct mapistore_mgmt_notif             n;
124         const char                              *mapistoreURI;
125         bool                                    WholeStore;
126         uint16_t                                NotificationFlags;
127         uint64_t                                FolderID;
128         uint32_t                                identifier;
129
130         if (!PyArg_ParseTuple(args, "sbhi", &mapistoreURI, &WholeStore, &NotificationFlags, &identifier)) {
131                 return NULL;
132         }
133
134         n.WholeStore = WholeStore;
135         n.NotificationFlags = NotificationFlags;
136
137         if (WholeStore == true) {
138                 n.FolderID = 0;
139                 n.MessageID = 0;
140                 n.MAPIStoreURI = NULL;
141         } else {
142                 /* Retrieve folderID from mapistoreURI in openchange.ldb */
143                 ret = openchangedb_get_fid(self->parent->ocdb_ctx, mapistoreURI, &FolderID);
144                 if (ret != MAPISTORE_SUCCESS) {
145                         /* Try to retrieve URI from user indexing.tdb */
146                 }
147
148                 n.FolderID = FolderID;
149                 n.MessageID = 0;
150                 n.MAPIStoreURI = mapistoreURI;
151         }
152         
153
154         ret = mapistore_mgmt_interface_unregister_subscription(self->mstore_ctx->conn_info, &n);
155
156         /* Remove matching notifications from mapistore_notification system */
157         if (ret == MAPISTORE_SUCCESS) {
158                 ret = mapistore_delete_subscription(self->mstore_ctx, identifier, NotificationFlags);
159         }
160
161         return PyBool_FromLong(!ret ? true : false);
162 }
163
164 static PyObject *py_MAPIStoreContext_get_notifications(PyMAPIStoreContextObject *self, PyObject *args)
165 {
166         int                                     ret;
167         struct mapistore_subscription_list      *sel;
168         struct mapistore_notification_list      *nlist;
169
170         for (sel = self->mstore_ctx->subscriptions; sel; sel = sel->next) {
171                 ret = mapistore_get_queued_notifications(self->mstore_ctx, sel->subscription, &nlist);
172                 if (ret == MAPISTORE_SUCCESS) {
173                         while (nlist) {
174                                 printf("notification FolderID: 0x%"PRIx64"\n", 
175                                        nlist->notification->parameters.object_parameters.folder_id);
176                                 printf("notification MessageID: 0x%"PRIx64"\n", 
177                                        nlist->notification->parameters.object_parameters.object_id);
178                                 nlist = nlist->next;
179                         }
180                         talloc_free(nlist);
181                 }
182         }
183
184         if (ret != MAPISTORE_SUCCESS) {
185                 return Py_None;
186         }
187         return Py_None;
188 }
189
190 static PyMethodDef mapistore_context_methods[] = {
191         { "open", (PyCFunction)py_MAPIStoreContext_open, METH_VARARGS },
192         { "add_subscription", (PyCFunction)py_MAPIStoreContext_register_subscription, METH_VARARGS },
193         { "delete_subscription", (PyCFunction)py_MAPIStoreContext_unregister_subscription, METH_VARARGS },
194         { "get_notifications", (PyCFunction)py_MAPIStoreContext_get_notifications, METH_VARARGS },
195         { NULL },
196 };
197
198 static PyGetSetDef mapistore_context_getsetters[] = {
199         { NULL }
200 };
201
202 PyTypeObject PyMAPIStoreContext = {
203         PyObject_HEAD_INIT(NULL) 0,
204         .tp_name = "mapistore context",
205         .tp_basicsize = sizeof (PyMAPIStoreContextObject),
206         .tp_methods = mapistore_context_methods,
207         .tp_getset = mapistore_context_getsetters,
208         .tp_doc = "mapistore context object",
209         .tp_dealloc = (destructor)py_MAPIStoreContext_dealloc,
210         .tp_flags = Py_TPFLAGS_DEFAULT,
211 };