Merge lp:~cjwatson/launchpad/geoip2 into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 19031
Proposed branch: lp:~cjwatson/launchpad/geoip2
Merge into: lp:launchpad
Prerequisite: lp:~cjwatson/launchpad/geoip-country
Diff against target: 83 lines (+23/-9)
3 files modified
constraints.txt (+2/-0)
lib/lp/services/geoip/model.py (+20/-9)
setup.py (+1/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpad/geoip2
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+371095@code.launchpad.net

Commit message

Add optional geoip2 support.

Description of the change

We don't have a useful way to test this until the relevant data packages gain the right set of database files, but I've run the existing tests with modified configuration to point to a local download of GeoLite2-Country.mmdb and they pass.

Once we're using this, it will give us GeoIP support for IPv6 addresses.

https://code.launchpad.net/~cjwatson/lp-source-dependencies/+git/lp-source-dependencies/+merge/371094 and probably https://code.launchpad.net/~cjwatson/meta-lp-deps/geoip2/+merge/371092 should land first.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'constraints.txt'
2--- constraints.txt 2019-07-09 12:32:22 +0000
3+++ constraints.txt 2019-08-08 15:23:22 +0000
4@@ -262,6 +262,7 @@
5 fixtures==3.0.0
6 FormEncode==1.2.4
7 futures==3.2.0
8+geoip2==2.9.0
9 grokcore.component==1.6
10 gunicorn==19.8.1
11 html5browser==0.0.9
12@@ -299,6 +300,7 @@
13 manuel==1.7.2
14 Markdown==2.3.1
15 martian==0.11
16+maxminddb==1.4.1
17 meliae==0.2.0.final.0
18 mistune==0.8.3
19 mock==1.0.1
20
21=== modified file 'lib/lp/services/geoip/model.py'
22--- lib/lp/services/geoip/model.py 2019-08-08 15:22:41 +0000
23+++ lib/lp/services/geoip/model.py 2019-08-08 15:23:22 +0000
24@@ -10,6 +10,8 @@
25 import os
26
27 import GeoIP as libGeoIP
28+from geoip2.database import Reader
29+from geoip2.errors import AddressNotFoundError
30 from zope.component import getUtility
31 from zope.i18n.interfaces import IUserPreferredLanguages
32 from zope.interface import implementer
33@@ -38,20 +40,29 @@
34 if not os.path.exists(config.launchpad.geoip_database):
35 raise NoGeoIPDatabaseFound(
36 "No GeoIP DB found. Please install launchpad-dependencies.")
37- return libGeoIP.open(
38- config.launchpad.geoip_database, libGeoIP.GEOIP_MEMORY_CACHE)
39+ if config.launchpad.geoip_database.endswith('.mmdb'):
40+ return Reader(config.launchpad.geoip_database)
41+ else:
42+ return libGeoIP.open(
43+ config.launchpad.geoip_database, libGeoIP.GEOIP_MEMORY_CACHE)
44
45 def getCountryCodeByAddr(self, ip_address):
46 """See `IGeoIP`."""
47 if not ipaddress_is_global(ip_address):
48 return None
49- try:
50- return self._gi.country_code_by_addr(ip_address)
51- except SystemError:
52- # libGeoIP may raise a SystemError if it doesn't find a record for
53- # some IP addresses (e.g. 255.255.255.255), so we need to catch
54- # that and return None here.
55- return None
56+ if isinstance(self._gi, Reader):
57+ try:
58+ return self._gi.country(ip_address).country.iso_code
59+ except AddressNotFoundError:
60+ return None
61+ else:
62+ try:
63+ return self._gi.country_code_by_addr(ip_address)
64+ except SystemError:
65+ # libGeoIP may raise a SystemError if it doesn't find a
66+ # record for some IP addresses (e.g. 255.255.255.255), so we
67+ # need to catch that and return None here.
68+ return None
69
70 def getCountryByAddr(self, ip_address):
71 """See `IGeoIP`."""
72
73=== modified file 'setup.py'
74--- setup.py 2019-08-08 15:22:41 +0000
75+++ setup.py 2019-08-08 15:23:22 +0000
76@@ -161,6 +161,7 @@
77 'feedparser',
78 'feedvalidator',
79 'fixtures',
80+ 'geoip2',
81 'gunicorn[gthread]',
82 'html5browser',
83 'importlib-resources',