3 import dateutil.relativedelta
10 _logger = logging.getLogger(__name__)
11 #----------------------------------------------------------
12 # OpenERPSession RPC openerp backend access
13 #----------------------------------------------------------
14 class OpenERPSession(object):
16 An OpenERP RPC session, a given user can own multiple such sessions
19 .. attribute:: context
21 The session context, a ``dict``. Can be reloaded by calling
22 :meth:`openerpweb.openerpweb.OpenERPSession.get_context`
24 .. attribute:: domains_store
26 A ``dict`` matching domain keys to evaluable (but non-literal) domains.
28 Used to store references to non-literal domains which need to be
29 round-tripped to the client browser.
32 self._creation_time = time.time()
37 self._password = False
39 self.contexts_store = {}
40 self.domains_store = {}
41 self.jsonp_requests = {} # FIXME use a LRU
43 def __getstate__(self):
44 state = dict(self.__dict__)
49 def openerp_entreprise(self):
53 return self.model('publisher_warranty.contract').status()['status'] == 'full'
55 def build_connection(self):
56 conn = openerplib.Connection(self.config.connector, database=self._db, login=self._login,
57 user_id=self._uid, password=self._password)
60 def proxy(self, service):
61 return self.build_connection().get_service(service)
63 def bind(self, db, uid, login, password):
67 self._password = password
69 def authenticate(self, db, login, password, env):
70 # TODO use the openerplib API once it exposes authenticate()
71 uid = self.proxy('common').authenticate(db, login, password, env)
72 self.bind(db, uid, login, password)
74 if uid: self.get_context()
77 def assert_valid(self, force=False):
79 Ensures this session is valid (logged into the openerp server)
81 self.build_connection().check_login(force)
83 def execute(self, model, func, *l, **d):
85 model = self.build_connection().get_model(model)
86 r = getattr(model, func)(*l, **d)
89 def exec_workflow(self, model, id, signal):
91 r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id)
94 def model(self, model):
95 """ Get an RPC proxy for the object ``model``, bound to this session.
97 :param model: an OpenERP model name
99 :rtype: a model object
101 return self.build_connection().get_model(model)
103 def get_context(self):
104 """ Re-initializes the current user's session context (based on
105 his preferences) by calling res.users.get_context() with the old
108 :returns: the new context
110 assert self._uid, "The user needs to be logged-in to initialize his context"
111 self.context = self.build_connection().get_user_context() or {}
116 def base_eval_context(self):
117 """ Default evaluation context for the session.
119 Used to evaluate contexts and domains.
123 current_date=datetime.date.today().strftime('%Y-%m-%d'),
126 relativedelta=dateutil.relativedelta.relativedelta
128 base.update(self.context)
131 def evaluation_context(self, context=None):
132 """ Returns the session's evaluation context, augmented with the
133 provided context if any.
135 :param dict context: to add merge in the session's base eval context
136 :returns: the augmented context
139 d = dict(self.base_eval_context)
145 def eval_context(self, context_to_eval, context=None):
146 """ Evaluates the provided context_to_eval in the context (haha) of
147 the context. Also merges the evaluated context with the session's context.
149 :param context_to_eval: a context to evaluate. Must be a dict or a
150 non-literal context. If it's a dict, will be
152 :type context_to_eval: openerpweb.nonliterals.Context
153 :returns: the evaluated context
156 :raises: ``TypeError`` if ``context_to_eval`` is neither a dict nor
160 self.base_eval_context,
163 # adding the context of the session to send to the openerp server
164 ccontext = nonliterals.CompoundContext(self.context, context_to_eval or {})
165 ccontext.session = self
166 return ccontext.evaluate(ctx)
168 def eval_domain(self, domain, context=None):
169 """ Evaluates the provided domain using the provided context
170 (merged with the session's evaluation context)
172 :param domain: an OpenERP domain as a list or as a
173 :class:`openerpweb.nonliterals.Domain` instance
175 In the second case, it will be evaluated and returned.
176 :type domain: openerpweb.nonliterals.Domain
177 :param dict context: the context to use in the evaluation, if any.
178 :returns: the evaluated domain
181 :raises: ``TypeError`` if ``domain`` is neither a list nor a Domain
183 if isinstance(domain, list):
186 cdomain = nonliterals.CompoundDomain(domain)
187 cdomain.session = self
188 return cdomain.evaluate(context or {})