1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
22 from osv import osv, fields
23 from tools.translate import _
27 from document import nodes
30 class node_database(nodes.node_database):
31 def _child_get(self, cr, name=False, parent_id=False, domain=None):
32 dirobj = self.context._dirobj
33 uid = self.context.uid
34 ctx = self.context.context.copy()
38 domain2 = domain + [('calendar_collection','=', False)]
39 res = super(node_database, self)._child_get(cr, name=name, parent_id=parent_id, domain=domain2)
40 where = [('parent_id','=',parent_id)]
41 domain2 = domain + [('calendar_collection','=', True)]
43 where.append(('name','=',name))
47 where2 = where + [('type', '=', 'directory')]
48 ids = dirobj.search(cr, uid, where2, context=ctx)
49 for dirr in dirobj.browse(cr,uid,ids,context=ctx):
50 res.append(node_calendar_collection(dirr.name,self,self.context,dirr))
53 class node_calendar_collection(nodes.node_dir):
55 "http://calendarserver.org/ns/" : ('getctag',),
58 "http://calendarserver.org/ns/" : '_get_dav',
61 http_options = { 'DAV': ['calendar-access'] }
63 def _file_get(self,cr, nodename=False):
66 def _child_get(self, cr, name=False, parent_id=False, domain=None):
67 dirobj = self.context._dirobj
68 uid = self.context.uid
69 ctx = self.context.context.copy()
71 where = [('collection_id','=',self.dir_id)]
73 if name and name.endswith('.ics'):
77 where.append(('name','=',name))
80 where = where + domain
81 fil_obj = dirobj.pool.get('basic.calendar')
82 ids = fil_obj.search(cr,uid,where,context=ctx)
84 for calender in fil_obj.browse(cr, uid, ids, context=ctx):
86 res.append(node_calendar(calender.name, self, self.context, calender))
88 res.append(res_node_calendar(name, self, self.context, calender))
91 def _get_dav_owner(self, cr):
95 def _get_ttag(self, cr):
96 return 'calen-dir-%d' % self.dir_id
98 def _get_dav_getctag(self, cr):
99 result = self.get_etag(cr)
102 class node_calendar(nodes.node_class):
103 our_type = 'collection'
105 "http://calendarserver.org/ns/" : ('getctag',),
106 'http://groupdav.org/': ('resourcetype',),
107 "urn:ietf:params:xml:ns:caldav" : (
108 'calendar-description',
111 'calendar-user-address-set',
112 'schedule-inbox-URL',
113 'schedule-outbox-URL',)}
116 'http://groupdav.org/': '_get_gdav',
117 "http://calendarserver.org/ns/" : '_get_dav',
118 "urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
120 http_options = { 'DAV': ['calendar-access'] }
122 def __init__(self,path, parent, context, calendar):
123 super(node_calendar,self).__init__(path, parent,context)
124 self.calendar_id = calendar.id
125 self.mimetype = 'application/x-directory'
126 self.create_date = calendar.create_date
127 self.write_date = calendar.write_date or calendar.create_date
128 self.content_length = 0
129 self.displayname = calendar.name
130 self.cal_type = calendar.type
132 def _get_dav_getctag(self, cr):
133 result = self._get_ttag(cr) + ':' + str(time.time())
136 def _get_gdav_resourcetype(self, cr):
137 return (str(self.cal_type + '-collection'), 'http://groupdav.org/')
139 def removeme_match_dav_eprop(self, cr, match, ns, prop):
141 if ns == "DAV:" and prop == "getetag":
142 dirobj = self.context._dirobj
143 uid = self.context.uid
144 ctx = self.context.context.copy()
145 tem, dav_time = tuple(match.split(':'))
146 model, res_id = tuple(tem.split('_'))
147 model_obj = dirobj.pool.get(model)
148 model = model_obj.browse(cr, uid, res_id, context=ctx)
149 write_time = model.write_date or model.create_date
150 wtime = time.mktime(time.strptime(write_time,'%Y-%m-%d %H:%M:%S'))
151 if float(dav_time) == float(wtime):
154 res = super(node_calendar, self).match_dav_eprop(cr, match, ns, prop)
157 def get_domain(self, cr, filters):
160 # dirobj = self.context._dirobj
161 #uid = self.context.uid
162 #ctx = self.context.context.copy()
163 #ctx.update(self.dctx)
164 # calendar_obj = dirobj.pool.get('basic.calendar')
167 if filters.localName == 'calendar-query':
169 for filter_child in filters.childNodes:
170 if filter_child.nodeType == filter_child.TEXT_NODE:
172 if filter_child.localName == 'filter':
173 for vcalendar_filter in filter_child.childNodes:
174 if vcalendar_filter.nodeType == vcalendar_filter.TEXT_NODE:
176 if vcalendar_filter.localName == 'comp-filter':
177 if vcalendar_filter.getAttribute('name') == 'VCALENDAR':
178 for vevent_filter in vcalendar_filter.childNodes:
179 if vevent_filter.nodeType == vevent_filter.TEXT_NODE:
181 if vevent_filter.localName == 'comp-filter':
182 if vevent_filter.getAttribute('name') == 'VEVENT':
183 res = [('type','=','vevent')]
184 if vevent_filter.getAttribute('name') == 'VTODO':
185 res = [('type','=','vtodo')]
187 elif filters.localName == 'calendar-multiget':
189 for filter_child in filters.childNodes:
190 if filter_child.nodeType == filter_child.TEXT_NODE:
192 if filter_child.localName == 'href':
193 if not filter_child.firstChild:
195 uri = filter_child.firstChild.data
196 caluri = uri.split('/')
199 if caluri not in names : names.append(caluri)
200 res = [('name','in',names)]
204 def children(self, cr, domain=None):
205 return self._child_get(cr, domain=domain)
207 def child(self,cr, name, domain=None):
208 res = self._child_get(cr, name, domain=domain)
214 def _child_get(self, cr, name=False, parent_id=False, domain=None):
215 dirobj = self.context._dirobj
216 uid = self.context.uid
217 ctx = self.context.context.copy()
218 ctx.update(self.dctx)
221 if name.endswith('.ics'):
223 where.append(('id','=',int(name)))
226 #for opr1, opt, opr2 in domain:
227 # if opr1 == 'type' and opr2 != self.cal_type:
230 fil_obj = dirobj.pool.get('basic.calendar')
231 ids = fil_obj.search(cr, uid, domain)
233 if self.calendar_id in ids:
234 res = fil_obj.get_calendar_objects(cr, uid, [self.calendar_id], self, domain=where, context=ctx)
237 def create_child(self, cr, path, data):
238 """ API function to create a child file object and node
239 Return the node_* created
241 # we ignore the path, it will be re-generated automatically
242 res = self.set_data(cr, data)
244 # TODO: use the res to create at least one node
248 def set_data(self, cr, data, fil_obj = None):
249 uid = self.context.uid
250 calendar_obj = self.context._dirobj.pool.get('basic.calendar')
251 res = calendar_obj.import_cal(cr, uid, data, self.calendar_id)
254 def get_data_len(self, cr, fil_obj = None):
255 return self.content_length
257 def _get_ttag(self,cr):
258 return 'calendar-%d' % (self.calendar_id,)
264 class res_node_calendar(nodes.node_class):
267 "http://calendarserver.org/ns/" : ('getctag'),
268 "urn:ietf:params:xml:ns:caldav" : (
269 'calendar-description',
272 'calendar-user-address-set',
273 'schedule-inbox-URL',
274 'schedule-outbox-URL',)}
276 "http://calendarserver.org/ns/" : '_get_dav',
277 "urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
279 http_options = { 'DAV': ['calendar-access'] }
281 def __init__(self,path, parent, context, res_obj, res_model=None, res_id=None):
282 super(res_node_calendar,self).__init__(path, parent, context)
283 self.mimetype = 'text/calendar'
284 self.create_date = parent.create_date
285 self.write_date = parent.write_date or parent.create_date
286 self.calendar_id = hasattr(parent, 'calendar_id') and parent.calendar_id or False
288 if not self.calendar_id: self.calendar_id = res_obj.id
289 pr = res_obj.perm_read()[0]
290 self.create_date = pr.get('create_date')
291 self.write_date = pr.get('write_date') or pr.get('create_date')
292 self.displayname = res_obj.name
294 self.content_length = 0
296 self.model = res_model
299 def open(self, cr, mode=False):
300 uid = self.context.uid
301 if self.type in ('collection','database'):
303 s = StringIO.StringIO(self.get_data(cr))
307 def get_data(self, cr, fil_obj = None):
308 uid = self.context.uid
309 calendar_obj = self.context._dirobj.pool.get('basic.calendar')
310 context = self.context.context.copy()
311 context.update({'model': self.model, 'res_id':self.res_id})
312 res = calendar_obj.export_cal(cr, uid, [self.calendar_id], context=context)
315 def get_data_len(self, cr, fil_obj = None):
316 return self.content_length
318 def set_data(self, cr, data, fil_obj = None):
319 uid = self.context.uid
320 calendar_obj = self.context._dirobj.pool.get('basic.calendar')
321 res = calendar_obj.import_cal(cr, uid, data, self.calendar_id)
324 def _get_ttag(self,cr):
326 if self.model and self.res_id:
327 res = '%s_%d' % (self.model, self.res_id)
328 elif self.calendar_id:
329 res = '%d' % (self.calendar_id)
332 def _get_caldav_calendar_data(self, cr):
333 return self.get_data(cr)
336 def _get_caldav_calendar_description(self, cr):
337 uid = self.context.uid
338 calendar_obj = self.context._dirobj.pool.get('basic.calendar')
339 ctx = self.context.context.copy()
340 ctx.update(self.dctx)
341 calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
342 return calendar.description
345 def _get_caldav_calendar_home_set(self, cr):
346 import xml.dom.minidom
348 uid = self.context.uid
349 ctx = self.context.context.copy()
350 ctx.update(self.dctx)
351 doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
353 calendar_obj = self.context._dirobj.pool.get('basic.calendar')
354 calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
355 huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, calendar.collection_id.name)))
356 href = doc.documentElement
357 href.tagName = 'D:href'
358 href.appendChild(huri)
361 def _get_caldav_calendar_user_address_set(self, cr):
362 import xml.dom.minidom
363 dirobj = self.context._dirobj
364 uid = self.context.uid
365 ctx = self.context.context.copy()
366 ctx.update(self.dctx)
367 user_obj = self.context._dirobj.pool.get('res.users')
368 user = user_obj.browse(cr, uid, uid, context=ctx)
369 doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
370 href = doc.documentElement
371 href.tagName = 'D:href'
372 huri = doc.createTextNode('MAILTO:' + user.email)
373 href.appendChild(huri)
377 def _get_caldav_schedule_inbox_URL(self, cr):
378 import xml.dom.minidom
380 uid = self.context.uid
381 ctx = self.context.context.copy()
382 ctx.update(self.dctx)
383 calendar_obj = self.context._dirobj.pool.get('basic.calendar')
384 calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
385 res = '%s/%s' %(calendar.name, calendar.collection_id.name)
386 doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
387 href = doc.documentElement
388 href.tagName = 'D:href'
389 huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, res)))
390 href.appendChild(huri)
395 uid = self.context.uid
397 if self.type in ('collection','database'):
399 if self.model and self.res_id:
400 document_obj = self.context._dirobj.pool.get(self.model)
402 res = document_obj.unlink(cr, uid, [self.res_id])
406 def _get_caldav_schedule_outbox_URL(self, cr):
407 return self._get_caldav_schedule_inbox_URL(cr)
409 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4