def _dispatch(cls): """ Before executing the endpoint method, add website params on request, such as - current website (record) - multilang support (set on cookies) - geoip dict data are added in the session Then follow the parent dispatching. Reminder : Do not use `request.env` before authentication phase, otherwise the env set on request will be created with uid=None (and it is a lazy property) """ first_pass = not hasattr(request, 'website') request.website = None func = None # add signup token or login to the session if given if 'auth_signup_token' in request.params: request.session['auth_signup_token'] = request.params[ 'auth_signup_token'] if 'auth_login' in request.params: request.session['auth_login'] = request.params['auth_login'] try: if request.httprequest.method == 'GET' and '//' in request.httprequest.path: new_url = request.httprequest.path.replace( '//', '/') + '?' + request.httprequest.query_string return werkzeug.utils.redirect(new_url, 301) func, arguments = cls._find_handler() request.website_enabled = func.routing.get('website', False) except werkzeug.exceptions.NotFound: # either we have a language prefixed route, either a real 404 # in all cases, website processes them request.website_enabled = True request.website_multilang = ( request.website_enabled and func and func.routing.get('multilang', func.routing['type'] == 'http')) cls._geoip_setup_resolver() cls._geoip_resolve() # For website routes (only), add website params on `request` cook_lang = request.httprequest.cookies.get('website_lang') if request.website_enabled: try: if func: cls._authenticate(func.routing['auth']) elif request.uid is None: cls._auth_method_public() except Exception as e: return cls._handle_exception(e) 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 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: is_a_bot = cls.is_a_bot() nearest_lang = not func and cls.get_nearest_lang(path[1]) url_lang = nearest_lang and path[1] preferred_lang = ((cook_lang if cook_lang in langs else False) or (not is_a_bot and cls.get_nearest_lang(request.lang)) or request.website.default_lang_code) 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 # and not a bot or bot but default lang in url if ((url_lang and (url_lang != request.lang or url_lang == request.website.default_lang_code)) or (not url_lang and request.website_multilang and request.lang != request.website.default_lang_code) and request.httprequest.method != 'POST') \ and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)): if url_lang: path.pop(1) if request.lang != request.website.default_lang_code: path.insert(1, request.lang) path = '/'.join(path) or '/' request.context = context redirect = request.redirect( path + '?' + request.httprequest.query_string) redirect.set_cookie('website_lang', request.lang) return redirect elif url_lang: request.uid = None path.pop(1) request.context = context return cls.reroute('/'.join(path) or '/') if request.lang == request.website.default_lang_code: context['edit_translations'] = False if not context.get('tz'): context['tz'] = request.session.get('geoip', {}).get('time_zone') # bind modified context request.context = context request.website = request.website.with_context(context) # removed cache for auth public request.cache_save = False resp = super(Http, cls)._dispatch() if request.website_enabled and cook_lang != request.lang and hasattr( resp, 'set_cookie'): resp.set_cookie('website_lang', request.lang) return resp
def _dispatch(self): """ Before executing the endpoint method, add website params on request, such as - current website (record) - multilang support (set on cookies) - geoip dict data are added in the session Then follow the parent dispatching. Reminder : Do not use `request.env` before authentication phase, otherwise the env set on request will be created with uid=None (and it is a lazy property) """ first_pass = not hasattr(request, 'website') request.website = None func = None try: if request.httprequest.method == 'GET' and '//' in request.httprequest.path: new_url = request.httprequest.path.replace('//', '/') + '?' + request.httprequest.query_string return werkzeug.utils.redirect(new_url, 301) func, arguments = self._find_handler() request.website_enabled = func.routing.get('website', False) except werkzeug.exceptions.NotFound: # either we have a language prefixed route, either a real 404 # in all cases, website processes them request.website_enabled = True request.website_multilang = ( request.website_enabled and func and func.routing.get('multilang', func.routing['type'] == 'http') ) self._geoip_setup_resolver() self._geoip_resolve() # For website routes (only), add website params on `request` cook_lang = request.httprequest.cookies.get('website_lang') if request.website_enabled: try: if func: self._authenticate(func.routing['auth']) elif request.uid is None: self._auth_method_public() except Exception as e: return self._handle_exception(e) 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 langs = [lg[0] for lg in request.website.get_languages()] path = request.httprequest.path.split('/') if first_pass: nearest_lang = not func and self.get_nearest_lang(path[1]) url_lang = nearest_lang and path[1] preferred_lang = ((cook_lang if cook_lang in langs else False) or self.get_nearest_lang(request.lang) or request.website.default_lang_code) is_a_bot = self.is_a_bot() request.lang = request.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 # and not a bot or bot but default lang in url if ((url_lang and (url_lang != request.lang or url_lang == request.website.default_lang_code)) or (not url_lang and request.website_multilang and request.lang != request.website.default_lang_code) and request.httprequest.method != 'POST') \ and (not is_a_bot or (url_lang and url_lang == request.website.default_lang_code)): if url_lang: path.pop(1) if request.lang != request.website.default_lang_code: path.insert(1, request.lang) path = '/'.join(path) or '/' redirect = request.redirect(path + '?' + request.httprequest.query_string) redirect.set_cookie('website_lang', request.lang) return redirect elif url_lang: request.uid = None path.pop(1) 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') # bind modified context request.website = request.website.with_context(request.context) # removed cache for auth public request.cache_save = False resp = super(Http, self)._dispatch() if request.website_enabled and cook_lang != request.lang and hasattr(resp, 'set_cookie'): resp.set_cookie('website_lang', request.lang) return resp