From 0a7efc04dcdca8404c4597f9f1642c380c6028a5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 25 Mar 2011 10:41:19 +0100 Subject: [PATCH] [IMP] eval action context and domain straight as they come from a tree_but_open (on menu), add APIDoc for OpenERPSession OpenERPSession is in charge of evaluating domains and contexts. Always. bzr revid: xmo@openerp.com-20110325094119-fpd4e00w20kbgfzf --- addons/base/controllers/main.py | 17 ++++--- doc/source/addons.rst | 9 ++++ openerpweb/openerpweb.py | 85 +++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 6 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 77eae20723b..60076d930e9 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -157,12 +157,17 @@ class Menu(openerpweb.Controller): @openerpweb.jsonrequest def action(self, req, menu_id): - print "QUERY" - m = req.session.model('ir.values') - r = m.get('action', 'tree_but_open', [('ir.ui.menu', menu_id)], False, {}) - print r - res = {"action": r} - return res + Values = req.session.model('ir.values') + actions = Values.get('action', 'tree_but_open', [('ir.ui.menu', menu_id)], False, {}) + + for _, _, action in actions: + print action + action['context'] = req.session.eval_context( + action['context']) or {} + action['domain'] = req.session.eval_domain( + action['domain'], action['context']) or [] + + return {"action": actions} class DataSet(openerpweb.Controller): diff --git a/doc/source/addons.rst b/doc/source/addons.rst index 71bfe9ceb37..70e753084de 100644 --- a/doc/source/addons.rst +++ b/doc/source/addons.rst @@ -275,6 +275,15 @@ convenient ways to refer to them and their properties. .. js:attribute:: sort +Python +++++++ + +.. autoclass:: openerpweb.openerpweb.OpenERPSession + :members: + +.. autoclass:: openerpweb.openerpweb.OpenERPModel + :members: + * Addons lifecycle (loading, execution, events, ...) * Python-side diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py index f858ff61aa5..3f53b07ffad 100644 --- a/openerpweb/openerpweb.py +++ b/openerpweb/openerpweb.py @@ -1,6 +1,9 @@ #!/usr/bin/python +import datetime import functools import optparse +import time +import dateutil.relativedelta import os import sys import tempfile @@ -39,6 +42,15 @@ class OpenERPModel(object): class OpenERPSession(object): + """ + An OpenERP RPC session, a given user can own multiple such sessions + in a web session. + + .. attribute:: context + + The session context, a ``dict``. Can be reloaded by calling + :meth:`openerpweb.openerpweb.OpenERPSession.get_context` + """ def __init__(self, server='127.0.0.1', port=8069, model_factory=OpenERPModel): self._server = server @@ -49,6 +61,8 @@ class OpenERPSession(object): self._password = False self.model_factory = model_factory + self.context = {} + def proxy(self, service): s = xmlrpctimeout.TimeoutServerProxy('http://%s:%s/xmlrpc/%s' % (self._server, self._port, service), timeout=5) return s @@ -62,6 +76,9 @@ class OpenERPSession(object): uid = self.proxy('common').login(db, login, password) self.bind(db, uid, password) self._login = login + + if uid: self.get_context() + return uid def execute(self, model, func, *l, **d): @@ -71,8 +88,76 @@ class OpenERPSession(object): return r def model(self, model): + """ Get an RPC proxy for the object ``model``, bound to this session. + + :param model: an OpenERP model name + :type model: str + :rtype: :class:`openerpweb.openerpweb.OpenERPModel` + """ return self.model_factory(self, model) + def get_context(self): + """ Re-initializes the current user's session context (based on + his preferences) by calling res.users.get_context() with the old + context + + :returns: the new context + """ + assert self._uid, "The user needs to be logged-in to initialize his context" + self.context = self.model('res.users').context_get(self.context) + return self.context + + @property + def base_eval_context(self): + """ Default evaluation context for the session. + + Used to evaluate contexts and domains. + """ + return dict( + uid=self._uid, + current_date=datetime.date.today().strftime('%Y-%m-%d'), + time=time, + datetime=datetime, + relativedelta=dateutil.relativedelta.relativedelta, + **self.context + ) + + def eval_context(self, context_string, context=None): + """ Evaluates the provided context_string in the context (haha) of + the context. + + :param str context_string: a context to evaluate, if not a string, + will be returned as-is + :param dict context: the context to use in the evaluation, if any. + Will be merged with a default context and + the session context. + :returns: the evaluated context + :rtype: dict + """ + if not isinstance(context_string, basestring): + return context_string + + return eval(context_string, dict( + self.base_eval_context, + **(context or {}))) + def eval_domain(self, domain_string, context=None): + """ Evaluates the provided domain_string using the provided context + (merged with the session's evaluation context) + + :param str domain_string: an OpenERP domain as a string, to evaluate. + + If not a string, is returned as-is + :param dict context: the context to use in the evaluation, if any. + :returns: the evaluated domain + :rtype: list + """ + if not isinstance(domain_string, basestring): + return domain_string + + return eval(domain_string, dict( + self.base_eval_context, + **(context or {}))) + #---------------------------------------------------------- # OpenERP Web RequestHandler #----------------------------------------------------------