<commit_before># -*- coding: utf-8 -*-
import logging
import os
import re
import time
import traceback

import werkzeug
import werkzeug.routing
import werkzeug.utils

import openerp
from openerp.addons.base import ir
from openerp.addons.base.ir import ir_qweb
from openerp.addons.website.models.website import slug, url_for, _UNSLUG_RE
from openerp.http import request
from openerp.tools import config
from openerp.osv import orm

logger = logging.getLogger(__name__)

class RequestUID(object):
    def __init__(self, **kw):
        self.__dict__.update(kw)

class ir_http(orm.AbstractModel):
    _inherit = 'ir.http'

    rerouting_limit = 10
    _geoip_resolver = None

    def _get_converters(self):
        return dict(
            super(ir_http, self)._get_converters(),
            model=ModelConverter,
            page=PageConverter,
        )

    def _auth_method_public(self):
        if not request.session.uid:
            website = self.pool['website'].get_current_website(request.cr, openerp.SUPERUSER_ID, context=request.context)
            if website:
                request.uid = website.user_id.id
            else:
                request.uid = self.pool['ir.model.data'].xmlid_to_res_id(request.cr, openerp.SUPERUSER_ID, 'base', 'public_user')
        else:
            request.uid = request.session.uid

    bots = "bot|crawl|slurp|spider|curl|wget|facebookexternalhit".split("|")
    def is_a_bot(self):
        # We don't use regexp and ustr voluntarily
        # timeit has been done to check the optimum method
        ua = request.httprequest.environ.get('HTTP_USER_AGENT', '').lower()
        try:
            return any(bot in ua for bot in self.bots)
        except UnicodeDecodeError:
            return any(bot in ua.encode('ascii', 'ignore') for bot in self.bots)

    def get_nearest_lang(self, lang):
        # Try to find a similar lang. Eg: fr_BE and fr_FR
        if lang in request.website.get_languages():
            return lang

        short = lang.split('_')[0]
        for code, name in request.website.get_languages():
            if code.startswith(short):
                return code
        return False

    def _geoip_setup_resolver(self):
        if self._geoip_resolver is None:
            try:
                import GeoIP
                # updated database can be downloaded on MaxMind website
                # http://dev.maxmind.com/geoip/legacy/install/city/
                geofile = config.get('geoip_database')
                if os.path.exists(geofile):
                    self._geoip_resolver = GeoIP.open(geofile, GeoIP.GEOIP_STANDARD)
                else:
                    self._geoip_resolver = False
                    logger.warning('GeoIP database file %r does not exists', geofile)
            except ImportError:
                self._geoip_resolver = False

    def _geoip_resolve(self):
        if 'geoip' not in request.session:
            record = {}
            if self._geoip_resolver and request.httprequest.remote_addr:
                record = self._geoip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
            request.session['geoip'] = record

    def _dispatch(self):
        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()

        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.registry['website'].get_current_website(request.cr, request.uid, context=request.context)
            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:
                    path.pop(1)
                    return self.reroute('/'.join(path) or '/')

            if not request.context.get('tz'):
                request.context['tz'] = request.session['geoip'].get('time_zone')
            # bind modified context
            request.website = request.website.with_context(request.context)

        # cache for auth public
        cache_time = func.routing.get('cache')
        cache_enable = cache_time and request.httprequest.method == "GET" and request.website.user_id.id == request.uid
        cache_response = None
        if cache_enable:
            key = (self._name, "cache", request.uid, request.httprequest.full_path)
            try:
                r = self.pool.cache[key]
                if r['time'] + cache_time > time.time():
                    cache_response = openerp.http.Response(r['content'], mimetype=r['mimetype'])
                else:
                    del self.pool.cache[key]
            except KeyError:
                pass

        if cache_response:
            request.cache_save = False
            resp = cache_response
        else:
            request.cache_save = key if cache_enable else False
            resp = super(ir_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

    def reroute(self, path):<commit_msg>[FIX] website: http cache some handler dont have routing<commit_after># -*- coding: utf-8 -*-
import logging
import os
import re
import time
import traceback

import werkzeug
import werkzeug.routing
import werkzeug.utils

import openerp
from openerp.addons.base import ir
from openerp.addons.base.ir import ir_qweb
from openerp.addons.website.models.website import slug, url_for, _UNSLUG_RE
from openerp.http import request
from openerp.tools import config
from openerp.osv import orm

logger = logging.getLogger(__name__)

class RequestUID(object):
    def __init__(self, **kw):
        self.__dict__.update(kw)

class ir_http(orm.AbstractModel):
    _inherit = 'ir.http'

    rerouting_limit = 10
    _geoip_resolver = None

    def _get_converters(self):
        return dict(
            super(ir_http, self)._get_converters(),
            model=ModelConverter,
            page=PageConverter,
        )

    def _auth_method_public(self):
        if not request.session.uid:
            website = self.pool['website'].get_current_website(request.cr, openerp.SUPERUSER_ID, context=request.context)
            if website:
                request.uid = website.user_id.id
            else:
                request.uid = self.pool['ir.model.data'].xmlid_to_res_id(request.cr, openerp.SUPERUSER_ID, 'base', 'public_user')
        else:
            request.uid = request.session.uid

    bots = "bot|crawl|slurp|spider|curl|wget|facebookexternalhit".split("|")
    def is_a_bot(self):
        # We don't use regexp and ustr voluntarily
        # timeit has been done to check the optimum method
        ua = request.httprequest.environ.get('HTTP_USER_AGENT', '').lower()
        try:
            return any(bot in ua for bot in self.bots)
        except UnicodeDecodeError:
            return any(bot in ua.encode('ascii', 'ignore') for bot in self.bots)

    def get_nearest_lang(self, lang):
        # Try to find a similar lang. Eg: fr_BE and fr_FR
        if lang in request.website.get_languages():
            return lang

        short = lang.split('_')[0]
        for code, name in request.website.get_languages():
            if code.startswith(short):
                return code
        return False

    def _geoip_setup_resolver(self):
        if self._geoip_resolver is None:
            try:
                import GeoIP
                # updated database can be downloaded on MaxMind website
                # http://dev.maxmind.com/geoip/legacy/install/city/
                geofile = config.get('geoip_database')
                if os.path.exists(geofile):
                    self._geoip_resolver = GeoIP.open(geofile, GeoIP.GEOIP_STANDARD)
                else:
                    self._geoip_resolver = False
                    logger.warning('GeoIP database file %r does not exists', geofile)
            except ImportError:
                self._geoip_resolver = False

    def _geoip_resolve(self):
        if 'geoip' not in request.session:
            record = {}
            if self._geoip_resolver and request.httprequest.remote_addr:
                record = self._geoip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
            request.session['geoip'] = record

    def _dispatch(self):
        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()

        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.registry['website'].get_current_website(request.cr, request.uid, context=request.context)
            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:
                    path.pop(1)
                    return self.reroute('/'.join(path) or '/')

            if not request.context.get('tz'):
                request.context['tz'] = request.session['geoip'].get('time_zone')
            # bind modified context
            request.website = request.website.with_context(request.context)

        # cache for auth public
        cache_time = getattr(func, 'routing', {}).get('cache')
        cache_enable = cache_time and request.httprequest.method == "GET" and request.website.user_id.id == request.uid
        cache_response = None
        if cache_enable:
            key = (self._name, "cache", request.uid, request.httprequest.full_path)
            try:
                r = self.pool.cache[key]
                if r['time'] + cache_time > time.time():
                    cache_response = openerp.http.Response(r['content'], mimetype=r['mimetype'])
                else:
                    del self.pool.cache[key]
            except KeyError:
                pass

        if cache_response:
            request.cache_save = False
            resp = cache_response
        else:
            request.cache_save = key if cache_enable else False
            resp = super(ir_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

    def reroute(self, path):
{'fraction_non_alphanumeric': 0.09261885675525683, 'fraction_numerical': 0.002343220077696245, 'mean_word_length': 1.9540983606557376, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7368748', 'n_tokens_mistral': 4625, 'n_tokens_neox': 4360, 'n_words': 1069}