bzr revid: hmo@tinyerp.com-20100730065747-z6dngo0mtk7vh0ov
This commit is contained in:
Harry (OpenERP)
2010-07-30 12:27:47 +05:30
14 changed files with 823 additions and 809 deletions
+1
View File
@@ -1500,6 +1500,7 @@ true, it will allow you to hide the event alarm information without removing it.
@param context: A standard dictionary for contextual values
@return: List of Dictionary of form [{‘name_of_the_field’: value, ...}, ...]
"""
# FIXME This whole id mangling has to go!
if not context:
context = {}
+6 -5
View File
@@ -26,15 +26,16 @@ import urlparse
urlparse.uses_netloc.append('caldav')
urlparse.uses_netloc.append('caldavs')
super_mk_prop_response = webdav.mk_prop_response
def mk_prop_response(self,uri,good_props,bad_props,doc):
res = super_mk_prop_response(self, uri,good_props,bad_props,doc)
uris = uri.split('/')
calendar = False
def mk_prop_response(self,uri,good_props,bad_props,doc):
res = super_mk_prop_response(self, uri,good_props,bad_props,doc)
uris = uri.split('/')
calendar = False
if 'http://calendarserver.org/ns/' in good_props or 'http://calendarserver.org/ns/' in bad_props:
calendar = True
if calendar:
ad = doc.createElement('calendar')
ad.setAttribute('xmlns', 'urn:ietf:params:xml:ns:caldav')
ad.setAttribute('xmlns', 'urn:ietf:params:xml:ns:caldav')
cols = res.getElementsByTagName('D:collection')
if cols:
cols[0].parentNode.appendChild(ad)
+378 -373
View File
@@ -1,385 +1,390 @@
<?xml version="1.0"?>
<openerp>
<data noupdate="1">
<data noupdate="1">
<record model="document.directory" id="document.dir_calendars">
<field name="name">Calendars</field>
<field name="calendar_collection">True</field>
</record>
<!-- Event attributes-->
<!-- Event attributes-->
<record model="basic.calendar.attributes" id="field_event_comment">
<field name="name">comment</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_comment">
<field name="name">comment</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_organizer">
<field name="name">organizer</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_uid">
<field name="name">uid</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_seq">
<field name="name">seq</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_recurrence-id">
<field name="name">recurrence-id</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_transp">
<field name="name">transp</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_attendee">
<field name="name">attendee</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_related">
<field name="name">related</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rrule">
<field name="name">rrule</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtend">
<field name="name">dtend</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_valarm">
<field name="name">valarm</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_vtimezone">
<field name="name">vtimezone</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_priority">
<field name="name">priority</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_location">
<field name="name">location</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_exrule">
<field name="name">exrule</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_resources">
<field name="name">resources</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rstatus">
<field name="name">rstatus</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_status">
<field name="name">status</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_exdate">
<field name="name">exdate</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtstamp">
<field name="name">dtstamp</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_description">
<field name="name">description</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rdate">
<field name="name">rdate</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtstart">
<field name="name">dtstart</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_class">
<field name="name">class</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_x-openobject-model">
<field name="name">x-openobject-model</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_created">
<field name="name">created</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_url">
<field name="name">url</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_summary">
<field name="name">summary</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_contact">
<field name="name">contact</field>
<field name="type">vevent</field>
</record>
<!-- Todo attributes-->
<record model="basic.calendar.attributes" id="field_todo_status">
<field name="name">status</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_comment">
<field name="name">comment</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_attendee">
<field name="name">attendee</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_valarm">
<field name="name">valarm</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_description">
<field name="name">description</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_seq">
<field name="name">seq</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_vtimezone">
<field name="name">vtimezone</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_url">
<field name="name">url</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_completed">
<field name="name">completed</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_percent">
<field name="name">percent</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_due">
<field name="name">due</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_summary">
<field name="name">summary</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_priority">
<field name="name">priority</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_exdate">
<field name="name">exdate</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_location">
<field name="name">location</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_exrule">
<field name="name">exrule</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_duration">
<field name="name">duration</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_organizer">
<field name="name">organizer</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_dtstart">
<field name="name">dtstart</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_rrule">
<field name="name">rrule</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_class">
<field name="name">class</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_uid">
<field name="name">uid</field>
<field name="type">vtodo</field>
</record>
<!-- Attendee's attributes-->
<record model="basic.calendar.attributes" id="field_attendee_cn">
<field name="name">cn</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_sent-by">
<field name="name">sent-by</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_language">
<field name="name">language</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_delegated-from">
<field name="name">delegated-from</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_member">
<field name="name">member</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_cutype">
<field name="name">cutype</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_role">
<field name="name">role</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_partstat">
<field name="name">partstat</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_delegated-to">
<field name="name">delegated-to</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_dir">
<field name="name">dir</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_rsvp">
<field name="name">rsvp</field>
<field name="type">attendee</field>
</record>
<!-- Alarm attributes-->
<record model="basic.calendar.attributes" id="field_alarm_attendee">
<field name="name">attendee</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_duration">
<field name="name">trigger_duration</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_description">
<field name="name">description</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_attach">
<field name="name">attach</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_occurs">
<field name="name">trigger_occurs</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_interval">
<field name="name">trigger_interval</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_summary">
<field name="name">summary</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_duration">
<field name="name">duration</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_repeat">
<field name="name">repeat</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_action">
<field name="name">action</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_related">
<field name="name">trigger_related</field>
<field name="type">alarm</field>
</record>
</data>
<field name="name">organizer</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_uid">
<field name="name">uid</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_seq">
<field name="name">seq</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_recurrence-id">
<field name="name">recurrence-id</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_transp">
<field name="name">transp</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_attendee">
<field name="name">attendee</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_related">
<field name="name">related</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rrule">
<field name="name">rrule</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtend">
<field name="name">dtend</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_duration">
<field name="name">duration</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_valarm">
<field name="name">valarm</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_vtimezone">
<field name="name">vtimezone</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_priority">
<field name="name">priority</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_location">
<field name="name">location</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_exrule">
<field name="name">exrule</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_resources">
<field name="name">resources</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rstatus">
<field name="name">rstatus</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_status">
<field name="name">status</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_exdate">
<field name="name">exdate</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtstamp">
<field name="name">dtstamp</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_description">
<field name="name">description</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_rdate">
<field name="name">rdate</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_dtstart">
<field name="name">dtstart</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_class">
<field name="name">class</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_x-openobject-model">
<field name="name">x-openobject-model</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_created">
<field name="name">created</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_url">
<field name="name">url</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_summary">
<field name="name">summary</field>
<field name="type">vevent</field>
</record>
<record model="basic.calendar.attributes" id="field_event_contact">
<field name="name">contact</field>
<field name="type">vevent</field>
</record>
<!-- Todo attributes-->
<record model="basic.calendar.attributes" id="field_todo_status">
<field name="name">status</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_comment">
<field name="name">comment</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_attendee">
<field name="name">attendee</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_valarm">
<field name="name">valarm</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_description">
<field name="name">description</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_seq">
<field name="name">sequence</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_vtimezone">
<field name="name">vtimezone</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_url">
<field name="name">url</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_completed">
<field name="name">completed</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_percent">
<field name="name">percent-complete</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_due">
<field name="name">due</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_summary">
<field name="name">summary</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_priority">
<field name="name">priority</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_exdate">
<field name="name">exdate</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_location">
<field name="name">location</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_exrule">
<field name="name">exrule</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_duration">
<field name="name">duration</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_organizer">
<field name="name">organizer</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_dtstart">
<field name="name">dtstart</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_rrule">
<field name="name">rrule</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_class">
<field name="name">class</field>
<field name="type">vtodo</field>
</record>
<record model="basic.calendar.attributes" id="field_todo_uid">
<field name="name">uid</field>
<field name="type">vtodo</field>
</record>
<!-- Attendee's attributes-->
<record model="basic.calendar.attributes" id="field_attendee_cn">
<field name="name">cn</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_sent-by">
<field name="name">sent-by</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_language">
<field name="name">language</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_delegated-from">
<field name="name">delegated-from</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_member">
<field name="name">member</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_cutype">
<field name="name">cutype</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_role">
<field name="name">role</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_partstat">
<field name="name">partstat</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_delegated-to">
<field name="name">delegated-to</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_dir">
<field name="name">dir</field>
<field name="type">attendee</field>
</record>
<record model="basic.calendar.attributes" id="field_attendee_rsvp">
<field name="name">rsvp</field>
<field name="type">attendee</field>
</record>
<!-- Alarm attributes-->
<record model="basic.calendar.attributes" id="field_alarm_attendee">
<field name="name">attendee</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_duration">
<field name="name">trigger_duration</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_description">
<field name="name">description</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_attach">
<field name="name">attach</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_occurs">
<field name="name">trigger_occurs</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_interval">
<field name="name">trigger_interval</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_summary">
<field name="name">summary</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_duration">
<field name="name">duration</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_repeat">
<field name="name">repeat</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_action">
<field name="name">action</field>
<field name="type">alarm</field>
</record>
<record model="basic.calendar.attributes" id="field_alarm_trigger_related">
<field name="name">trigger_related</field>
<field name="type">alarm</field>
</record>
</data>
</openerp>
+121 -233
View File
@@ -24,7 +24,6 @@ from tools.translate import _
import pooler
import tools
import time
import base64
from document import nodes
import StringIO
@@ -38,78 +37,48 @@ class node_database(nodes.node_database):
domain = []
domain2 = domain + [('calendar_collection','=', False)]
res = super(node_database, self)._child_get(cr, name=name, parent_id=parent_id, domain=domain2)
where = [('parent_id','=',parent_id)]
domain2 = domain + [('calendar_collection','=', True)]
where = [('parent_id','=',parent_id)]
domain2 = domain + [('calendar_collection','=', True)]
if name:
where.append(('name','=',name))
if domain2:
where += domain2
where2 = where + [('type', '=', 'directory')]
ids = dirobj.search(cr, uid, where2, context=ctx)
for dirr in dirobj.browse(cr,uid,ids,context=ctx):
ids = dirobj.search(cr, uid, where2, context=ctx)
for dirr in dirobj.browse(cr,uid,ids,context=ctx):
res.append(node_calendar_collection(dirr.name,self,self.context,dirr))
return res
class node_calendar_collection(nodes.node_dir):
PROPS = {
"http://calendarserver.org/ns/" : ('getctag'),
}
M_NS = {
class node_calendar_collection(nodes.node_dir):
DAV_PROPS = {
"http://calendarserver.org/ns/" : ('getctag',),
}
DAV_M_NS = {
"http://calendarserver.org/ns/" : '_get_dav',
}
}
def get_dav_props(self, cr):
return self.PROPS
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
http_options = { 'DAV': ['calendar-access'] }
def _file_get(self,cr, nodename=False):
return []
def _child_get(self, cr, name=False, parent_id=False, domain=None):
def _child_get(self, cr, name=False, parent_id=False, domain=None):
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
where = [('collection_id','=',self.dir_id)]
ext = False
if name:
res = name.split('.ics')
if len(res) > 1:
name = res[0]
ext = '.ics'
if name:
where = [('collection_id','=',self.dir_id)]
ext = False
if name and name.endswith('.ics'):
name = name[-4]
ext = '.ics'
if name:
where.append(('name','=',name))
if not domain:
domain = []
domain = []
where = where + domain
fil_obj = dirobj.pool.get('basic.calendar')
fil_obj = dirobj.pool.get('basic.calendar')
ids = fil_obj.search(cr,uid,where,context=ctx)
res = []
for calender in fil_obj.browse(cr, uid, ids, context=ctx):
@@ -120,34 +89,21 @@ class node_calendar_collection(nodes.node_dir):
return res
def _get_dav_owner(self, cr):
# Todo?
return False
def get_etag(self, cr):
""" Get a tag, unique per object + modification.
see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
return self._get_ttag(cr) + ':' + self._get_wtag(cr)
def _get_wtag(self, cr):
""" Return the modification time as a unique, compact string """
if self.write_date:
wtime = time.mktime(time.strptime(self.write_date, '%Y-%m-%d %H:%M:%S'))
else: wtime = time.time()
return str(wtime)
def _get_ttag(self, cr):
return 'calendar collection-%d' % self.dir_id
return 'calen-dir-%d' % self.dir_id
def _get_dav_getctag(self, cr):
result = self.get_etag(cr)
return str(result)
result = self.get_etag(cr)
return str(result)
class node_calendar(nodes.node_class):
our_type = 'collection'
PROPS = {
"http://calendarserver.org/ns/" : ('getctag'),
class node_calendar(nodes.node_class):
our_type = 'collection'
DAV_PROPS = {
"http://calendarserver.org/ns/" : ('getctag',),
'http://groupdav.org/': ('resourcetype',),
"urn:ietf:params:xml:ns:caldav" : (
'calendar-description',
'calendar-data',
@@ -155,10 +111,13 @@ class node_calendar(nodes.node_class):
'calendar-user-address-set',
'schedule-inbox-URL',
'schedule-outbox-URL',)}
M_NS = {
"DAV:" : '_get_dav',
DAV_M_NS = {
"DAV:" : '_get_dav',
'http://groupdav.org/': '_get_gdav',
"http://calendarserver.org/ns/" : '_get_dav',
"urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
"urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
http_options = { 'DAV': ['calendar-access'] }
def __init__(self,path, parent, context, calendar):
super(node_calendar,self).__init__(path, parent,context)
@@ -170,45 +129,49 @@ class node_calendar(nodes.node_class):
self.displayname = calendar.name
self.cal_type = calendar.type
def _get_dav_getctag(self, cr):
def _get_dav_getctag(self, cr):
result = self._get_ttag(cr) + ':' + str(time.time())
return str(result)
return str(result)
def match_dav_eprop(self, cr, match, ns, prop):
def _get_gdav_resourcetype(self, cr):
return (str(self.cal_type + '-collection'), 'http://groupdav.org/')
def removeme_match_dav_eprop(self, cr, match, ns, prop):
# Why?
if ns == "DAV:" and prop == "getetag":
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx = self.context.context.copy()
tem, dav_time = tuple(match.split(':'))
model, res_id = tuple(tem.split('_'))
model_obj = dirobj.pool.get(model)
model = model_obj.browse(cr, uid, res_id, context=ctx)
write_time = model.write_date or model.create_date
wtime = time.mktime(time.strptime(write_time,'%Y-%m-%d %H:%M:%S'))
wtime = time.mktime(time.strptime(write_time,'%Y-%m-%d %H:%M:%S'))
if float(dav_time) == float(wtime):
return True
return False
res = super(node_calendar, self).match_dav_eprop(cr, match, ns, prop)
return res
def get_domain(self, cr, filters):
return res
def get_domain(self, cr, filters):
# TODO: doc.
res = []
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = dirobj.pool.get('basic.calendar')
# dirobj = self.context._dirobj
#uid = self.context.uid
#ctx = self.context.context.copy()
#ctx.update(self.dctx)
# calendar_obj = dirobj.pool.get('basic.calendar')
if not filters:
return res
if filters.localName == 'calendar-query':
if filters.localName == 'calendar-query':
res = []
for filter_child in filters.childNodes:
if filter_child.nodeType == filter_child.TEXT_NODE:
continue
if filter_child.localName == 'filter':
continue
if filter_child.localName == 'filter':
for vcalendar_filter in filter_child.childNodes:
if vcalendar_filter.nodeType == vcalendar_filter.TEXT_NODE:
if vcalendar_filter.nodeType == vcalendar_filter.TEXT_NODE:
continue
if vcalendar_filter.localName == 'comp-filter':
if vcalendar_filter.getAttribute('name') == 'VCALENDAR':
@@ -216,10 +179,10 @@ class node_calendar(nodes.node_class):
if vevent_filter.nodeType == vevent_filter.TEXT_NODE:
continue
if vevent_filter.localName == 'comp-filter':
if vevent_filter.getAttribute('name') == 'VEVENT':
if vevent_filter.getAttribute('name') == 'VEVENT':
res = [('type','=','vevent')]
if vevent_filter.getAttribute('name') == 'VTODO':
res = [('type','=','vtodo')]
res = [('type','=','vtodo')]
return res
elif filters.localName == 'calendar-multiget':
names = []
@@ -229,105 +192,70 @@ class node_calendar(nodes.node_class):
if filter_child.localName == 'href':
if not filter_child.firstChild:
continue
uri = filter_child.firstChild.data
uri = filter_child.firstChild.data
caluri = uri.split('/')
if len(caluri):
caluri = caluri[-2]
if caluri not in names : names.append(caluri)
res = [('name','in',names)]
return res
return res
return res
def children(self, cr, domain=None):
def children(self, cr, domain=None):
return self._child_get(cr, domain=domain)
def child(self,cr, name, domain=None):
res = self._child_get(cr, name, domain=domain)
def child(self,cr, name, domain=None):
res = self._child_get(cr, name, domain=domain)
if res:
return res[0]
return None
return None
def _child_get(self, cr, name=False, parent_id=False, domain=None):
dirobj = self.context._dirobj
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
where = []
if name:
where.append(('id','=',int(name)))
ctx.update(self.dctx)
where = []
if name:
if name.endswith('.ics'):
name = name[:-4]
where.append(('id','=',int(name)))
if not domain:
domain = []
#for opr1, opt, opr2 in domain:
# if opr1 == 'type' and opr2 != self.cal_type:
# return []
fil_obj = dirobj.pool.get('basic.calendar')
fil_obj = dirobj.pool.get('basic.calendar')
ids = fil_obj.search(cr, uid, domain)
res = []
if self.calendar_id in ids:
res = fil_obj.get_calendar_objects(cr, uid, [self.calendar_id], self, domain=where, context=ctx)
return res
res = fil_obj.get_calendar_objects(cr, uid, [self.calendar_id], self, domain=where, context=ctx)
return res
def get_dav_props(self, cr):
return self.PROPS
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
propname = propname.replace('-','_')
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 create_child(self,cr,path,data):
def create_child(self, cr, path, data):
""" API function to create a child file object and node
Return the node_* created
"""
return self.set_data(cr, data)
# we ignore the path, it will be re-generated automatically
res = self.set_data(cr, data)
# TODO: use the res to create at least one node
return None
def set_data(self, cr, data, fil_obj = None):
uid = self.context.uid
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
return calendar_obj.import_cal(cr, uid, base64.encodestring(data), self.calendar_id)
res = calendar_obj.import_cal(cr, uid, data, self.calendar_id)
return res
def get_data_len(self, cr, fil_obj = None):
def get_data_len(self, cr, fil_obj = None):
return self.content_length
def _get_ttag(self,cr):
return 'calendar-%d' % (self.calendar_id,)
def get_etag(self, cr):
""" Get a tag, unique per object + modification.
see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
return self._get_ttag(cr) + ':' + self._get_wtag(cr)
def _get_wtag(self, cr):
""" Return the modification time as a unique, compact string """
if self.write_date:
wtime = time.mktime(time.strptime(self.write_date, '%Y-%m-%d %H:%M:%S'))
else: wtime = time.time()
return str(wtime)
return 'calendar-%d' % (self.calendar_id,)
def rmcol(self, cr):
return False
@@ -335,7 +263,7 @@ class node_calendar(nodes.node_class):
class res_node_calendar(nodes.node_class):
our_type = 'file'
PROPS = {
DAV_PROPS = {
"http://calendarserver.org/ns/" : ('getctag'),
"urn:ietf:params:xml:ns:caldav" : (
'calendar-description',
@@ -344,76 +272,54 @@ class res_node_calendar(nodes.node_class):
'calendar-user-address-set',
'schedule-inbox-URL',
'schedule-outbox-URL',)}
M_NS = {
DAV_M_NS = {
"http://calendarserver.org/ns/" : '_get_dav',
"urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
"urn:ietf:params:xml:ns:caldav" : '_get_caldav'}
http_options = { 'DAV': ['calendar-access'] }
def __init__(self,path, parent, context, res_obj, res_model=None, res_id=None):
super(res_node_calendar,self).__init__(path, parent, context)
super(res_node_calendar,self).__init__(path, parent, context)
self.mimetype = 'text/calendar'
self.create_date = parent.create_date
self.write_date = parent.write_date or parent.create_date
self.calendar_id = hasattr(parent, 'calendar_id') and parent.calendar_id or False
if res_obj:
if not self.calendar_id: self.calendar_id = res_obj.id
self.create_date = res_obj.create_date
self.write_date = res_obj.write_date or res_obj.create_date
pr = res_obj.perm_read()[0]
self.create_date = pr.get('create_date')
self.write_date = pr.get('write_date') or pr.get('create_date')
self.displayname = res_obj.name
self.content_length = 0
self.model = res_model
self.res_id = res_id
def open(self, cr, mode=False):
uid = self.context.uid
uid = self.context.uid
if self.type in ('collection','database'):
return False
s = StringIO.StringIO(self.get_data(cr))
return False
s = StringIO.StringIO(self.get_data(cr))
s.name = self
return s
return s
def get_dav_props(self, cr):
return self.PROPS
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
propname = propname.replace('-','_')
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 get_data(self, cr, fil_obj = None):
def get_data(self, cr, fil_obj = None):
uid = self.context.uid
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
context = self.context.context.copy()
context.update({'model': self.model, 'res_id':self.res_id})
res = calendar_obj.export_cal(cr, uid, [self.calendar_id], context=context)
context = self.context.context.copy()
context.update({'model': self.model, 'res_id':self.res_id})
res = calendar_obj.export_cal(cr, uid, [self.calendar_id], context=context)
return res
def get_data_len(self, cr, fil_obj = None):
def get_data_len(self, cr, fil_obj = None):
return self.content_length
def set_data(self, cr, data, fil_obj = None):
uid = self.context.uid
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
return calendar_obj.import_cal(cr, uid, base64.encodestring(data), self.calendar_id)
res = calendar_obj.import_cal(cr, uid, data, self.calendar_id)
return res
def _get_ttag(self,cr):
res = False
@@ -423,30 +329,28 @@ class res_node_calendar(nodes.node_class):
res = '%d' % (self.calendar_id)
return res
def _get_caldav_calendar_data(self, cr):
def _get_caldav_calendar_data(self, cr):
return self.get_data(cr)
def _get_caldav_calendar_description(self, cr):
uid = self.context.uid
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
ctx = self.context.context.copy()
ctx.update(self.dctx)
ctx.update(self.dctx)
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
return calendar.description
def _get_caldav_calendar_home_set(self, cr):
import xml.dom.minidom
import urllib
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
huri = doc.createTextNode(urllib.quote('/%s/%s' % (cr.dbname, calendar.collection_id.name)))
href = doc.documentElement
@@ -461,7 +365,7 @@ class res_node_calendar(nodes.node_class):
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)
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'
@@ -472,11 +376,11 @@ class res_node_calendar(nodes.node_class):
def _get_caldav_schedule_inbox_URL(self, cr):
import xml.dom.minidom
import urllib
import urllib
uid = self.context.uid
ctx = self.context.context.copy()
ctx.update(self.dctx)
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar_obj = self.context._dirobj.pool.get('basic.calendar')
calendar = calendar_obj.browse(cr, uid, self.calendar_id, context=ctx)
res = '%s/%s' %(calendar.name, calendar.collection_id.name)
doc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'href', None)
@@ -491,31 +395,15 @@ class res_node_calendar(nodes.node_class):
uid = self.context.uid
res = False
if self.type in ('collection','database'):
return False
if self.model and self.res_id:
return False
if self.model and self.res_id:
document_obj = self.context._dirobj.pool.get(self.model)
if document_obj:
res = False
#res = document_obj.unlink(cr, uid, [self.res_id]) #TOFIX
return res
res = document_obj.unlink(cr, uid, [self.res_id])
return res
def _get_caldav_schedule_outbox_URL(self, cr):
return self._get_caldav_schedule_inbox_URL(cr)
def get_etag(self, cr):
""" Get a tag, unique per object + modification.
see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
return self._get_ttag(cr) + ':' + self._get_wtag(cr)
def _get_wtag(self, cr):
""" Return the modification time as a unique, compact string """
if self.write_date:
wtime = time.mktime(time.strptime(self.write_date, '%Y-%m-%d %H:%M:%S'))
else: wtime = time.time()
return str(wtime)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4
+35 -35
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<data>
<record model="ir.ui.view" id="view_calendar_collection_form">
<field name="name">Calendar Collections : Form</field>
<field name="model">document.directory</field>
@@ -17,10 +17,10 @@
<record model="ir.ui.view" id="view_calendar_collection_tree">
<field name="name">Calendar Collections : Tree</field>
<field name="model">document.directory</field>
<field name="type">tree</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Calendar Collections" toolbar="1">
<field name="name"/>
<field name="name"/>
<field name="user_id"/>
<field name="create_date"/>
<field name="write_date"/>
@@ -73,34 +73,34 @@
<field name="name"/>
<field name="type"/>
<field name="user_id"/>
<field name="collection_id" required="1"/>
<field name="collection_id" required="1"/>
<field name="line_ids" mode="form,tree" colspan="4" nolabel="1">
<form string="Calendar Lines">
<field name="name" required="1" select="1" />
<field name="object_id" required="1" select="1" />
<field name="domain" select="1" />
<field name="mapping_ids" select="1" colspan="4" nolabel="1">
<tree string="Attributes Mapping" editable="bottom">
<field name="name" required="1" domain="[('type', '=', parent.name)]"/>
<field name="fn" select="1" />
<field name="field_id" select="1" required="1" domain="[('model_id', '=', parent.object_id)]" />
<field name="expr" />
</tree>
<form string="Attributes Mapping">
<field name="name" select="1" required="1" domain="[('type', '=', parent.name)]"/>
<field name="field_id" select="1" domain="[('model_id', '=', parent.object_id)]"
required="1" />
<field name="fn" select="1" required="1" />
<field name="expr" />
<separator string="Value Mapping" colspan="4" />
<field name="mapping" select="1" colspan="4" nolabel="1" />
</form>
</field>
</form>
<form string="Calendar Lines">
<field name="name" required="1" select="1" />
<field name="object_id" required="1" select="1" />
<field name="domain" select="1" />
<field name="mapping_ids" select="1" colspan="4" nolabel="1">
<tree string="Attributes Mapping" editable="bottom">
<field name="name" required="1" domain="[('type', '=', parent.name)]"/>
<field name="fn" select="1" />
<field name="field_id" select="1" required="1" domain="[('model_id', '=', parent.object_id)]" />
<field name="expr" />
</tree>
<form string="Attributes Mapping">
<field name="name" select="1" required="1" domain="[('type', '=', parent.name)]"/>
<field name="field_id" select="1" domain="[('model_id', '=', parent.object_id)]"
required="1" />
<field name="fn" select="1" required="1" />
<field name="expr" />
<separator string="Value Mapping" colspan="4" />
<field name="mapping" select="1" colspan="4" nolabel="1" />
</form>
</field>
</form>
<tree string="Calendar Lines" editable="bottom">
<field name="name" select="1" />
<field name="object_id" select="1" />
</tree>
<field name="name" select="1" />
<field name="object_id" select="1" />
</tree>
</field>
</form>
</field>
@@ -110,11 +110,11 @@
<record model="ir.ui.view" id="view_caldav_tree">
<field name="name">Calendar : Tree</field>
<field name="model">basic.calendar</field>
<field name="type">tree</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Calendars" toolbar="1">
<field name="name"/>
<field name="type"/>
<field name="name"/>
<field name="type"/>
<field name="user_id"/>
<field name="create_date"/>
<field name="write_date"/>
@@ -127,8 +127,8 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">basic.calendar</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<field name="view_mode">tree,form</field>
</record>
<record id="action_caldav_view1" model="ir.actions.act_window.view">
<field eval="10" name="sequence"/>
@@ -147,5 +147,5 @@
action="action_caldav_form"
id="menu_caldav_directories"
parent="menu_calendar"/>
</data>
</data>
</openerp>
+25 -29
View File
@@ -24,7 +24,6 @@ from dateutil import parser
from dateutil.rrule import *
from osv import osv, fields
from tools.translate import _
import base64
import math
import pooler
import pytz
@@ -52,6 +51,8 @@ def uid2openobjectid(cr, uidval, oomodel, rdate):
@param rdate: Get Recurrent Date
"""
__rege = re.compile(r'OpenObject-([\w|\.]+)_([0-9]+)@(\w+)$')
if not uidval:
return (False, None)
wematch = __rege.match(uidval.encode('utf8'))
if not wematch:
return (False, None)
@@ -133,7 +134,7 @@ def map_data(cr, uid, obj, context=None):
continue
mapping = obj.__attribute__[map_dict].get('mapping', False)
if mapping:
map_val = mapping[map_val.lower()]
map_val = mapping.get(map_val.lower(), False)
else:
map_val = map_val.lower()
if field_type == 'many2many':
@@ -381,7 +382,7 @@ class CalDAV(object):
raise osv.except_osv(('Error !'), (str(e)))
return ids
def export_cal(self, cr, uid, datas, vobj=None, context={}):
def export_cal(self, cr, uid, datas, vobj=None, context=None):
""" Export Calendar
@param self: The object pointer
@param cr: the current row, from the database cursor,
@@ -396,7 +397,7 @@ class CalDAV(object):
self.create_ics(cr, uid, datas, vobj, ical, context=context)
return ical
except Exception, e:
raise osv.except_osv(('Error !'), (str(e)))
raise # osv.except_osv(('Error !'), (str(e)))
def import_cal(self, cr, uid, content, data_id=None, context=None):
""" Import Calendar
@@ -407,7 +408,7 @@ class CalDAV(object):
@param context: A standard dictionary for contextual values
"""
ical_data = base64.decodestring(content)
ical_data = content
self.__attribute__ = get_attribute_mapping(cr, uid, self._calname, context)
parsedCal = vobject.readOne(ical_data)
res = []
@@ -447,8 +448,8 @@ class Calendar(CalDAV, osv.osv):
'type': fields.selection([('vevent', 'Event'), ('vtodo', 'TODO')], \
string="Type", size=64),
'line_ids': fields.one2many('basic.calendar.lines', 'calendar_id', 'Calendar Lines'),
'create_date': fields.datetime('Created Date'),
'write_date': fields.datetime('Modifided Date'),
'create_date': fields.datetime('Created Date', readonly=True),
'write_date': fields.datetime('Modifided Date', readonly=True),
}
def get_calendar_objects(self, cr, uid, ids, parent=None, domain=None, context=None):
@@ -473,17 +474,16 @@ class Calendar(CalDAV, osv.osv):
data_ids = mod_obj.search(cr, uid, line_domain, context=context)
for data in mod_obj.browse(cr, uid, data_ids, context):
ctx = parent and parent.context or None
node = res_node_calendar('%s' %data.id, parent, ctx, data, line.object_id.model, data.id)
node = res_node_calendar('%s.ics' %data.id, parent, ctx, data, line.object_id.model, data.id)
res.append(node)
return res
def export_cal(self, cr, uid, ids, vobj='vevent', context=None):
""" Export Calendar
@param self: The object pointer
@param cr: the current row, from the database cursor,
@param uid: the current user’s ID for security checks,
@param ids: List of calendar’s IDs
@param context: A standard dictionary for contextual values
@param vobj: the type of object to export
@return the ical data.
"""
if not context:
context = {}
@@ -521,7 +521,7 @@ class Calendar(CalDAV, osv.osv):
if not context:
context = {}
vals = []
ical_data = base64.decodestring(content)
ical_data = content
parsedCal = vobject.readOne(ical_data)
if not data_id:
data_id = self.search(cr, uid, [])[0]
@@ -541,14 +541,19 @@ class Calendar(CalDAV, osv.osv):
val = self.parse_ics(cr, uid, child, cal_children=cal_children, context=context)
vals.append(val)
objs.append(cal_children[child.name.lower()])
res = []
for obj_name in list(set(objs)):
obj = self.pool.get(obj_name)
if hasattr(obj, 'check_import'):
obj.check_import(cr, uid, vals, context=context)
r = obj.check_import(cr, uid, vals, context=context)
checked = True
res.extend(r)
if not checked:
self.check_import(cr, uid, vals, context=context)
return {}
r = self.check_import(cr, uid, vals, context=context)
res.extend(r)
return res
Calendar()
@@ -632,6 +637,10 @@ class basic_calendar_fields(osv.osv):
'fn': lambda *a: 'field',
}
_sql_constraints = [
( 'name_type_uniq', 'UNIQUE(name, type_id)', 'Can not map a field more than once'),
]
def check_line(self, cr, uid, vals, name, context=None):
""" check calendar's line
@param self: The object pointer
@@ -667,12 +676,6 @@ class basic_calendar_fields(osv.osv):
name = name[0]
if name in ('valarm', 'attendee'):
self.check_line(cr, uid, vals, name, context=context)
cr.execute("Select count(id) from basic_calendar_fields \
where name=%s and type_id=%s" % (vals.get('name'), vals.get('type_id')))
res = cr.fetchone()
if res:
if res[0] > 0:
raise osv.except_osv(_('Warning !'), _('Can not map the field more than once'))
return super(basic_calendar_fields, self).create(cr, uid, vals, context=context)
def write(self, cr, uid, ids, vals, context=None):
@@ -691,13 +694,6 @@ class basic_calendar_fields(osv.osv):
name = field.name.name
if name in ('valarm', 'attendee'):
self.check_line(cr, uid, vals, name, context=context)
qry = "Select count(id) from basic_calendar_fields \
where name=%s and type_id=%s" % (field.name.id, field.type_id.id)
cr.execute(qry)
res = cr.fetchone()
if res:
if res[0] > 1:
raise osv.except_osv(_('Warning !'), _('Can not map same field more than once'))
return super(basic_calendar_fields, self).write(cr, uid, ids, vals, context)
basic_calendar_fields()
@@ -1,25 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_calendar_event_export" model="ir.ui.view">
<record id="view_calendar_event_export" model="ir.ui.view">
<field name="name">calendar.event.export.form</field>
<field name="model">calendar.event.export</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Export ICS">
<group colspan="4" >
<field name="name"/>
<field name="file_path" colspan="4" width="300"/>
<group colspan="4" >
<field name="name"/>
<field name="file_path" colspan="4" width="300"/>
</group>
<separator string="" colspan="4" />
<separator string="" colspan="4" />
<group colspan="4" col="6">
<label string=""/>
<button icon="gtk-close" special="cancel" string="_Close"/>
<label string=""/>
<button icon="gtk-close" special="cancel" string="_Close"/>
</group>
</form>
</field>
</record>
</record>
<record id="action_calendar_event_export" model="ir.actions.act_window">
<field name="name">Export .ics File</field>
<field name="res_model">calendar.event.export</field>
@@ -30,10 +30,10 @@
</record>
<act_window id="action_calendar_event_export_values"
key2="client_action_multi" name="Export .ics File"
res_model="calendar.event.export" src_model="basic.calendar"
view_mode="form" target="new" view_type="form" />
<act_window id="action_calendar_event_export_values"
key2="client_action_multi" name="Export .ics File"
res_model="calendar.event.export" src_model="basic.calendar"
view_mode="form" target="new" view_type="form" />
</data>
</openerp>
@@ -1,42 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_calendar_event_import" model="ir.ui.view">
<record id="view_calendar_event_import" model="ir.ui.view">
<field name="name">calendar.event.import.form</field>
<field name="model">calendar.event.import</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import ICS">
<group colspan="4" >
<separator string="Select ICS file"/>
<field name="file_path" colspan="4" width="300" nolabel="1"/>
<group colspan="4" >
<separator string="Select ICS file"/>
<field name="file_path" colspan="4" width="300" nolabel="1"/>
</group>
<separator string="" colspan="4" />
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="process_imp_ics" string="_Import" type="object"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="process_imp_ics" string="_Import" type="object"/>
</group>
</form>
</field>
</record>
<record id="view_calendar_event_import_display" model="ir.ui.view">
</record>
<record id="view_calendar_event_import_display" model="ir.ui.view">
<field name="name">calendar.event.import.form.display</field>
<field name="model">calendar.event.import</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Import Message">
<group colspan="4" >
<field name="msg" colspan="4" width="300" nolabel="1"/>
<group colspan="4" >
<field name="msg" colspan="4" width="300" nolabel="1"/>
</group>
<separator string="" colspan="4" />
<separator string="" colspan="4" />
<group colspan="4">
<button icon="gtk-ok" special="cancel" string="Ok"/>
<button icon="gtk-ok" special="cancel" string="Ok"/>
</group>
</form>
</field>
</record>
</record>
<record id="action_calendar_event_import" model="ir.actions.act_window">
<field name="name">Import .ics File</field>
<field name="res_model">calendar.event.import</field>
@@ -47,9 +47,9 @@
</record>
<act_window id="action_calendar_event_import_values"
key2="client_action_multi" name="Import .ics File"
res_model="calendar.event.import" src_model="basic.calendar"
view_mode="form" target="new" view_type="form" />
key2="client_action_multi" name="Import .ics File"
res_model="calendar.event.import" src_model="basic.calendar"
view_mode="form" target="new" view_type="form" />
</data>
</openerp>
@@ -1,42 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_calendar_event_subscribe" model="ir.ui.view">
<record id="view_calendar_event_subscribe" model="ir.ui.view">
<field name="name">calendar.event.subscribe.form</field>
<field name="model">calendar.event.subscribe</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Subscribe to Remote Calendar">
<group colspan="4" >
<separator string="Provide path for Remote Calendar"/>
<field name="url_path" colspan="4" width="300" nolabel="1" widget="url"/>
<group colspan="4" >
<separator string="Provide path for Remote Calendar"/>
<field name="url_path" colspan="4" width="300" nolabel="1" widget="url"/>
</group>
<separator string="" colspan="4" />
<separator string="" colspan="4" />
<group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="process_imp_ics" string="_Subscribe" type="object"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
<button icon="gtk-ok" name="process_imp_ics" string="_Subscribe" type="object"/>
</group>
</form>
</field>
</record>
<record id="view_calendar_event_subscribe_display" model="ir.ui.view">
</record>
<record id="view_calendar_event_subscribe_display" model="ir.ui.view">
<field name="name">calendar.event.subscribe.form.display</field>
<field name="model">calendar.event.subscribe</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Message...">
<group colspan="4" >
<field name="msg" colspan="4" width="300" nolabel="1"/>
<group colspan="4" >
<field name="msg" colspan="4" width="300" nolabel="1"/>
</group>
<separator string="" colspan="4" />
<separator string="" colspan="4" />
<group colspan="4">
<button icon="gtk-ok" special="cancel" string="Ok"/>
<button icon="gtk-ok" special="cancel" string="Ok"/>
</group>
</form>
</field>
</record>
</record>
<record id="action_calendar_event_subscribe" model="ir.actions.act_window">
<field name="name">Subscribe</field>
<field name="res_model">calendar.event.subscribe</field>
@@ -47,9 +47,9 @@
</record>
<act_window id="action_calendar_event_subscribe_values"
key2="client_action_multi" name="Subscribe"
res_model="calendar.event.subscribe" src_model="basic.calendar"
view_mode="form" target="new" view_type="form" />
key2="client_action_multi" name="Subscribe"
res_model="calendar.event.subscribe" src_model="basic.calendar"
view_mode="form" target="new" view_type="form" />
</data>
</openerp>
+41 -20
View File
@@ -44,6 +44,20 @@ from StringIO import StringIO
# root: if we are at the first directory of a ressource
#
def _str2time(cre):
""" Convert a string with time representation (from db) into time (float)
Note: a place to fix if datetime is used in db.
"""
if not cre:
return time.time()
frac = 0.0
if isinstance(cre, basestring) and '.' in cre:
fdot = cre.find('.')
frac = float(cre[fdot:])
cre = cre[:fdot]
return time.mktime(time.strptime(cre,'%Y-%m-%d %H:%M:%S')) + frac
def get_node_context(cr, uid, context):
return node_context(cr, uid, context)
@@ -157,6 +171,8 @@ class node_class(object):
Nodes have attributes which contain usual file properties
"""
our_type = 'baseclass'
DAV_PROPS = None
DAV_M_NS = None
def __init__(self, path, parent, context):
assert isinstance(context,node_context)
@@ -253,24 +269,21 @@ class node_class(object):
see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
return self._get_ttag(cr) + ':' + self._get_wtag(cr)
def _get_wtag(self,cr):
def _get_wtag(self, cr):
""" Return the modification time as a unique, compact string """
if self.write_date:
wtime = time.mktime(time.strptime(self.write_date,'%Y-%m-%d %H:%M:%S'))
else: wtime = time.time()
return str(wtime)
return str(_str2time(self.write_date))
def _get_ttag(self,cr):
""" Get a unique tag for this type/id of object.
Must be overriden, so that each node is uniquely identified.
"""
print "node_class.get_ttag()",self
raise RuntimeError("get_etag stub()")
raise NotImplementedError("get_etag stub()")
def get_dav_props(self, cr):
""" If this class has special behaviour for GroupDAV etc, export
its capabilities """
return {}
return self.DAV_PROPS or {}
def match_dav_eprop(self, cr, match, ns, prop):
res = self.get_dav_eprop(cr, ns, prop)
@@ -279,6 +292,26 @@ class node_class(object):
return False
def get_dav_eprop(self, cr, ns, prop):
if not self.DAV_M_NS:
return None
if self.DAV_M_NS.has_key(ns):
prefix = self.DAV_M_NS[ns]
else:
logger.debug('No namespace: %s ("%s")',ns, prop)
return None
mname = prefix + "_" + prop.replace('-','_')
if not hasattr(self, mname):
return None
try:
m = getattr(self, mname)
r = m(cr)
return r
except AttributeError:
logger.debug('Property %s not supported' % prop, exc_info=True)
return None
def move_to(self, cr, ndir_node, new_name=False, fil_obj=None, ndir_obj=None, in_write=False):
@@ -327,6 +360,7 @@ class node_class(object):
raise NotImplementedError(repr(self))
def get_domain(self, cr, filters):
# TODO Document
return []
def check_perms(self, perms):
@@ -573,19 +607,6 @@ class node_dir(node_database):
fnode.set_data(cr, data, fil)
return fnode
def get_etag(self, cr):
""" Get a tag, unique per object + modification.
see. http://tools.ietf.org/html/rfc2616#section-13.3.3 """
return self._get_ttag(cr) + ':' + self._get_wtag(cr)
def _get_wtag(self, cr):
""" Return the modification time as a unique, compact string """
if self.write_date:
wtime = time.mktime(time.strptime(self.write_date, '%Y-%m-%d %H:%M:%S'))
else: wtime = time.time()
return str(wtime)
def _get_ttag(self,cr):
return 'dir-%d' % self.dir_id
+94 -34
View File
@@ -46,6 +46,10 @@ CACHE_SIZE=20000
urlparse.uses_netloc.append('webdav')
urlparse.uses_netloc.append('webdavs')
day_names = { 0: 'Mon', 1: 'Tue' , 2: 'Wed', 3: 'Thu', 4: 'Fri', 5: 'Sat', 6: 'Sun' }
month_names = { 1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun',
7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec' }
class DAV_NotFound2(DAV_NotFound):
"""404 exception, that accepts our list uris
"""
@@ -55,6 +59,19 @@ class DAV_NotFound2(DAV_NotFound):
args = (path, )
DAV_NotFound.__init__(self, *args)
def _str2time(cre):
""" Convert a string with time representation (from db) into time (float)
"""
if not cre:
return time.time()
frac = 0.0
if isinstance(cre, basestring) and '.' in cre:
fdot = cre.find('.')
frac = float(cre[fdot:])
cre = cre[:fdot]
return time.mktime(time.strptime(cre,'%Y-%m-%d %H:%M:%S')) + frac
class openerp_dav_handler(dav_interface):
"""
This class models a OpenERP interface for the DAV server
@@ -79,20 +96,21 @@ class openerp_dav_handler(dav_interface):
return props
node = self.uri2object(cr, uid, pool, uri2)
if node:
props = props.copy()
props.update(node.get_dav_props(cr))
cr.close()
return props
def _try_function(self, funct, args, opname='run function', cr=None,
default_exc=DAV_Forbidden):
def _try_function(self, funct, args, opname='run function', cr=None,
default_exc=DAV_Forbidden):
""" Try to run a function, and properly convert exceptions to DAV ones.
@objname the name of the operation being performed
@param cr if given, the cursor to close at exceptions
"""
try:
funct(*args)
return funct(*args)
except DAV_Error:
if cr: cr.close()
raise
@@ -111,7 +129,7 @@ class openerp_dav_handler(dav_interface):
raise default_exc(err.strerror)
except Exception,e:
import traceback
self.parent.log_error("Cannot create %s: %s", opname, str(e))
self.parent.log_error("Cannot %s: %s", opname, str(e))
self.parent.log_message("Exc: %s",traceback.format_exc())
raise default_exc("Operation failed")
@@ -122,6 +140,8 @@ class openerp_dav_handler(dav_interface):
raise DAV_NotFound
def match_prop(self, uri, match, ns, propname):
if self.M_NS.has_key(ns):
return match == dav_interface.get_prop(self, uri, ns, propname)
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
if cr: cr.close()
@@ -134,6 +154,37 @@ class openerp_dav_handler(dav_interface):
cr.close()
return res
def prep_http_options(self, uri, opts):
"""see HttpOptions._prep_OPTIONS """
self.parent.log_message('get options: %s' % uri)
cr, uid, pool, dbname, uri2 = self.get_cr(uri, allow_last=True)
if not dbname:
if cr: cr.close()
return opts
node = self.uri2object(cr, uid, pool, uri2[:])
if not node:
if cr: cr.close()
return opts
else:
if hasattr(node, 'http_options'):
ret = opts.copy()
for key, val in node.http_options.items():
if isinstance(val, basestring):
val = [val, ]
if key in ret:
ret[key] = ret[key][:] # copy the orig. array
else:
ret[key] = []
ret[key].extend(val)
self.parent.log_message('options: %s' % ret)
else:
ret = opts
cr.close()
return ret
def get_prop(self, uri, ns, propname):
""" return the value of a given property
@@ -159,18 +210,18 @@ class openerp_dav_handler(dav_interface):
"""Parse the uri and get the dbname and the rest.
Db name should be the first component in the unix-like
path supplied in uri.
@param rest_ret Instead of the db_name, return (db_name, rest),
where rest is the remaining path
@param allow_last If the dbname is the last component in the
path, allow it to be resolved. The default False value means
we will not attempt to use the db, unless there is more
path.
@return db_name or (dbname, rest) depending on rest_ret,
will return dbname=False when component is not found.
"""
uri2 = self.uri2local(uri)
if uri2.startswith('/'):
uri2 = uri2[1:]
@@ -294,7 +345,7 @@ class openerp_dav_handler(dav_interface):
try:
if not dbname:
raise DAV_Error, 409
node = self.uri2object(cr, uid, pool, uri2)
node = self.uri2object(cr, uid, pool, uri2)
if not node:
raise DAV_NotFound2(uri2)
try:
@@ -339,11 +390,11 @@ class openerp_dav_handler(dav_interface):
self.parent.log_message('get DN: %s' % uri)
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
cr.close()
if cr: cr.close()
return COLLECTION
node = self.uri2object(cr, uid, pool, uri2)
if not node:
cr.close()
if cr: cr.close()
raise DAV_NotFound2(uri2)
cr.close()
return node.displayname
@@ -359,7 +410,7 @@ class openerp_dav_handler(dav_interface):
return str(result)
node = self.uri2object(cr, uid, pool, uri2)
if not node:
cr.close()
if cr: cr.close()
raise DAV_NotFound2(uri2)
result = node.content_length or 0
cr.close()
@@ -372,34 +423,41 @@ class openerp_dav_handler(dav_interface):
result = 0
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
cr.close()
if cr: cr.close()
return '0'
node = self.uri2object(cr, uid, pool, uri2)
if not node:
cr.close()
raise DAV_NotFound2(uri2)
result = node.get_etag(cr)
result = self._try_function(node.get_etag ,(cr,), "etag %s" %uri, cr=cr)
cr.close()
return str(result)
@memoize(CACHE_SIZE)
def get_lastmodified(self, uri):
""" return the last modified date of the object """
today = time.time()
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
return today
return time.time()
try:
node = self.uri2object(cr, uid, pool, uri2)
if not node:
raise DAV_NotFound2(uri2)
if node.write_date:
return time.mktime(time.strptime(node.write_date,'%Y-%m-%d %H:%M:%S'))
else:
return today
return _str2time(node.write_date)
finally:
if cr: cr.close()
def _get_dav_getlastmodified(self,uri):
""" return the last modified date of a resource
"""
d=self.get_lastmodified(uri)
# format it. Note that we explicitly set the day, month names from
# an array, so that strftime() doesn't use its own locale-aware
# strings.
gmt = time.gmtime(d)
return time.strftime("%%s, %d %%s %Y %H:%M:%S GMT", gmt ) % \
(day_names[gmt.tm_wday], month_names[gmt.tm_mon])
@memoize(CACHE_SIZE)
def get_creationdate(self, uri):
""" return the last modified date of the object """
@@ -410,11 +468,8 @@ class openerp_dav_handler(dav_interface):
node = self.uri2object(cr, uid, pool, uri2)
if not node:
raise DAV_NotFound2(uri2)
if node.create_date:
result = time.mktime(time.strptime(node.create_date,'%Y-%m-%d %H:%M:%S'))
else:
result = time.time()
return result
return _str2time(node.create_date)
finally:
if cr: cr.close()
@@ -423,6 +478,7 @@ class openerp_dav_handler(dav_interface):
self.parent.log_message('get contenttype: %s' % uri)
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
if cr: cr.close()
return 'httpd/unix-directory'
try:
node = self.uri2object(cr, uid, pool, uri2)
@@ -441,10 +497,10 @@ class openerp_dav_handler(dav_interface):
self.parent.log_message('MKCOL: %s' % uri)
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not uri2[-1]:
cr.close()
if cr: cr.close()
raise DAV_Error(409, "Cannot create nameless collection")
if not dbname:
cr.close()
if cr: cr.close()
raise DAV_Error, 409
node = self.uri2object(cr,uid,pool, uri2[:-1])
if not node:
@@ -466,10 +522,11 @@ class openerp_dav_handler(dav_interface):
parent='/'.join(uri.split('/')[:-1])
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
if not dbname:
if cr: cr.close()
raise DAV_Forbidden
try:
node = self.uri2object(cr, uid, pool, uri2[:])
except:
except Exception:
node = False
objname = uri2[-1]
@@ -481,7 +538,7 @@ class openerp_dav_handler(dav_interface):
cr.close()
raise DAV_NotFound('Parent folder not found')
self._try_function(dir_node.create_child, (cr, objname, data),
self._try_function(dir_node.create_child, (cr, objname, data),
"create %s" % objname, cr=cr)
else:
self._try_function(node.set_data, (cr, data), "save %s" % objname, cr=cr)
@@ -494,9 +551,11 @@ class openerp_dav_handler(dav_interface):
""" delete a collection """
cr, uid, pool, dbname, uri2 = self.get_cr(uri)
if not dbname:
if cr: cr.close()
raise DAV_Error, 409
node = self.uri2object(cr, uid, pool, uri2)
node.rmcol(cr)
self._try_function(node.rmcol, (cr,), "rmcol %s" % uri, cr=cr)
cr.commit()
cr.close()
@@ -505,11 +564,12 @@ class openerp_dav_handler(dav_interface):
def rm(self,uri):
cr, uid, pool,dbname, uri2 = self.get_cr(uri)
if not dbname:
cr.close()
if cr: cr.close()
raise DAV_Error, 409
node = self.uri2object(cr, uid, pool, uri2)
res = node.rm(cr)
res = self._try_function(node.rm, (cr,), "rm %s" % uri, cr=cr)
if not res:
if cr: cr.close()
raise OSError(1, 'Operation not permited.')
cr.commit()
cr.close()
@@ -671,7 +731,7 @@ class openerp_dav_handler(dav_interface):
node = self.uri2object(cr, uid, pool, uri2)
if node:
result = True
except:
except Exception:
pass
cr.close()
return result
+41 -25
View File
@@ -30,21 +30,24 @@ import tools
super_mk_prop_response = PROPFIND.mk_prop_response
def mk_prop_response(self, uri, good_props, bad_props, doc):
""" make a new <prop> result element
def mk_prop_response(self, uri, good_props, bad_props, doc):
""" make a new <prop> result element
We differ between the good props and the bad ones for
each generating an extra <propstat>-Node (for each error
one, that means).
"""
"""
re=doc.createElement("D:response")
# append namespaces to response
nsnum=0
for nsname in self.namespaces:
namespaces = self.namespaces
if 'DAV:' in namespaces:
namespaces.remove('DAV:')
for nsname in namespaces:
re.setAttribute("xmlns:ns"+str(nsnum),nsname)
nsnum=nsnum+1
# write href information
uparts=urlparse.urlparse(uri)
fileloc=uparts[2]
@@ -64,24 +67,30 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
gp=doc.createElement("D:prop")
for ns in good_props.keys():
ns_prefix="ns"+str(self.namespaces.index(ns))+":"
for p,v in good_props[ns].items():
if ns == 'DAV:':
ns_prefix = 'D:'
else:
ns_prefix="ns"+str(namespaces.index(ns))+":"
for p,v in good_props[ns].items():
if not v:
pass
continue
pe=doc.createElement(ns_prefix+str(p))
if hasattr(v, '__class__') and v.__class__.__name__ == 'Element':
pe.appendChild(v)
else:
if p=="resourcetype":
if v==1:
if ns == 'DAV:' and p=="resourcetype":
if v == 1:
ve=doc.createElement("D:collection")
pe.appendChild(ve)
elif isinstance(v,tuple) and v[1] == ns:
ve=doc.createElement(ns_prefix+v[0])
pe.appendChild(ve)
else:
ve=doc.createTextNode(tools.ustr(v))
pe.appendChild(ve)
gp.appendChild(pe)
ps.appendChild(gp)
s=doc.createElement("D:status")
t=doc.createTextNode("HTTP/1.1 200 OK")
@@ -100,12 +109,15 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
ps.appendChild(bp)
for ns in bad_props[ecode].keys():
ns_prefix="ns"+str(self.namespaces.index(ns))+":"
if ns == 'DAV:':
ns_prefix='D:'
else:
ns_prefix="ns"+str(self.namespaces.index(ns))+":"
for p in bad_props[ecode][ns]:
pe=doc.createElement(ns_prefix+str(p))
bp.appendChild(pe)
s=doc.createElement("D:status")
t=doc.createTextNode(utils.gen_estring(ecode))
s.appendChild(t)
@@ -114,10 +126,10 @@ def mk_prop_response(self, uri, good_props, bad_props, doc):
# return the new response element
return re
def mk_propname_response(self,uri,propnames,doc):
""" make a new <prop> result element for a PROPNAME request
""" make a new <prop> result element for a PROPNAME request
This will simply format the propnames list.
propnames should have the format {NS1 : [prop1, prop2, ...], NS2: ...}
@@ -143,16 +155,20 @@ def mk_propname_response(self,uri,propnames,doc):
for ns,plist in propnames.items():
# write prop element
pr=doc.createElement("D:prop")
nsp="ns"+str(nsnum)
pr.setAttribute("xmlns:"+nsp,ns)
nsnum=nsnum+1
if ns == 'DAV':
nsp = 'D'
else:
nsp="ns"+str(nsnum)
ps.setAttribute("xmlns:"+nsp,ns)
nsnum=nsnum+1
# write propertynames
for p in plist:
pe=doc.createElement(nsp+":"+p)
pr.appendChild(pe)
# write propertynames
for p in plist:
pe=doc.createElement(nsp+":"+p)
pr.appendChild(pe)
ps.appendChild(pr)
ps.appendChild(pr)
re.appendChild(ps)
return re
+24 -3
View File
@@ -32,12 +32,13 @@ import tools
from dav_fs import openerp_dav_handler
from tools.config import config
from DAV.WebDAVServer import DAVRequestHandler
from service.websrv_lib import HTTPDir,FixSendError
from service.websrv_lib import HTTPDir, FixSendError, HttpOptions
from BaseHTTPServer import BaseHTTPRequestHandler
import urlparse
import urllib
from string import atoi,split
from DAV.errors import *
# from DAV.constants import DAV_VERSION_1, DAV_VERSION_2
def OpenDAVConfig(**kw):
class OpenDAV:
@@ -53,10 +54,15 @@ def OpenDAVConfig(**kw):
return Config()
class DAVHandler(FixSendError,DAVRequestHandler):
class DAVHandler(HttpOptions, FixSendError, DAVRequestHandler):
verbose = False
protocol_version = 'HTTP/1.1'
_HTTP_OPTIONS= { 'DAV' : ['1',],
'Allow' : [ 'GET', 'HEAD', 'COPY', 'MOVE', 'POST', 'PUT',
'PROPFIND', 'PROPPATCH', 'OPTIONS', 'MKCOL',
'DELETE', 'TRACE', 'REPORT', ]
}
def get_userinfo(self,user,pw):
return False
def _log(self, message):
@@ -99,6 +105,21 @@ class DAVHandler(FixSendError,DAVRequestHandler):
def log_error(self, format, *args):
netsvc.Logger().notifyChannel('xmlrpc', netsvc.LOG_WARNING, format % args)
def _prep_OPTIONS(self, opts):
ret = opts
dc=self.IFACE_CLASS
uri=urlparse.urljoin(self.get_baseuri(dc), self.path)
uri=urllib.unquote(uri)
try:
#location = dc.put(uri,body,ct)
ret = dc.prep_http_options(uri, opts)
except DAV_Error, (ec,dd):
pass
except Exception,e:
self.log_error("Error at options: %s", str(e))
raise
return ret
def send_response(self, code, message=None):
# the BufferingHttpServer will send Connection: close , while
# the BaseHTTPRequestHandler will only accept int code.
@@ -51,12 +51,17 @@
<field name="fn">field</field>
</record>
<!-- Sequence is not impemented right.
See http://tools.ietf.org/html/rfc5545#section-3.8.7.4
Disabling..
<record model="basic.calendar.fields" id="map_todo_6">
<field name="name" ref="caldav.field_todo_seq"/>
<field name="type_id" ref="caldav.calendar_lines_todo" />
<field name="field_id" search="[('name','=','sequence'),('model_id.model','=','calendar.todo')]" />
<field name="fn">field</field>
</record>
-->
<record model="basic.calendar.fields" id="map_todo_7">
<field name="name" ref="caldav.field_todo_url"/>