odoo/ext/3rd-party-addons/queue_job/fields.py

74 lines
2.2 KiB
Python

# -*- coding: utf-8 -*-
# copyright 2016 Camptocamp
# license agpl-3.0 or later (http://www.gnu.org/licenses/agpl.html)
import json
from datetime import datetime, date
import dateutil
from odoo import fields, models
class JobSerialized(fields.Field):
""" Serialized fields provide the storage for sparse fields. """
type = 'job_serialized'
column_type = ('text', 'text')
def convert_to_column(self, value, record, values=None):
return json.dumps(value, cls=JobEncoder)
def convert_to_cache(self, value, record, validate=True):
# cache format: dict
value = value or {}
if isinstance(value, dict):
return value
else:
return json.loads(value, cls=JobDecoder, env=record.env)
class JobEncoder(json.JSONEncoder):
""" Encode Odoo recordsets so that we can later recompose them """
def default(self, obj):
if isinstance(obj, models.BaseModel):
return {'_type': 'odoo_recordset',
'model': obj._name,
'ids': obj.ids,
'uid': obj.env.uid,
}
elif isinstance(obj, datetime):
return {'_type': 'datetime_isoformat',
'value': obj.isoformat()}
elif isinstance(obj, date):
return {'_type': 'date_isoformat',
'value': obj.isoformat()}
return json.JSONEncoder.default(self, obj)
class JobDecoder(json.JSONDecoder):
""" Decode json, recomposing recordsets """
def __init__(self, *args, **kwargs):
env = kwargs.pop('env')
super(JobDecoder, self).__init__(
object_hook=self.object_hook, *args, **kwargs
)
assert env
self.env = env
def object_hook(self, obj):
if '_type' not in obj:
return obj
type_ = obj['_type']
if type_ == 'odoo_recordset':
model = self.env[obj['model']]
if obj.get('uid'):
model = model.sudo(obj['uid'])
return model.browse(obj['ids'])
elif type_ == 'datetime_isoformat':
return dateutil.parser.parse(obj['value'])
elif type_ == 'date_isoformat':
return dateutil.parser.parse(obj['value']).date()
return obj