[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 time import strftime, strptime
|
||||
from datetime import timedelta
|
||||
from datetime import timedelta, datetime
|
||||
import pytz
|
||||
import vobject
|
||||
from odoorpc import ODOO
|
||||
@ -88,8 +88,9 @@ class Collection(BaseCollection):
|
||||
self.is_principal = len(attributes) == 0
|
||||
|
||||
@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 """
|
||||
date_obj = datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S')
|
||||
local_date = cls.server_timezone.localize(date_obj, is_dst=None)
|
||||
return local_date.astimezone(pytz.utc)
|
||||
|
||||
@ -155,6 +156,17 @@ class Collection(BaseCollection):
|
||||
def get_events_from_odoo(cls, login, path):
|
||||
""" Gets all events available from one Odoo 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
|
||||
if path.endswith('odoo-calendar-own'):
|
||||
domain = [('user_id', '=', cls.odoo.env.uid)]
|
||||
@ -164,10 +176,12 @@ class Collection(BaseCollection):
|
||||
domain = [('partner_ids', '=', pid)]
|
||||
else:
|
||||
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...
|
||||
# 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):
|
||||
""" Debug purpose """
|
||||
@ -240,35 +254,41 @@ class Collection(BaseCollection):
|
||||
return vobject_item
|
||||
|
||||
@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 """
|
||||
# TODO/IMP : attendees management (not handled directly by vobject)
|
||||
if event.allday:
|
||||
utc_dtstart = event.start_date
|
||||
utc_dtstop = event.stop_date + timedelta(days=1)
|
||||
event = cls.events.get(database_id)
|
||||
if event.get('allday'):
|
||||
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:
|
||||
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))
|
||||
utc_dtstart = cls.odoo_date_to_utc(event.get('start_datetime'))
|
||||
utc_dtstop = cls.odoo_date_to_utc(event.get('stop_datetime'))
|
||||
last_modified = str(cls.odoo_date_to_utc(event.get('write_date')))
|
||||
cal = vobject.iCalendar()
|
||||
cal.add('vevent')
|
||||
cal.vevent.add('summary').value = event.name
|
||||
cal.vevent.add('location').value = event.location or ''
|
||||
cal.vevent.add('description').value = event.description or ''
|
||||
cal.vevent.add('summary').value = event.get('name')
|
||||
cal.vevent.add('location').value = event.get('location') or ''
|
||||
cal.vevent.add('description').value = event.get('description') or ''
|
||||
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]
|
||||
if event.get('categ_ids'):
|
||||
categs = [cls.event_types.get(etid) for etid in event.get('categ_ids')]
|
||||
cal.vevent.add('categories').value = categs
|
||||
if event.alarm_ids:
|
||||
for alarm in event.alarm_ids:
|
||||
if event.get('alarm_ids'):
|
||||
for alarm_id in event.get('alarm_ids'):
|
||||
alarm = cls.event_alarms.get(alarm_id)
|
||||
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('trigger').value = timedelta(minutes=-alarm.duration_minutes)
|
||||
if event.recurrency:
|
||||
cal.vevent.add('rrule').value = event.rrule
|
||||
valarm.add('trigger').value = timedelta(
|
||||
minutes=-alarm.get('duration_minutes'))
|
||||
if event.get('recurrency'):
|
||||
cal.vevent.add('rrule').value = event.get('rrule')
|
||||
cal.vevent.add('uid').value = href
|
||||
cal.vevent.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)
|
||||
return self._get_item_from_vobject(href, vobject_item)
|
||||
elif model == 'calendar.event':
|
||||
record = self.odoo.env[model].browse([database_id])
|
||||
vobject_item = self._generate_ics_from_odoo(href, record)
|
||||
vobject_item = self._generate_ics_from_odoo(href, database_id)
|
||||
return self._get_item_from_vobject(href, vobject_item)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
Loading…
Reference in New Issue
Block a user