[REF+IMP] caldav
bzr revid: hmo@tinyerp.com-20100414073616-i84h1e197yswuv0v
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
@@ -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'),
|
||||
|
||||
@@ -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()
|
||||
@@ -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('/')
|
||||
|
||||
Reference in New Issue
Block a user