[ADD][WIP]Radicale Odoo Storage : add calendar unique events display

This commit is contained in:
Fabien BOURGEOIS 2018-05-10 17:31:04 +02:00
parent b61be41911
commit 3350d83d94

View File

@ -18,16 +18,18 @@
""" Odoo Radicale Storage Plugin """
# # PLAN
# 1. Implement readonly from Odoo only
# 2. Implement contacts first (and so vcf)
# 3. Implement unique events (.ics)
# 4. Implement recurrent events
# 5. Begin write (two way) for contacts
# 5. Begin write (two way) for calendar
# 1. OK : Implement readonly from Odoo only
# 2. OK : Implement contacts first (and so vcf)
# 3. OK : Implement unique events (.ics) and timezone
# 4. Implement notifications for events
# 5. Implement recurrent events
# 6. Begin write (two way) for contacts
# 7. Begin write (two way) for calendar
from contextlib import contextmanager
from time import strftime, strptime
import pytz
import vobject
from odoorpc import ODOO
from odoorpc.error import RPCError
@ -47,8 +49,10 @@ class Collection(BaseCollection):
if not self.__class__.odoo:
self.logger.error('No auth Odoo found...')
raise RuntimeError('No auth Odoo found')
self.__class__.odoo_connect()
# self.__class__.odoo_connect()
# self.odoo_init()
odoo_timezone = self.configuration.get('storage', 'odoo_timezone')
self.__class__.server_timezone = pytz.timezone(odoo_timezone)
attributes = path.strip('/').split('/')
self.tag = None
@ -118,6 +122,11 @@ class Collection(BaseCollection):
self.create_collection(calendar_path, props=props)
self.logger.info('Collection creation for Odoo Sync : %s' % calendar_path)
@classmethod
def odoo_date_to_utc(cls, date_obj):
""" Transform naive Odoo date object to UTC TZ """
local_date = cls.server_timezone.localize(date_obj, is_dst=None)
return local_date.astimezone(pytz.utc)
@classmethod
@contextmanager
@ -176,6 +185,13 @@ class Collection(BaseCollection):
partner_ids = cls.odoo.env['res.partner'].search([])
return ['res.partner:%s' % pid for pid in partner_ids]
@classmethod
def get_events_from_odoo(cls, login):
""" Gets all events available from one Odoo login """
cls.logger.info('Get events for Odoo user %s' % login)
event_ids = cls.odoo.env['calendar.event'].search([])
return ['calendar.event:%s' % eid for eid in event_ids]
def sync(self, old_token=None):
""" Debug purpose """
token, ilist = super(Collection, self).sync(old_token)
@ -185,13 +201,17 @@ class Collection(BaseCollection):
def list(self):
"""List collection items."""
# TODO : get all ICS from Odoo...
self.logger.debug('List collection %s' % self.path)
self.logger.debug('Collection tag %s' % self.tag)
if self.tag:
if self.tag == 'VADDRESSBOOK':
for oid in self.__class__.get_contacts_from_odoo(self.owner):
for oid in self.get_contacts_from_odoo(self.owner):
yield oid + self.content_suffix
elif self.tag == 'VCALENDAR':
for oid in self.get_events_from_odoo(self.owner):
yield oid + self.content_suffix
else:
raise NotImplementedError
@classmethod
def _generate_vcard_from_odoo(cls, partner):
@ -230,6 +250,40 @@ class Collection(BaseCollection):
vobject_item.add('rev').value = last_modified
return vobject_item
@classmethod
def _generate_ics_from_odoo(cls, href, event):
""" Generate and return UCS object from Odoo calendar.event record """
utc_dtstart = cls.odoo_date_to_utc(event.start_datetime)
utc_dtstop = cls.odoo_date_to_utc(event.stop_datetime)
last_modified = str(cls.odoo_date_to_utc(event.write_date))
cal = vobject.iCalendar()
cal.add('vevent')
cal.vevent.add('summary').value = event.name
cal.vevent.add('location').value = event.location
cal.vevent.add('description').value = event.description
cal.vevent.add('dtstart').value = utc_dtstart
cal.vevent.add('dtend').value = utc_dtstop
# cal.vevent.add('duration').value = event.duration
if event.categ_ids:
categs = [categ.name for categ in event.categ_ids]
cal.vevent.add('categories').value = categs
cal.vevent.add('uid').value = href
cal.vevent.add('rev').value = last_modified
cal.add('rev').value = last_modified
return cal
def _get_item_from_vobject(self, href, vobject_item):
""" Return Item from Vobject and HREF """
vobject_item.add('uid').value = href
tag, start, end = xmlutils.find_tag_and_time_range(vobject_item)
text = vobject_item.serialize()
etag = get_etag(text)
# uid = get_uid_from_object(vobject_item)
return Item(
self, href=href, last_modified=vobject_item.rev.value, etag=etag,
text=text, item=vobject_item, uid=href,
name=vobject_item.name, component_name=tag), (tag, start, end)
def _get_with_metadata(self, href):
"""Fetch a single item from Odoo database"""
model, database_id = href.split(':')
@ -240,17 +294,10 @@ class Collection(BaseCollection):
record = self.odoo.env[model].browse([database_id])
if model == 'res.partner':
vobject_item = self._generate_vcard_from_odoo(record)
vobject_item.add('uid').value = href
tag, start, end = xmlutils.find_tag_and_time_range(vobject_item)
text = vobject_item.serialize()
etag = get_etag(text)
# uid = get_uid_from_object(vobject_item)
return Item(
self, href=href, last_modified=vobject_item.rev.value, etag=etag,
text=text, item=vobject_item, uid=href,
name=vobject_item.name, component_name=tag), (tag, start, end)
return self._get_item_from_vobject(href, vobject_item)
elif model == 'calendar.event':
raise NotImplementedError
vobject_item = self._generate_ics_from_odoo(href, record)
return self._get_item_from_vobject(href, vobject_item)
else:
raise NotImplementedError