[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/
This commit is contained in:
Christophe Simonis
2018-04-16 11:20:39 +02:00
parent 8c0b23c239
commit 264398de3e
2 changed files with 68 additions and 13 deletions
+60
View File
@@ -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)
+8 -13
View File
@@ -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):