[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 """
|
""" Odoo Radicale Storage Plugin """
|
||||||
|
|
||||||
# # PLAN
|
# # PLAN
|
||||||
# 1. Implement readonly from Odoo only
|
# 1. OK : Implement readonly from Odoo only
|
||||||
# 2. Implement contacts first (and so vcf)
|
# 2. OK : Implement contacts first (and so vcf)
|
||||||
# 3. Implement unique events (.ics)
|
# 3. OK : Implement unique events (.ics) and timezone
|
||||||
# 4. Implement recurrent events
|
# 4. Implement notifications for events
|
||||||
# 5. Begin write (two way) for contacts
|
# 5. Implement recurrent events
|
||||||
# 5. Begin write (two way) for calendar
|
# 6. Begin write (two way) for contacts
|
||||||
|
# 7. Begin write (two way) for calendar
|
||||||
|
|
||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from time import strftime, strptime
|
from time import strftime, strptime
|
||||||
|
import pytz
|
||||||
import vobject
|
import vobject
|
||||||
from odoorpc import ODOO
|
from odoorpc import ODOO
|
||||||
from odoorpc.error import RPCError
|
from odoorpc.error import RPCError
|
||||||
@ -47,8 +49,10 @@ class Collection(BaseCollection):
|
|||||||
if not self.__class__.odoo:
|
if not self.__class__.odoo:
|
||||||
self.logger.error('No auth Odoo found...')
|
self.logger.error('No auth Odoo found...')
|
||||||
raise RuntimeError('No auth Odoo found')
|
raise RuntimeError('No auth Odoo found')
|
||||||
self.__class__.odoo_connect()
|
# self.__class__.odoo_connect()
|
||||||
# self.odoo_init()
|
# self.odoo_init()
|
||||||
|
odoo_timezone = self.configuration.get('storage', 'odoo_timezone')
|
||||||
|
self.__class__.server_timezone = pytz.timezone(odoo_timezone)
|
||||||
|
|
||||||
attributes = path.strip('/').split('/')
|
attributes = path.strip('/').split('/')
|
||||||
self.tag = None
|
self.tag = None
|
||||||
@ -118,6 +122,11 @@ class Collection(BaseCollection):
|
|||||||
self.create_collection(calendar_path, props=props)
|
self.create_collection(calendar_path, props=props)
|
||||||
self.logger.info('Collection creation for Odoo Sync : %s' % calendar_path)
|
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
|
@classmethod
|
||||||
@contextmanager
|
@contextmanager
|
||||||
@ -176,6 +185,13 @@ class Collection(BaseCollection):
|
|||||||
partner_ids = cls.odoo.env['res.partner'].search([])
|
partner_ids = cls.odoo.env['res.partner'].search([])
|
||||||
return ['res.partner:%s' % pid for pid in partner_ids]
|
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):
|
def sync(self, old_token=None):
|
||||||
""" Debug purpose """
|
""" Debug purpose """
|
||||||
token, ilist = super(Collection, self).sync(old_token)
|
token, ilist = super(Collection, self).sync(old_token)
|
||||||
@ -185,13 +201,17 @@ class Collection(BaseCollection):
|
|||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
"""List collection items."""
|
"""List collection items."""
|
||||||
# TODO : get all ICS from Odoo...
|
|
||||||
self.logger.debug('List collection %s' % self.path)
|
self.logger.debug('List collection %s' % self.path)
|
||||||
self.logger.debug('Collection tag %s' % self.tag)
|
self.logger.debug('Collection tag %s' % self.tag)
|
||||||
if self.tag:
|
if self.tag:
|
||||||
if self.tag == 'VADDRESSBOOK':
|
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
|
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
|
@classmethod
|
||||||
def _generate_vcard_from_odoo(cls, partner):
|
def _generate_vcard_from_odoo(cls, partner):
|
||||||
@ -230,6 +250,40 @@ class Collection(BaseCollection):
|
|||||||
vobject_item.add('rev').value = last_modified
|
vobject_item.add('rev').value = last_modified
|
||||||
return vobject_item
|
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):
|
def _get_with_metadata(self, href):
|
||||||
"""Fetch a single item from Odoo database"""
|
"""Fetch a single item from Odoo database"""
|
||||||
model, database_id = href.split(':')
|
model, database_id = href.split(':')
|
||||||
@ -240,17 +294,10 @@ class Collection(BaseCollection):
|
|||||||
record = self.odoo.env[model].browse([database_id])
|
record = self.odoo.env[model].browse([database_id])
|
||||||
if model == 'res.partner':
|
if model == 'res.partner':
|
||||||
vobject_item = self._generate_vcard_from_odoo(record)
|
vobject_item = self._generate_vcard_from_odoo(record)
|
||||||
vobject_item.add('uid').value = href
|
return self._get_item_from_vobject(href, vobject_item)
|
||||||
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)
|
|
||||||
elif model == 'calendar.event':
|
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:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user