5df134ea001c5ff26ad1d055be68f8b3f4962159
[jelmer/openchange.git] / pyopenchange / mapistore / folder.c
1 /*
2    OpenChange MAPI implementation.
3
4    Python interface to mapistore folder
5
6    Copyright (C) Julien Kerihuel 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 #include "gen_ndr/exchange.h"
25
26 static void py_MAPIStoreFolder_dealloc(PyObject *_self)
27 {
28         PyMAPIStoreFolderObject *self = (PyMAPIStoreFolderObject *)_self;
29
30         Py_DECREF(self->context);
31         PyObject_Del(_self);
32 }
33
34 static PyObject *py_MAPIStoreFolder_create_folder(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs)
35 {
36         int                     ret;
37         /* PyMAPIStoreFolderObject      *folder; */
38         char                    *kwnames[] = { "name", "description", "foldertype", "flags" };
39         const char              *name;
40         const char              *desc = NULL;
41         uint16_t                foldertype = FOLDER_GENERIC;
42         uint16_t                flags = NONE;
43         uint64_t                fid;
44
45         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|shh", kwnames, &name, &desc, &foldertype, &flags)) {
46                 return NULL;
47         }
48
49         /* Step 1. Check if the folder already exists */
50         ret = mapistore_folder_get_child_fid_by_name(self->context->mstore_ctx,
51                                                      self->context->context_id,
52                                                      self->context->folder_object, 
53                                                      name, &fid);
54         if (ret == MAPISTORE_SUCCESS) {
55                 if (flags != OPEN_IF_EXISTS) {
56                         PyErr_MAPIStore_IS_ERR_RAISE(MAPISTORE_ERR_EXIST);
57                         Py_RETURN_NONE;
58                 }
59         }
60         
61         /* TODO: Complete the implementation */
62
63         return Py_None;
64 }
65
66 static PyObject *py_MAPIStoreFolder_get_fid(PyMAPIStoreFolderObject *self, void *closure)
67 {
68         return PyLong_FromLongLong(self->fid);
69 }
70
71 static PyObject *py_MAPIStoreFolder_get_child_count(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs)
72 {
73         uint32_t                        RowCount;
74         enum mapistore_table_type       table_type;
75         char                            *kwnames[] = { "table_type" };
76         int                             retval;
77
78         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwnames, &table_type)) {
79                 return NULL;
80         }
81
82         retval = mapistore_folder_get_child_count(self->context->mstore_ctx, self->context->context_id,
83                                                   (self->folder_object ? self->folder_object : 
84                                                    self->context->folder_object), table_type, &RowCount);
85         if (retval != MAPISTORE_SUCCESS) {
86                 return PyInt_FromLong(-1);
87         }
88
89         return PyInt_FromLong(RowCount);
90 }
91
92 static void convert_datetime_to_tm(TALLOC_CTX *mem_ctx, PyObject *datetime, struct tm *tm)
93 {
94         PyObject *value;
95
96         value = PyObject_GetAttrString(datetime, "year");
97         tm->tm_year = PyInt_AS_LONG(value) - 1900;
98         value = PyObject_GetAttrString(datetime, "month");
99         tm->tm_mon = PyInt_AS_LONG(value) - 1;
100         value = PyObject_GetAttrString(datetime, "day");
101         tm->tm_mday = PyInt_AS_LONG(value);
102         value = PyObject_GetAttrString(datetime, "hour");
103         tm->tm_hour = PyInt_AS_LONG(value);
104         value = PyObject_GetAttrString(datetime, "minute");
105         tm->tm_min = PyInt_AS_LONG(value);
106         value = PyObject_GetAttrString(datetime, "second");
107         tm->tm_sec = PyInt_AS_LONG(value);
108
109 #ifdef  __USE_BSD
110         value = PyObject_CallMethod(datetime, "utcoffset", NULL);
111         if (value && value != Py_None) {
112                 tm->tm_gmtoff = PyInt_AS_LONG(value);
113         }
114         else {
115                 tm->tm_gmtoff = 0;
116         }
117         value = PyObject_CallMethod(datetime, "tzname", NULL);
118         if (value && value != Py_None) {
119                 tm->tm_zone = talloc_strdup(mem_ctx, PyString_AsString(value));
120         }
121         else {
122                 tm->tm_zone = NULL;
123         }
124 #else
125         value = PyObject_CallMethod(datetime, "utcoffset", NULL);
126         if (value && value != Py_None) {
127                 tm->__tm_gmtoff = PyInt_AS_LONG(value);
128         }
129         else {
130                 tm->__tm_gmtoff = 0;
131         }
132         value = PyObject_CallMethod(datetime, "tzname", NULL);
133         if (value && value != Py_None) {
134                 tm->__tm_zone = talloc_strdup(mem_ctx, PyString_AsString(value));
135         }
136         else {
137                 tm->__tm_zone = NULL;
138         }
139 #endif
140 }
141
142 static PyObject *py_MAPIStoreFolder_fetch_freebusy_properties(PyMAPIStoreFolderObject *self, PyObject *args, PyObject *kwargs)
143 {
144         TALLOC_CTX              *mem_ctx;
145         char                    *kwnames[] = { "startdate", "enddate", NULL };
146         PyObject                *start = NULL, *end = NULL, *result = NULL;
147         struct tm               *start_tm, *end_tm;
148         enum mapistore_error    retval;
149         struct mapistore_freebusy_properties *fb_props;
150
151         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwnames, &start, &end)) {
152                 return NULL;
153         }
154
155         mem_ctx = talloc_zero(NULL, TALLOC_CTX);
156
157         if (start) {
158                 if (!PyObject_IsInstance(start, datetime_datetime_class)) {
159                         PyErr_SetString(PyExc_TypeError, "'start' must either be a datetime.datetime instance of None");
160                         goto end;
161                 }
162                 start_tm = talloc_zero(mem_ctx, struct tm);
163                 convert_datetime_to_tm(mem_ctx, start, start_tm);
164         }
165         else {
166                 start_tm = NULL;
167         }
168
169         if (end) {
170                 if (!PyObject_IsInstance(end, datetime_datetime_class)) {
171                         PyErr_SetString(PyExc_TypeError, "'end' must either be a datetime.datetime instance of None");
172                         goto end;
173                 }
174                 end_tm = talloc_zero(mem_ctx, struct tm);
175                 convert_datetime_to_tm(mem_ctx, end, end_tm);
176         }
177         else {
178                 end_tm = NULL;
179         }
180
181         retval = mapistore_folder_fetch_freebusy_properties(self->context->mstore_ctx, self->context->context_id, self->folder_object, start_tm, end_tm, mem_ctx, &fb_props);
182         if (retval != MAPISTORE_SUCCESS) {
183                 PyErr_MAPIStore_IS_ERR_RAISE(retval);
184                 goto end;
185         }
186         result = (PyObject *) instantiate_freebusy_properties(fb_props);
187
188 end:
189         talloc_free(mem_ctx);
190
191         return result;
192 /* enum mapistore_error mapistore_folder_fetch_freebusy_properties(struct mapistore_context *mstore_ctx, uint32_t context_id, void *folder, struct tm *start_tm, struct tm *end_tm, TALLOC_CTX *mem_ctx, struct mapistore_freebusy_properties **fb_props_p) */
193
194 }
195
196 static PyMethodDef mapistore_folder_methods[] = {
197         { "create_folder", (PyCFunction)py_MAPIStoreFolder_create_folder, METH_VARARGS|METH_KEYWORDS },
198         { "get_child_count", (PyCFunction)py_MAPIStoreFolder_get_child_count, METH_VARARGS|METH_KEYWORDS },
199         { "fetch_freebusy_properties", (PyCFunction)py_MAPIStoreFolder_fetch_freebusy_properties, METH_VARARGS|METH_KEYWORDS },
200         { NULL },
201 };
202
203 static PyGetSetDef mapistore_folder_getsetters[] = {
204         { (char *)"fid", (getter)py_MAPIStoreFolder_get_fid, NULL, NULL },
205         { NULL }
206 };
207
208 PyTypeObject PyMAPIStoreFolder = {
209         PyObject_HEAD_INIT(NULL) 0,
210         .tp_name = "mapistore folder",
211         .tp_basicsize = sizeof (PyMAPIStoreFolderObject),
212         .tp_methods = mapistore_folder_methods,
213         .tp_getset = mapistore_folder_getsetters,
214         .tp_doc = "mapistore folder object",
215         .tp_dealloc = (destructor)py_MAPIStoreFolder_dealloc,
216         .tp_flags = Py_TPFLAGS_DEFAULT,
217 };
218
219 void initmapistore_folder(PyObject *m)
220 {
221         if (PyType_Ready(&PyMAPIStoreFolder) < 0) {
222                 return;
223         }
224
225         PyModule_AddObject(m, "FOLDER_GENERIC", PyInt_FromLong(0x1));
226         PyModule_AddObject(m, "FOLDER_SEARCH", PyInt_FromLong(0x2));
227
228         PyModule_AddObject(m, "NONE", PyInt_FromLong(0x0));
229         PyModule_AddObject(m, "OPEN_IF_EXISTS", PyInt_FromLong(0x1));
230 }