[IMP][WIP]Odoo storage plugin : other implementations, tests and failures...

This commit is contained in:
Fabien BOURGEOIS 2018-05-09 18:24:12 +02:00
parent f23010827e
commit 94f6e12601
1 changed files with 125 additions and 11 deletions

View File

@ -17,12 +17,23 @@
""" Odoo Radicale Storage Plugin """
from json import dumps
import threading
# # 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
from contextlib import contextmanager
from time import strftime, strptime
import vobject
from odoorpc import ODOO
from odoorpc.error import RPCError
from radicale.storage import BaseCollection
from radicale import xmlutils
from radicale.storage import BaseCollection, Item, get_etag, get_uid_from_object
from radicale_odoo_auth import Auth
class Collection(BaseCollection):
@ -32,7 +43,10 @@ class Collection(BaseCollection):
def __init__(self, path):
""" Init function """
if not self.odoo:
self.__class__.odoo = Auth.odoo
if not self.__class__.odoo:
self.logger.error('No auth Odoo found...')
raise RuntimeError('No auth Odoo found')
self.__class__.odoo_connect()
# self.odoo_init()
@ -41,12 +55,14 @@ class Collection(BaseCollection):
self.props = {}
if 'odoo-contact' in attributes:
self.tag = 'VADDRESSBOOK'
self.odoo_model = 'res.partner'
self.content_suffix = '.vcf'
self.props.update({'tag': 'VADDRESSBOOK',
'D:displayname': 'Odoo contacts',
'CR:addressbook-description': 'Contacts form your Odoo account'})
elif 'odoo-calendar' in attributes:
self.tag = 'VCALENDAR'
self.odoo_model = 'calendar.event'
self.content_suffix = '.ics'
self.props.update({'tag': 'VCALENDAR',
'D:displayname': 'Odoo calendar',
@ -132,18 +148,116 @@ class Collection(BaseCollection):
cls.logger.warning('Discover : %s (path), %s (depth), %s (cls.user), %s (attributes)' %
(path, depth, cls.user, attributes))
yield cls(path)
contact_path = '%s/odoo-contact' % path
calendar_path = '%s/odoo-calendar' % path
yield cls(contact_path)
yield cls(calendar_path)
if len(attributes) == 1: # Got all if root is needed
contact_path = '%s/odoo-contact' % path
calendar_path = '%s/odoo-calendar' % path
yield cls(contact_path)
yield cls(calendar_path)
def get_meta(self, key=None):
"""Get metadata value for collection """
if key == 'tag':
return self.tag
return self.props.get(key)
if key:
return self.props.get(key)
else:
return self.props
@classmethod
def create_collection(cls, href, collection=None, props=None):
""" Create collection implementation : only warns ATM """
cls.logger.error('Attemmpt to create a new collection for %s' % href)
@classmethod
def get_contacts_from_odoo(cls, login):
""" Gets all contacts available from one Odoo login """
cls.logger.info('Get contacts for Odoo user %s' % login)
partner_ids = cls.odoo.env['res.partner'].search([])
cls.logger.debug(partner_ids)
return ['res.partner:%s' % pid for pid in partner_ids]
def list(self):
"""List collection items."""
# TODO : get all ICS from Odoo...
self.logger.warning('List collection %s' % self.path)
self.logger.warning('Collection tag %s' % self.tag)
if self.tag:
if self.tag == 'VADDRESSBOOK':
for oid in self.__class__.get_contacts_from_odoo(self.owner):
yield oid
# for item in self.collection.list():
# yield item.uid + self.content_suffix
def _get_with_metadata(self, href):
"""Fetch a single item from Odoo database"""
model, database_id = href.split(':')
fields = ['name', 'write_date', 'comment']
data = self.odoo.execute(model, 'read', [int(database_id)], fields)[0]
self.logger.warning(data)
if model == 'res.partner':
# last_modified = strftime("%a, %d %b %Y %H:%M:%S GMT",
# strptime(data.get('write_date'), '%Y-%m-%d %H:%M:%S'))
last_modified = strftime("%Y-%m-%dT%H:%M:%SZ",
strptime(data.get('write_date'), '%Y-%m-%d %H:%M:%S'))
self.logger.warning(last_modified)
vobject_item = vobject.vCard()
vobject_item.add('n')
vobject_item.n.value = vobject.vcard.Name(family=data.get('name'))
vobject_item.add('fn')
vobject_item.fn.value = data.get('name')
vobject_item.add('uid').value = database_id
vobject_item.add('rev').value = last_modified
self.logger.warning(vobject_item.name)
self.logger.warning([c for c in vobject_item.components()])
tag, start, end = xmlutils.find_tag_and_time_range(vobject_item)
self.logger.warning('Tag, start, end : %s %s %s' % (tag, start, end))
text = vobject_item.serialize()
etag = get_etag(text)
uid = get_uid_from_object(vobject_item)
self.logger.warning('Text, ETAG, UID : %s %s %s' % (text, etag, uid))
return Item(
self, href=href, last_modified=last_modified, etag=etag,
text=text, item=vobject_item, uid=href,
name=vobject_item.name, component_name=tag), (tag, start, end)
elif model == 'calendar.event':
raise NotImplementedError
else:
raise NotImplementedError
def get(self, href, verify_href=True):
item, metadata = self._get_with_metadata(href)
self.logger.warning(item)
self.logger.warning(item.serialize())
self.logger.warning(item.name)
self.logger.warning(item.last_modified)
self.logger.warning([c for c in item.components()])
self.logger.warning(metadata)
return item
def delete(self, href=None):
""" Can not delete collection but item, yes """
self.logger.warning(href)
if href is None:
# Delete the collection
self.logger.error('Attempt to delete collection %s' % self.path)
raise ValueError('Can not delete collection')
else:
# Delete an item
raise NotImplementedError
# def serialize(self):
# """ Get the whole collection unicode """
# # TODO: CALENDAR
# self.logger.warning('From serialize : %s' % self.tag)
# if self.tag == "VADDRESSBOOK":
# self.logger.warning('HERE')
# self.logger.warning([item.serialize() for item in self.get_all()])
# return ''.join((item.serialize() for item in self.get_all()))
# return ''
@property
def last_modified(self):
""" Return last modified """
last = self.odoo.env[self.odoo_model].search([], limit=1, order='write_date desc')
last_fields = self.odoo.execute(self.odoo_model, 'read', last, ['write_date'])[0]
self.logger.info(last_fields)
return strftime("%a, %d %b %Y %H:%M:%S GMT",
strptime(last_fields.get('write_date'), '%Y-%m-%d %H:%M:%S'))