[ADD][WIP]Radicale Odoo Storage : add calendar unique events display
This commit is contained in:
parent
b61be41911
commit
3350d83d94
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user