diff --git a/addons/caldav/__init__.py b/addons/caldav/__init__.py index 95c230e09f8..cb496d12de0 100644 --- a/addons/caldav/__init__.py +++ b/addons/caldav/__init__.py @@ -20,8 +20,7 @@ ############################################################################## import calendar -import caldav_fs -import caldav_server +import calendar_collection import wizard # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/caldav/caldav_fs.py b/addons/caldav/caldav_fs.py deleted file mode 100644 index c7505b3846b..00000000000 --- a/addons/caldav/caldav_fs.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from document_webdav import dav_fs -from document_webdav.cache import memoize -class openerp_dav_handler(dav_fs.openerp_dav_handler): - PROPS = {'DAV:': dav_fs.openerp_dav_handler.PROPS['DAV:'] + - ('owner',), - 'http://calendarserver.org/ns/': ('getctag')} - - M_NS = { "DAV:" : dav_fs.openerp_dav_handler.M_NS['DAV:'], - "http://calendarserver.org/ns/" : '_get_dav'} - - @memoize(dav_fs.CACHE_SIZE) - def _get_dav_getctag(self,uri): - print """ return the CTag of an object """ - self.parent.log_message('get ctag: %s' % uri) - if uri[-1]=='/':uri=uri[:-1] - result = 0 - cr, uid, pool, dbname, uri2 = self.get_cr(uri) - if not dbname: - cr.close() - return '0' - node = self.uri2object(cr, uid, pool, uri2) - if not node: - cr.close() - raise DAV_NotFound(uri2) - result = node.get_ctag(cr) - cr.close() - return str(result) - - @memoize(dav_fs.CACHE_SIZE) - def _get_dav_owner(self,uri): - print """ return the Owner of an object """ - self.parent.log_message('get ctag: %s' % uri) - if uri[-1]=='/':uri=uri[:-1] - result = 0 - cr, uid, pool, dbname, uri2 = self.get_cr(uri) - if not dbname: - cr.close() - return '0' - node = self.uri2object(cr, uid, pool, uri2) - if not node: - cr.close() - raise DAV_NotFound(uri2) - result = node.get_owner(cr) - cr.close() - return str(result) - - - diff --git a/addons/caldav/caldav_node.py b/addons/caldav/caldav_node.py index 311e0fef0c8..9c7c73a098d 100644 --- a/addons/caldav/caldav_node.py +++ b/addons/caldav/caldav_node.py @@ -51,12 +51,42 @@ class node_database(nodes.node_database): res.append(node_calendar_collection(dirr.name,self,self.context,dirr)) return res -class node_calendar_collection(nodes.node_dir): - def get_dav_props(self, cr): - res = {} - return res +class node_calendar_collection(nodes.node_dir): + PROPS = { + "http://calendarserver.org/ns/" : ('getctag'), + "urn:ietf:params:xml:ns:caldav" : ( + 'calendar-description', + 'calendar-data', + 'calendar-home-set', + 'calendar-user-address-set', + 'schedule-inbox-URL', + 'schedule-outbox-URL',)} + M_NS = { + "http://calendarserver.org/ns/" : '_get_dav', + "urn:ietf:params:xml:ns:caldav" : '_get_caldav'} + + def get_dav_props(self, cr): + return self.PROPS - def get_dav_eprop(self,cr,ns,prop): + def get_dav_eprop(self,cr, ns, propname): + if self.M_NS.has_key(ns): + prefix = self.M_NS[ns] + else: + print "No namespace:",ns, "( for prop:", propname,")" + return None + + mname = prefix + "_" + propname + + if not hasattr(self, mname): + return None + + try: + m = getattr(self, mname) + r = m(cr) + return r + except AttributeError, e: + print 'Property %s not supported' % propname + print "Exception:", e return None def _child_get(self, cr, name=False, parent_id=False, domain=None): @@ -78,7 +108,7 @@ class node_calendar_collection(nodes.node_dir): res.append(node_calendar(fil.name,self,self.context,fil)) return res - def get_owner(self, cr): + def _get_dav_owner(self, cr): return False @@ -97,9 +127,90 @@ class node_calendar_collection(nodes.node_dir): def _get_ttag(self, cr): return 'calendar collection-%d' % self.dir_id - - def get_ctag(self, cr): - return self.get_etag(cr) + + def _get_dav_getctag(self, cr): + result = self.get_etag(cr) + return str(result) + + + def _get_caldav_calendar_description(self, cr): + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + ids = [self.dir_id] + res = dirobj.get_description(cr, uid, ids, context=ctx) + return res + + def _get_caldav_calendar_data(self, cr): + return self.get_data(cr) + + def _get_caldav_calendar_home_set(self, cr): + import xml.dom.minidom + import urllib + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None) + root_cal_dir = dirobj._get_root_calendar_directory(cr, uid, context=ctx) + huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, root_cal_dir))) + href = doc.documentElement + href.tagName = 'D:href' + href.appendChild(huri) + return href + + def _get_caldav_calendar_user_address_set(self, cr): + import xml.dom.minidom + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + user_obj = self.context._dirobj.pool.get('res.users') + user = user_obj.browse(cr, uid, uid, context=ctx) + doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None) + href = doc.documentElement + href.tagName = 'D:href' + huri = doc.createTextNode('MAILTO:' + user.email) + href.appendChild(huri) + return href + + + def _get_caldav_schedule_inbox_URL(self, cr): + import xml.dom.minidom + import urllib + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + ids = [self.dir_id] + res = collection_obj.get_schedule_inbox_URL(cr, uid, ids, context=ctx) + + doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None) + href = doc.documentElement + href.tagName = 'D:href' + huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, res))) + href.appendChild(huri) + return href + + + + def _get_caldav_schedule_outbox_URL(self, cr): + import xml.dom.minidom + import urllib + dirobj = self.context._dirobj + uid = self.context.uid + ctx = self.context.context.copy() + ctx.update(self.dctx) + ids = [self.dir_id] + res = collection_obj.get_schedule_outbox_URL(cr, uid, ids, context=ctx) + + doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None) + href = doc.documentElement + href.tagName = 'D:href' + huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, res))) + href.appendChild(huri) + return href class node_calendar(nodes.node_class): diff --git a/addons/caldav/caldav_server.py b/addons/caldav/caldav_server.py deleted file mode 100644 index 77244e5d764..00000000000 --- a/addons/caldav/caldav_server.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## -from service import http_server -from document_webdav import webdav_server -import tools -from caldav_fs import openerp_dav_handler -from tools.config import config - -class DAVHandler(webdav_server.DAVHandler): - def setup(self): - davpath = '/'+config.get_misc('webdav','vdir','webdav') - self.baseuri = "http://%s:%d/"% (self.server.server_name,self.server.server_port) - self.IFACE_CLASS = openerp_dav_handler(self, self.verbose) - - - -handler = webdav_server.handler -if handler: - handler = DAVHandler - handler.debug = config.get_misc('webdav','debug',True) - handler._config = webdav_server.conf - -if http_server.httpd and handler: - for vdir in http_server.httpd.server.vdirs: - print vdir.handler , webdav_server.DAVHandler - if vdir.handler == webdav_server.DAVHandler: - vdir.handler = handler -if http_server.httpsd and handler: - for vdir in http_server.httpsd.server.vdirs: - if vdir.handler == webdav_server.DAVHandler: - vdir.handler = handler diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py index 6ccd5989d5c..4f672838155 100644 --- a/addons/caldav/calendar.py +++ b/addons/caldav/calendar.py @@ -31,7 +31,6 @@ import pytz import re import tools import time -import caldav_node try: import vobject @@ -410,23 +409,6 @@ class CalDAV(object): self.ical_reset('value') return res -class calendar_collection(osv.osv): - _inherit = 'document.directory' - _columns = { - 'calendar_collection' : fields.boolean('Calendar Collection'), - 'calendar_ids': fields.one2many('basic.calendar', 'collection_id', 'Calendars'), - } - _default = { - 'calendar_collection' : False, - } - def _locate_child(self, cr, uid, root_id, uri,nparent, ncontext): - """ try to locate the node in uri, - Return a tuple (node_dir, remaining_path) - """ - return (caldav_node.node_database(context=ncontext), uri) - -calendar_collection() - class Calendar(CalDAV, osv.osv): _name = 'basic.calendar' _calname = 'calendar' @@ -445,10 +427,10 @@ class Calendar(CalDAV, osv.osv): 'vtimezone': None, # Use: O-n, Type: Collection of Timezone class } _columns = { - 'name': fields.char("Name", size=64), - 'collection_id': fields.many2one('document.directory', 'Collection', \ - required=True), + 'name': fields.char("Name", size=64), 'user_id': fields.many2one('res.users', 'Owner'), + 'collection_id': fields.many2one('document.directory', 'Collection', \ + required=True), 'line_ids': fields.one2many('basic.calendar.lines', 'calendar_id', 'Calendar Lines'), 'create_date': fields.datetime('Created Date'), 'write_date': fields.datetime('Modifided Date'), diff --git a/addons/caldav/calendar_collection.py b/addons/caldav/calendar_collection.py new file mode 100644 index 00000000000..06e799b1686 --- /dev/null +++ b/addons/caldav/calendar_collection.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +from osv import osv, fields +from tools.translate import _ +import caldav_node + +class calendar_collection(osv.osv): + _inherit = 'document.directory' + _columns = { + 'calendar_collection' : fields.boolean('Calendar Collection'), + 'calendar_ids': fields.one2many('basic.calendar', 'collection_id', 'Calendars'), + } + _default = { + 'calendar_collection' : False, + } + def _get_root_calendar_directory(self, cr, uid, context=None): + objid = self.pool.get('ir.model.data') + try: + mid = objid._get_id(cr, uid, 'document', 'dir_calendars') + if not mid: + return False + root_id = objid.read(cr, uid, mid, ['res_id'])['res_id'] + root_cal_dir = self.browse(cr, uid, root_id, context=context) + return root_cal_dir.name + except Exception, e: + import netsvc + logger = netsvc.Logger() + logger.notifyChannel("document", netsvc.LOG_WARNING, 'Cannot set root directory for Calendars:'+ str(e)) + return False + return False + + def _locate_child(self, cr, uid, root_id, uri,nparent, ncontext): + """ try to locate the node in uri, + Return a tuple (node_dir, remaining_path) + """ + return (caldav_node.node_database(context=ncontext), uri) + + def get_description(self, cr, uid, ids, context=None): + #TODO : return description of all calendars + if not context: + context = {} + return False + + def get_schedule_inbox_URL(self, cr, uid, ids, context=None): + calendar_obj = self.pool.get('basic.calendar') + + calendar_ids = calendar_obj.search(cr, uid, [ + ('user_id', '=', uid), ('collection_id', 'in', ids) + ], limit=1, context=context) + + root_cal_dir = self._get_root_calendar_directory(cr, uid, context=context) + if not calendar_ids: + return root_cal_dir + calendar_id = calendar_ids[0] + calendar = calendar_obj.browse(cr, uid, calendar_id, + context=context) + return '%s/%s' %(root_cal_dir, calendar.name) + + def get_schedule_outbox_URL(self, cr, uid, ids, context=None): + return self.get_schedule_inbox_URL(cr, uid, ids, context=context) + +calendar_collection() diff --git a/addons/document_webdav/dav_fs.py b/addons/document_webdav/dav_fs.py index 9be77c50daa..41a65c73bfb 100644 --- a/addons/document_webdav/dav_fs.py +++ b/addons/document_webdav/dav_fs.py @@ -63,7 +63,17 @@ class openerp_dav_handler(dav_interface): self.verbose = verbose def get_propnames(self,uri): - props = self.PROPS + props = self.PROPS + self.parent.log_message('get propnames: %s' % uri) + if uri[-1]=='/':uri=uri[:-1] + cr, uid, pool, dbname, uri2 = self.get_cr(uri) + if not dbname: + cr.close() + return props + node = self.uri2object(cr, uid, pool, uri2) + if node: + props.update(node.get_dav_props(cr)) + cr.close() return props def _get_dav_lockdiscovery(self, uri): @@ -71,7 +81,8 @@ class openerp_dav_handler(dav_interface): def _get_dav_supportedlock(self, uri): raise DAV_NotFound - def get_prop(self,uri,ns,propname): + + def get_prop(self, uri, ns, propname): """ return the value of a given property uri -- uri of the object to get the property of @@ -79,8 +90,19 @@ class openerp_dav_handler(dav_interface): pname -- name of the property """ if self.M_NS.has_key(ns): - return dav_interface.get_prop(self,uri,ns,propname) - raise DAV_NotFound + return dav_interface.get_prop(self,uri,ns,propname) + if uri[-1]=='/':uri=uri[:-1] + cr, uid, pool, dbname, uri2 = self.get_cr(uri) + if not dbname: + cr.close() + raise DAV_NotFound + node = self.uri2object(cr, uid, pool, uri2) + if not node: + cr.close() + raise DAV_NotFound + res = node.get_dav_eprop(cr,ns,propname) + cr.close() + return res def get_db(self,uri): names=self.uri2local(uri).split('/')