From 264398de3eb2e11c692bc5cfc98c13c235d6c53e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 3 Apr 2018 12:03:39 +0200 Subject: [PATCH 1/3] [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/3] [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) From aaadfd7d768e6271afc287cea2de19c769aa786a Mon Sep 17 00:00:00 2001 From: Kirti Choudhary Date: Fri, 9 Mar 2018 18:43:03 +0530 Subject: [PATCH 3/3] [FIX] sale: income account in invoice with down payments When creating an invoice with 'Down payment' option for an SO, it should first consider income account of the 'Deposit Product'. if it does not have one then it should consider that product category's income account. Fixes #23100 Task# 1819531 --- addons/sale/wizard/sale_make_invoice_advance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index eca97519e48..ee304b8881e 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -65,7 +65,7 @@ class SaleAdvancePaymentInv(models.TransientModel): account_id = False if self.product_id.id: - account_id = self.product_id.property_account_income_id.id + account_id = self.product_id.property_account_income_id.id or self.product_id.categ_id.property_account_income_categ_id.id if not account_id: inc_acc = ir_property_obj.get('property_account_income_categ_id', 'product.category') account_id = order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False