From 264398de3eb2e11c692bc5cfc98c13c235d6c53e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 3 Apr 2018 12:03:39 +0200 Subject: [PATCH 1/2] [IMP] website: handle geoip2 databases Since April 1, 2018, free versions of GeoLite Legac y databases are no longer updated and free downloads not available [1]. [1] https://support.maxmind.com/geolite-legacy-discontinuation-notice/ --- addons/website/geoipresolver.py | 60 ++++++++++++++++++++++++++++++++ addons/website/models/ir_http.py | 21 +++++------ 2 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 addons/website/geoipresolver.py diff --git a/addons/website/geoipresolver.py b/addons/website/geoipresolver.py new file mode 100644 index 00000000000..1f9b0e22724 --- /dev/null +++ b/addons/website/geoipresolver.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os.path + +try: + import GeoIP # Legacy +except ImportError: + GeoIP = None + +try: + import geoip2 + import geoip2.database +except ImportError: + geoip2 = None + +class GeoIPResolver(object): + def __init__(self, fname): + self.fname = fname + try: + self._db = geoip2.database.Reader(fname) + self.version = 2 + except Exception: + try: + self._db = GeoIP.open(fname, GeoIP.GEOIP_STANDARD) + self.version = 1 + assert self._db.database_info is not None + except Exception: + raise ValueError('Invalid GeoIP database: %r' % fname) + + def __del__(self): + if self.version == 2: + self._db.close() + + @classmethod + def open(cls, fname): + if not GeoIP and not geoip2: + return None + if not os.path.exists(fname): + return None + return GeoIPResolver(fname) + + def resolve(self, ip): + if self.version == 1: + return self._db.record_by_addr(ip) or {} + elif self.version == 2: + try: + r = self._db.city(ip) + except (ValueError, geoip2.errors.AddressNotFoundError): + return {} + return { + 'city': r.city.name, + 'country_code': r.country.iso_code, + 'country_name': r.country.name, + 'region': r.subdivisions[0].iso_code if r.subdivisions else None, + 'time_zone': r.location.time_zone, + } + + # compat + def record_by_addr(self, addr): + return self.resolve(addr) diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 6b6f119fd88..70cb480c86d 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -14,10 +14,12 @@ 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.tools import config, ustr from openerp.osv import orm from openerp.tools.safe_eval import safe_eval as eval +from ..geoipresolver import GeoIPResolver + logger = logging.getLogger(__name__) class RequestUID(object): @@ -70,24 +72,17 @@ class ir_http(orm.AbstractModel): def _geoip_setup_resolver(self): if self._geoip_resolver is None: + geofile = config.get('geoip_database') 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, apt-get install geoip-database-contrib or download it from http://dev.maxmind.com/geoip/legacy/install/city/', geofile) - except ImportError: - self._geoip_resolver = False + self._geoip_resolver = GeoIPResolver.open(geofile) or False + except Exception as e: + logger.warning('Cannot load GeoIP: %s', ustr(e)) 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 {} + record = self._geoip_resolver.resolve(request.httprequest.remote_addr) or {} request.session['geoip'] = record def get_page_key(self): From 752dcc761caf15cb532b1e787e9a378a8112a6a4 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 3 Apr 2018 15:28:00 +0200 Subject: [PATCH 2/2] [IMP] core: load geoip2 database by default --- openerp/tools/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/tools/config.py b/openerp/tools/config.py index d1cbc306d88..60fa9c2d73d 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -251,7 +251,7 @@ class configmanager(object): type="int") group.add_option("--unaccent", dest="unaccent", my_default=False, action="store_true", help="Use the unaccent function provided by the database when available.") - group.add_option("--geoip-db", dest="geoip_database", my_default='/usr/share/GeoIP/GeoLiteCity.dat', + group.add_option("--geoip-db", dest="geoip_database", my_default='/usr/share/GeoIP/GeoLite2-City.mmdb', help="Absolute path to the GeoIP database file.") parser.add_option_group(group)