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