Files
tryton/trytond/rpc.py
T

97 lines
3.4 KiB
Python
Raw Normal View History

2014-12-02 12:54:01 +01:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import copy
2019-04-08 10:10:40 +02:00
import datetime as dt
2016-06-23 18:48:52 +02:00
from trytond.transaction import Transaction
2012-09-24 22:16:53 +02:00
__all__ = ['RPC']
class RPC(object):
'''Define RPC behavior
readonly: The transaction mode
2013-12-19 14:44:01 +01:00
instantiate: The position or the slice of the arguments to be instanciated
2012-09-24 22:16:53 +02:00
result: The function to transform the result
2014-09-17 21:43:53 +02:00
check_access: If access right must be checked
2018-08-26 18:04:05 +02:00
fresh_session: If a fresh session is required
unique: Check instances are unique
2012-09-24 22:16:53 +02:00
'''
2018-08-26 18:04:05 +02:00
__slots__ = ('readonly', 'instantiate', 'result', 'check_access',
2019-04-08 10:10:40 +02:00
'fresh_session', 'unique', 'cache')
2012-09-24 22:16:53 +02:00
2014-09-17 21:43:53 +02:00
def __init__(self, readonly=True, instantiate=None, result=None,
2019-04-08 10:10:40 +02:00
check_access=True, fresh_session=False, unique=True, cache=None):
2012-09-24 22:16:53 +02:00
self.readonly = readonly
self.instantiate = instantiate
if result is None:
2020-03-01 12:33:54 +01:00
def result(r):
return r
2012-09-24 22:16:53 +02:00
self.result = result
2014-09-17 21:43:53 +02:00
self.check_access = check_access
2018-08-26 18:04:05 +02:00
self.fresh_session = fresh_session
self.unique = unique
2019-04-08 10:10:40 +02:00
if cache:
if not isinstance(cache, RPCCache):
cache = RPCCache(**cache)
self.cache = cache
2012-09-24 22:16:53 +02:00
def convert(self, obj, *args, **kwargs):
args = list(args)
kwargs = kwargs.copy()
2012-09-24 22:16:53 +02:00
if 'context' in kwargs:
context = kwargs.pop('context')
if not isinstance(context, dict):
raise TypeError("context must be a dictionary")
2012-09-24 22:16:53 +02:00
else:
try:
context = args.pop()
except IndexError:
context = None
if not isinstance(context, dict):
raise ValueError("Missing context argument")
context = copy.deepcopy(context)
2012-09-24 22:16:53 +02:00
timestamp = None
2018-06-26 19:11:19 +02:00
for key in list(context.keys()):
2014-11-19 21:35:51 +01:00
if key == '_timestamp':
timestamp = context[key]
# Remove all private keyword but _datetime for history
if key.startswith('_') and key != '_datetime':
2014-11-19 21:35:51 +01:00
del context[key]
2012-09-24 22:16:53 +02:00
if self.instantiate is not None:
def instance(data):
2016-06-23 18:48:52 +02:00
with Transaction().set_context(context):
2018-06-26 19:11:19 +02:00
if isinstance(data, int):
2016-06-23 18:48:52 +02:00
return obj(data)
elif isinstance(data, dict):
return obj(**data)
else:
if self.unique and len(data) != len(set(data)):
raise ValueError("Duplicate ids")
2016-06-23 18:48:52 +02:00
return obj.browse(data)
2013-12-19 14:44:01 +01:00
if isinstance(self.instantiate, slice):
for i, data in enumerate(args[self.instantiate]):
start, _, step = self.instantiate.indices(len(args))
i = i * step + start
args[i] = instance(data)
else:
data = args[self.instantiate]
args[self.instantiate] = instance(data)
2016-06-23 18:48:52 +02:00
if self.check_access:
context['_check_access'] = True
2012-09-24 22:16:53 +02:00
return args, kwargs, context, timestamp
2019-04-08 10:10:40 +02:00
class RPCCache:
__slots__ = ('duration',)
def __init__(self, days=0, seconds=0):
self.duration = dt.timedelta(days=days, seconds=seconds)
def headers(self):
return {
'X-Tryton-Cache': int(self.duration.total_seconds()),
}