@@ -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 = {}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user