3 import dateutil.relativedelta
8 #----------------------------------------------------------
9 # OpenERPSession RPC openerp backend access
10 #----------------------------------------------------------
11 class OpenERPUnboundException(Exception):
14 class OpenERPConnector(object):
17 class OpenERPAuth(object):
20 class OpenERPSession(object):
22 An OpenERP RPC session, a given user can own multiple such sessions
25 .. attribute:: context
27 The session context, a ``dict``. Can be reloaded by calling
28 :meth:`openerpweb.openerpweb.OpenERPSession.get_context`
30 .. attribute:: domains_store
32 A ``dict`` matching domain keys to evaluable (but non-literal) domains.
34 Used to store references to non-literal domains which need to be
35 round-tripped to the client browser.
37 def __init__(self, server='127.0.0.1', port=8069):
43 self._password = False
44 self.model_factory = model_factory
45 self._locale = 'en_US'
47 self.contexts_store = {}
48 self.domains_store = {}
50 self.remote_timezone = 'utc'
51 self.client_timezone = False
53 def build_connection(self):
54 return openerplib.get_connection(hostname=self._server, port=self._port,
56 user_id=self._uid, password=self._password)
58 def proxy(self, service):
59 return self.build_connection().get_service(service)
61 def bind(self, db, uid, password):
64 self._password = password
66 def login(self, db, login, password):
67 uid = self.proxy('common').login(db, login, password)
68 self.bind(db, uid, password)
71 if uid: self.get_context()
74 def assert_valid(self):
76 Ensures this session is valid (logged into the openerp server)
78 if not (self._db and self._uid and self._password):
79 raise OpenERPUnboundException()
81 def execute(self, model, func, *l, **d):
83 model = self.build_connection().get_model(model)
84 r = getattr(model, func)(*l, **d)
87 def exec_workflow(self, model, id, signal):
89 r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id)
92 def model(self, model):
93 """ Get an RPC proxy for the object ``model``, bound to this session.
95 :param model: an OpenERP model name
97 :rtype: a model object
99 return self.build_connection().get_model(model)
101 def get_context(self):
102 """ Re-initializes the current user's session context (based on
103 his preferences) by calling res.users.get_context() with the old
106 :returns: the new context
108 assert self._uid, "The user needs to be logged-in to initialize his context"
109 self.context = self.model('res.users').context_get(self.context)
110 self.context = self.context or {}
112 self.client_timezone = self.context.get("tz", False)
113 # invalid code, anyway we decided the server will be in UTC
114 #if self.client_timezone:
115 # self.remote_timezone = self.execute('common', 'timezone_get')
117 self._locale = self.context.get('lang','en_US')
118 lang_ids = self.execute('res.lang','search', [('code', '=', self._locale)])
120 self._lang = self.execute('res.lang', 'read',lang_ids[0], [])
124 def base_eval_context(self):
125 """ Default evaluation context for the session.
127 Used to evaluate contexts and domains.
131 current_date=datetime.date.today().strftime('%Y-%m-%d'),
134 relativedelta=dateutil.relativedelta.relativedelta
136 base.update(self.context)
139 def evaluation_context(self, context=None):
140 """ Returns the session's evaluation context, augmented with the
141 provided context if any.
143 :param dict context: to add merge in the session's base eval context
144 :returns: the augmented context
147 d = dict(self.base_eval_context)
153 def eval_context(self, context_to_eval, context=None):
154 """ Evaluates the provided context_to_eval in the context (haha) of
155 the context. Also merges the evaluated context with the session's context.
157 :param context_to_eval: a context to evaluate. Must be a dict or a
158 non-literal context. If it's a dict, will be
160 :type context_to_eval: openerpweb.nonliterals.Context
161 :returns: the evaluated context
164 :raises: ``TypeError`` if ``context_to_eval`` is neither a dict nor
168 self.base_eval_context,
171 # adding the context of the session to send to the openerp server
172 ccontext = nonliterals.CompoundContext(self.context, context_to_eval or {})
173 ccontext.session = self
174 return ccontext.evaluate(ctx)
176 def eval_domain(self, domain, context=None):
177 """ Evaluates the provided domain using the provided context
178 (merged with the session's evaluation context)
180 :param domain: an OpenERP domain as a list or as a
181 :class:`openerpweb.nonliterals.Domain` instance
183 In the second case, it will be evaluated and returned.
184 :type domain: openerpweb.nonliterals.Domain
185 :param dict context: the context to use in the evaluation, if any.
186 :returns: the evaluated domain
189 :raises: ``TypeError`` if ``domain`` is neither a list nor a Domain
191 if isinstance(domain, list):
194 cdomain = nonliterals.CompoundDomain(domain)
195 cdomain.session = self
196 return cdomain.evaluate(context or {})