[REF+IMP] caldav

bzr revid: hmo@tinyerp.com-20100414073616-i84h1e197yswuv0v
This commit is contained in:
Harry (Open ERP)
2010-04-14 13:06:16 +05:30
parent a3dab7abb8
commit f2311d256f
7 changed files with 230 additions and 154 deletions
+1 -2
View File
@@ -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:
-69
View File
@@ -1,69 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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)
+120 -9
View File
@@ -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):
-49
View File
@@ -1,49 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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
+3 -21
View File
@@ -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'),
+80
View File
@@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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()
+26 -4
View File
@@ -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('/')