[PERF]Radicale Odoo Storage : huge performance optimization for events too
This commit is contained in:
parent
15cf112cc3
commit
7b82b4c2d4
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from time import strftime, strptime
|
from time import strftime, strptime
|
||||||
from datetime import timedelta
|
from datetime import timedelta, datetime
|
||||||
import pytz
|
import pytz
|
||||||
import vobject
|
import vobject
|
||||||
from odoorpc import ODOO
|
from odoorpc import ODOO
|
||||||
@ -88,8 +88,9 @@ class Collection(BaseCollection):
|
|||||||
self.is_principal = len(attributes) == 0
|
self.is_principal = len(attributes) == 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def odoo_date_to_utc(cls, date_obj):
|
def odoo_date_to_utc(cls, date_str):
|
||||||
""" Transform naive Odoo date object to UTC TZ """
|
""" Transform naive Odoo date object to UTC TZ """
|
||||||
|
date_obj = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
|
||||||
local_date = cls.server_timezone.localize(date_obj, is_dst=None)
|
local_date = cls.server_timezone.localize(date_obj, is_dst=None)
|
||||||
return local_date.astimezone(pytz.utc)
|
return local_date.astimezone(pytz.utc)
|
||||||
|
|
||||||
@ -155,6 +156,17 @@ class Collection(BaseCollection):
|
|||||||
def get_events_from_odoo(cls, login, path):
|
def get_events_from_odoo(cls, login, path):
|
||||||
""" Gets all events available from one Odoo login """
|
""" Gets all events available from one Odoo login """
|
||||||
cls.logger.info('Get events for Odoo user %s' % login)
|
cls.logger.info('Get events for Odoo user %s' % login)
|
||||||
|
fields = ['allday', 'start_date', 'stop_date', 'start_datetime',
|
||||||
|
'stop_datetime', 'write_date', 'name', 'location',
|
||||||
|
'description', 'recurrency', 'rrule', 'categ_ids', 'alarm_ids']
|
||||||
|
event_types = cls.odoo.execute_kw('calendar.event.type', 'search_read',
|
||||||
|
[[]], {'fields': ['name']})
|
||||||
|
cls.event_types = {et['id']: et['name'] for et in event_types}
|
||||||
|
event_alarms = cls.odoo.execute_kw('calendar.alarm', 'search_read',
|
||||||
|
[[]], {'fields': ['type',
|
||||||
|
'duration_minutes']})
|
||||||
|
cls.event_alarms = {ea['id']: ea for ea in event_alarms}
|
||||||
|
|
||||||
cls.odoo.env.context.update({'virtual_id': False}) # Only real events
|
cls.odoo.env.context.update({'virtual_id': False}) # Only real events
|
||||||
if path.endswith('odoo-calendar-own'):
|
if path.endswith('odoo-calendar-own'):
|
||||||
domain = [('user_id', '=', cls.odoo.env.uid)]
|
domain = [('user_id', '=', cls.odoo.env.uid)]
|
||||||
@ -164,10 +176,12 @@ class Collection(BaseCollection):
|
|||||||
domain = [('partner_ids', '=', pid)]
|
domain = [('partner_ids', '=', pid)]
|
||||||
else:
|
else:
|
||||||
domain = []
|
domain = []
|
||||||
event_ids = cls.odoo.env['calendar.event'].search(domain)
|
events = cls.odoo.execute_kw('calendar.event', 'search_read',
|
||||||
|
[domain], {'fields': fields})
|
||||||
|
cls.events = {e['id']: e for e in events}
|
||||||
# WARNING: Odoo does not remove from database deleted recurrent events...
|
# WARNING: Odoo does not remove from database deleted recurrent events...
|
||||||
# Should be fixed on Odoo side and will be fixed via 2way here too
|
# Should be fixed on Odoo side and will be fixed via 2way here too
|
||||||
return ['calendar.event:%s' % eid for eid in event_ids]
|
return ['calendar.event:%s' % eid for eid in cls.events.keys()]
|
||||||
|
|
||||||
def sync(self, old_token=None):
|
def sync(self, old_token=None):
|
||||||
""" Debug purpose """
|
""" Debug purpose """
|
||||||
@ -240,35 +254,41 @@ class Collection(BaseCollection):
|
|||||||
return vobject_item
|
return vobject_item
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _generate_ics_from_odoo(cls, href, event):
|
def _generate_ics_from_odoo(cls, href, database_id):
|
||||||
""" Generate and return UCS object from Odoo calendar.event record """
|
""" Generate and return UCS object from Odoo calendar.event record """
|
||||||
# TODO/IMP : attendees management (not handled directly by vobject)
|
# TODO/IMP : attendees management (not handled directly by vobject)
|
||||||
if event.allday:
|
event = cls.events.get(database_id)
|
||||||
utc_dtstart = event.start_date
|
if event.get('allday'):
|
||||||
utc_dtstop = event.stop_date + timedelta(days=1)
|
utc_dtstart = datetime.strptime(event.get('start_date'),
|
||||||
|
'%Y-%m-%d').date()
|
||||||
|
stop_date_obj = datetime.strptime(event.get('stop_date'),
|
||||||
|
'%Y-%m-%d').date()
|
||||||
|
utc_dtstop = stop_date_obj + timedelta(days=1)
|
||||||
else:
|
else:
|
||||||
utc_dtstart = cls.odoo_date_to_utc(event.start_datetime)
|
utc_dtstart = cls.odoo_date_to_utc(event.get('start_datetime'))
|
||||||
utc_dtstop = cls.odoo_date_to_utc(event.stop_datetime)
|
utc_dtstop = cls.odoo_date_to_utc(event.get('stop_datetime'))
|
||||||
last_modified = str(cls.odoo_date_to_utc(event.write_date))
|
last_modified = str(cls.odoo_date_to_utc(event.get('write_date')))
|
||||||
cal = vobject.iCalendar()
|
cal = vobject.iCalendar()
|
||||||
cal.add('vevent')
|
cal.add('vevent')
|
||||||
cal.vevent.add('summary').value = event.name
|
cal.vevent.add('summary').value = event.get('name')
|
||||||
cal.vevent.add('location').value = event.location or ''
|
cal.vevent.add('location').value = event.get('location') or ''
|
||||||
cal.vevent.add('description').value = event.description or ''
|
cal.vevent.add('description').value = event.get('description') or ''
|
||||||
cal.vevent.add('dtstart').value = utc_dtstart
|
cal.vevent.add('dtstart').value = utc_dtstart
|
||||||
cal.vevent.add('dtend').value = utc_dtstop
|
cal.vevent.add('dtend').value = utc_dtstop
|
||||||
# cal.vevent.add('duration').value = event.duration
|
# cal.vevent.add('duration').value = event.duration
|
||||||
if event.categ_ids:
|
if event.get('categ_ids'):
|
||||||
categs = [categ.name for categ in event.categ_ids]
|
categs = [cls.event_types.get(etid) for etid in event.get('categ_ids')]
|
||||||
cal.vevent.add('categories').value = categs
|
cal.vevent.add('categories').value = categs
|
||||||
if event.alarm_ids:
|
if event.get('alarm_ids'):
|
||||||
for alarm in event.alarm_ids:
|
for alarm_id in event.get('alarm_ids'):
|
||||||
|
alarm = cls.event_alarms.get(alarm_id)
|
||||||
valarm = cal.vevent.add('valarm')
|
valarm = cal.vevent.add('valarm')
|
||||||
action = 'DISPLAY' if alarm.type == 'notification' else 'EMAIL'
|
action = 'DISPLAY' if alarm.get('type') == 'notification' else 'EMAIL'
|
||||||
valarm.add('action').value = action
|
valarm.add('action').value = action
|
||||||
valarm.add('trigger').value = timedelta(minutes=-alarm.duration_minutes)
|
valarm.add('trigger').value = timedelta(
|
||||||
if event.recurrency:
|
minutes=-alarm.get('duration_minutes'))
|
||||||
cal.vevent.add('rrule').value = event.rrule
|
if event.get('recurrency'):
|
||||||
|
cal.vevent.add('rrule').value = event.get('rrule')
|
||||||
cal.vevent.add('uid').value = href
|
cal.vevent.add('uid').value = href
|
||||||
cal.vevent.add('rev').value = last_modified
|
cal.vevent.add('rev').value = last_modified
|
||||||
cal.add('rev').value = last_modified
|
cal.add('rev').value = last_modified
|
||||||
@ -294,8 +314,7 @@ class Collection(BaseCollection):
|
|||||||
vobject_item = self._generate_vcard_from_odoo(database_id)
|
vobject_item = self._generate_vcard_from_odoo(database_id)
|
||||||
return self._get_item_from_vobject(href, vobject_item)
|
return self._get_item_from_vobject(href, vobject_item)
|
||||||
elif model == 'calendar.event':
|
elif model == 'calendar.event':
|
||||||
record = self.odoo.env[model].browse([database_id])
|
vobject_item = self._generate_ics_from_odoo(href, database_id)
|
||||||
vobject_item = self._generate_ics_from_odoo(href, record)
|
|
||||||
return self._get_item_from_vobject(href, vobject_item)
|
return self._get_item_from_vobject(href, vobject_item)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
Loading…
x
Reference in New Issue
Block a user