From 75dc39e0428465f38b2d3c4840764cdb0fac69db Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Thu, 18 Aug 2016 14:30:08 +0200 Subject: [PATCH] [REF] openerp.http: make `request.context` consistent with `request.env.context` --- addons/web/controllers/main.py | 6 +- addons/web_editor/models/ir_http.py | 14 +-- addons/website/models/ir_http.py | 16 ++-- addons/website/models/website.py | 2 +- addons/website_event/controllers/main.py | 4 +- addons/website_event_sale/controllers/main.py | 6 +- addons/website_sale/controllers/main.py | 2 +- openerp/http.py | 86 ++++++++++--------- 8 files changed, 73 insertions(+), 63 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 186e9715a8c..55edef0a3ed 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1102,14 +1102,14 @@ class Action(http.Controller): base_action = Actions.browse([action_id]).read(['type']) if base_action: - ctx = request.context + ctx = dict(request.context) action_type = base_action[0]['type'] if action_type == 'ir.actions.report.xml': ctx.update({'bin_size': True}) if additional_context: ctx.update(additional_context) - env = request.env(context=ctx) - action = env[action_type].browse([action_id]).read() + request.context = ctx + action = request.env[action_type].browse([action_id]).read() if action: value = clean_action(action[0]) return value diff --git a/addons/web_editor/models/ir_http.py b/addons/web_editor/models/ir_http.py index 238b488716e..5abe7862245 100644 --- a/addons/web_editor/models/ir_http.py +++ b/addons/web_editor/models/ir_http.py @@ -9,10 +9,12 @@ class IrHttp(models.AbstractModel): _inherit = 'ir.http' def _dispatch(self): - if 'editable' in request.httprequest.args and 'editable' not in request.context: - request.context['editable'] = True - if 'edit_translations' in request.httprequest.args and 'edit_translations' not in request.context: - request.context['edit_translations'] = True - if request.context.get('lang') != "en_US" and 'translatable' not in request.context: - request.context['translatable'] = True + context = dict(request.context) + if 'editable' in request.httprequest.args and 'editable' not in context: + context['editable'] = True + if 'edit_translations' in request.httprequest.args and 'edit_translations' not in context: + context['edit_translations'] = True + if context.get('lang') != "en_US" and 'translatable' not in context: + context['translatable'] = True + request.context = context return super(IrHttp, self)._dispatch() diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 6aa299ed4fb..58e87bb8e20 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -154,7 +154,8 @@ class Http(models.AbstractModel): request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code) request.website = request.env['website'].get_current_website() # can use `request.env` since auth methods are called - request.context['website_id'] = request.website.id + context = dict(request.context) + context['website_id'] = request.website.id langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') if first_pass: @@ -166,7 +167,7 @@ class Http(models.AbstractModel): is_a_bot = self.is_a_bot() - request.lang = request.context['lang'] = nearest_lang or preferred_lang + request.lang = context['lang'] = nearest_lang or preferred_lang # if lang in url but not the displayed or default language --> change or remove # or no lang in url, and lang to dispay not the default language --> add lang # and not a POST request @@ -182,17 +183,20 @@ class Http(models.AbstractModel): path = '/'.join(path) or '/' redirect = request.redirect(path + '?' + request.httprequest.query_string) redirect.set_cookie('website_lang', request.lang) + request.context = context return redirect elif url_lang: request.uid = None path.pop(1) + request.context = context return self.reroute('/'.join(path) or '/') if path[1] == request.website.default_lang_code: - request.context['edit_translations'] = False - if not request.context.get('tz'): - request.context['tz'] = request.session.get('geoip', {}).get('time_zone') + context['edit_translations'] = False + if not context.get('tz'): + context['tz'] = request.session.get('geoip', {}).get('time_zone') # bind modified context - request.website = request.website.with_context(request.context) + request.context = context + request.website = request.website.with_context(context) # removed cache for auth public request.cache_save = False diff --git a/addons/website/models/website.py b/addons/website/models/website.py index e48fa69136c..a2ce44f72ca 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -394,7 +394,7 @@ class Website(models.Model): def get_current_website(self): domain_name = request.httprequest.environ.get('HTTP_HOST', '').split(':')[0] website_id = self._get_current_website_id(domain_name) - request.context['website_id'] = website_id + request.context = dict(request.context, website_id=website_id) return self.browse(website_id) @tools.cache('domain_name') diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index c0ec1c82708..9a9ef605118 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -178,8 +178,6 @@ class WebsiteEventController(http.Controller): return request.redirect("/event/%s/register?enable_editor=1" % slug(event)) def _add_event(self, event_name=None, context=None, **kwargs): - if context is None: - context = {} if not event_name: event_name = _("New Event") date_begin = datetime.today() + timedelta(days=(14)) @@ -189,7 +187,7 @@ class WebsiteEventController(http.Controller): 'date_end': fields.Date.to_string((date_begin + timedelta(days=(1)))), 'seats_available': 1000, } - return request.env['event.event'].with_context(context).create(vals) + return request.env['event.event'].with_context(context or {}).create(vals) def get_formated_date(self, event): start_date = fields.Datetime.from_string(event.date_begin).date() diff --git a/addons/website_event_sale/controllers/main.py b/addons/website_event_sale/controllers/main.py index 3b35337b250..9ddb85f7bb7 100644 --- a/addons/website_event_sale/controllers/main.py +++ b/addons/website_event_sale/controllers/main.py @@ -55,15 +55,13 @@ class WebsiteEventSaleController(WebsiteEventController): return request.redirect("/shop/checkout") def _add_event(self, event_name="New Event", context=None, **kwargs): - if context is None: - context = {} product = request.env.ref('event_sale.product_product_event', raise_if_not_found=False) if product: - context['default_event_ticket_ids'] = [[0, 0, { + context = dict(context or {}, default_event_ticket_ids=[[0, 0, { 'name': _('Registration'), 'product_id': product.id, 'deadline': False, 'seats_max': 1000, 'price': 0, - }]] + }]]) return super(WebsiteEventSaleController, self)._add_event(event_name, context, **kwargs) diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 54ed985928f..a756173183e 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -205,7 +205,7 @@ class WebsiteSale(http.Controller): else: pricelist = request.env['product.pricelist'].browse(pricelist_context['pricelist']) - request.env = request.env(context=dict(request.env.context, pricelist=pricelist.id, partner=request.env.user.partner_id)) + request.context = dict(request.context, pricelist=pricelist.id, partner=request.env.user.partner_id) url = "/shop" if search: diff --git a/openerp/http.py b/openerp/http.py index 12f68b4725f..7e14b5d857c 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -47,7 +47,7 @@ import openerp from openerp.service.server import memory_info from openerp.service import security, model as service_model from openerp.tools.func import lazy_property -from openerp.tools import ustr, consteq +from openerp.tools import ustr, consteq, frozendict _logger = logging.getLogger(__name__) rpc_request = logging.getLogger(__name__ + '.rpc.request') @@ -186,11 +186,13 @@ class WebRequest(object): self.httprequest = httprequest self.httpresponse = None self.disable_db = False - self.uid = None self.endpoint = None self.endpoint_arguments = None self.auth_method = None self._cr = None + self._uid = None + self._context = None + self._env = None # prevents transaction commit, use when you catch an exception during handling self._failed = None @@ -202,43 +204,9 @@ class WebRequest(object): if self.session.uid: threading.current_thread().uid = self.session.uid - @lazy_property - def env(self): - """ - The :class:`~openerp.api.Environment` bound to current request. - Raises a :class:`RuntimeError` if the current requests is not bound - to a database. - """ - if not self.db: - raise RuntimeError('request not bound to a database') - return openerp.api.Environment(self.cr, self.uid, self.context) - - @lazy_property - def context(self): - """ - :class:`~collections.Mapping` of context values for the current - request - """ - return dict(self.session.context) - - @lazy_property - def lang(self): - self.session._fix_lang(self.context) - return self.context["lang"] - - @lazy_property - def session(self): - """ - a :class:`OpenERPSession` holding the HTTP session data for the - current http session - """ - return self.httprequest.session - @property def cr(self): - """ - :class:`~openerp.sql_db.Cursor` initialized for the current method - call. + """ :class:`~openerp.sql_db.Cursor` initialized for the current method call. Accessing the cursor when the current request uses the ``none`` authentication will raise an exception. @@ -251,6 +219,48 @@ class WebRequest(object): self._cr = self.registry.cursor() return self._cr + @property + def uid(self): + return self._uid + + @uid.setter + def uid(self, val): + self._uid = val + self._env = None + + @property + def context(self): + """ :class:`~collections.Mapping` of context values for the current request """ + if self._context is None: + self._context = frozendict(self.session.context) + return self._context + + @context.setter + def context(self, val): + self._context = frozendict(val) + self._env = None + + @property + def env(self): + """ The :class:`~openerp.api.Environment` bound to current request. """ + if self._env is None: + self._env = openerp.api.Environment(self.cr, self.uid, self.context) + return self._env + + @lazy_property + def lang(self): + context = dict(self.context) + self.session._fix_lang(context) + self.context = context + return context["lang"] + + @lazy_property + def session(self): + """ :class:`OpenERPSession` holding the HTTP session data for the + current http session + """ + return self.httprequest.session + def __enter__(self): _request_stack.push(self) return self @@ -270,12 +280,10 @@ class WebRequest(object): # is this needed ? arguments = dict((k, v) for k, v in arguments.iteritems() if not k.startswith("_ignored_")) - self.endpoint_arguments = arguments self.endpoint = endpoint self.auth_method = auth - def _handle_exception(self, exception): """Called within an except block to allow converting exceptions to abitrary responses. Anything returned (except None) will