diff --git a/django/contrib/gis/geoip/base.py b/django/contrib/gis/geoip/base.py
index e00e0a4..6bca923 100644
|
a
|
b
|
import re
|
| 3 | 3 | from ctypes import c_char_p |
| 4 | 4 | |
| 5 | 5 | from django.core.validators import ipv4_re |
| | 6 | from django.utils.ipv6 import is_valid_ipv6_address |
| 6 | 7 | from django.contrib.gis.geoip.libgeoip import GEOIP_SETTINGS |
| 7 | 8 | from django.contrib.gis.geoip.prototypes import ( |
| 8 | 9 | GeoIPRecord, GeoIPTag, GeoIP_open, GeoIP_delete, GeoIP_database_info, |
| 9 | 10 | GeoIP_lib_version, GeoIP_record_by_addr, GeoIP_record_by_name, |
| 10 | 11 | GeoIP_country_code_by_addr, GeoIP_country_code_by_name, |
| 11 | | GeoIP_country_name_by_addr, GeoIP_country_name_by_name) |
| | 12 | GeoIP_country_name_by_addr, GeoIP_country_name_by_name, |
| | 13 | GeoIP_country_code_by_addr_v6, GeoIP_country_name_by_addr_v6, |
| | 14 | GeoIP_record_by_addr_v6) |
| 12 | 15 | |
| 13 | 16 | # Regular expressions for recognizing the GeoIP free database editions. |
| 14 | 17 | free_regex = re.compile(r'^GEO-\d{3}FREE') |
| … |
… |
class GeoIP(object):
|
| 46 | 49 | |
| 47 | 50 | # Paths to the city & country binary databases. |
| 48 | 51 | _city_file = '' |
| | 52 | _city6_file = '' |
| 49 | 53 | _country_file = '' |
| | 54 | _country6_file = '' |
| 50 | 55 | |
| 51 | 56 | # Initially, pointers to GeoIP file references are NULL. |
| 52 | 57 | _city = None |
| | 58 | _city6 = None |
| 53 | 59 | _country = None |
| | 60 | _country6 = None |
| 54 | 61 | |
| 55 | 62 | def __init__(self, path=None, cache=0, country=None, city=None): |
| 56 | 63 | """ |
| … |
… |
class GeoIP(object):
|
| 98 | 105 | self._country = GeoIP_open(country_db, cache) |
| 99 | 106 | self._country_file = country_db |
| 100 | 107 | |
| | 108 | country6_db = os.path.join(path, country or GEOIP_SETTINGS.get('GEOIP_COUNTRY6', 'GeoIPv6.dat')) |
| | 109 | if os.path.isfile(country6_db): |
| | 110 | self._country6 = GeoIP_open(country6_db, cache) |
| | 111 | self._country6_file = country6_db |
| | 112 | |
| 101 | 113 | city_db = os.path.join(path, city or GEOIP_SETTINGS.get('GEOIP_CITY', 'GeoLiteCity.dat')) |
| 102 | 114 | if os.path.isfile(city_db): |
| 103 | 115 | self._city = GeoIP_open(city_db, cache) |
| 104 | 116 | self._city_file = city_db |
| | 117 | |
| | 118 | city6_db = os.path.join(path, city or GEOIP_SETTINGS.get('GEOIP_CITY6', 'GeoLiteCityv6.dat')) |
| | 119 | if os.path.isfile(city6_db): |
| | 120 | self._city6 = GeoIP_open(city6_db, cache) |
| | 121 | self._city6_file = city6_db |
| 105 | 122 | elif os.path.isfile(path): |
| 106 | 123 | # Otherwise, some detective work will be needed to figure |
| 107 | 124 | # out whether the given database path is for the GeoIP country |
| … |
… |
class GeoIP(object):
|
| 124 | 141 | def __del__(self): |
| 125 | 142 | # Cleaning any GeoIP file handles lying around. |
| 126 | 143 | if self._country: GeoIP_delete(self._country) |
| | 144 | if self._country6: GeoIP_delete(self._country6) |
| 127 | 145 | if self._city: GeoIP_delete(self._city) |
| | 146 | if self._city6: GeoIP_delete(self._city6) |
| 128 | 147 | |
| 129 | 148 | def _check_query(self, query, country=False, city=False, city_or_country=False): |
| 130 | 149 | "Helper routine for checking the query and database availability." |
| … |
… |
class GeoIP(object):
|
| 156 | 175 | if ipv4_re.match(query): |
| 157 | 176 | # If an IP address was passed in |
| 158 | 177 | return GeoIP_record_by_addr(self._city, c_char_p(query)) |
| | 178 | elif is_valid_ipv6_address(query) and self._city6: |
| | 179 | # If an IPv6 address was passed in |
| | 180 | return GeoIP_record_by_addr_v6(self._city6, c_char_p(query)) |
| 159 | 181 | else: |
| 160 | 182 | # If a FQDN was passed in. |
| 161 | 183 | return GeoIP_record_by_name(self._city, c_char_p(query)) |
| … |
… |
class GeoIP(object):
|
| 163 | 185 | def country_code(self, query): |
| 164 | 186 | "Returns the country code for the given IP Address or FQDN." |
| 165 | 187 | query = self._check_query(query, city_or_country=True) |
| 166 | | if self._country: |
| | 188 | if self._country6 and is_valid_ipv6_address(query): |
| | 189 | return GeoIP_country_code_by_addr_v6(self._country6, query) |
| | 190 | elif self._country: |
| 167 | 191 | if ipv4_re.match(query): |
| 168 | 192 | return GeoIP_country_code_by_addr(self._country, query) |
| 169 | 193 | else: |
| … |
… |
class GeoIP(object):
|
| 174 | 198 | def country_name(self, query): |
| 175 | 199 | "Returns the country name for the given IP Address or FQDN." |
| 176 | 200 | query = self._check_query(query, city_or_country=True) |
| 177 | | if self._country: |
| | 201 | if self._country6 and is_valid_ipv6_address(query): |
| | 202 | return GeoIP_country_name_by_addr_v6(self._country6, query) |
| | 203 | elif self._country: |
| 178 | 204 | if ipv4_re.match(query): |
| 179 | 205 | return GeoIP_country_name_by_addr(self._country, query) |
| 180 | 206 | else: |
diff --git a/django/contrib/gis/geoip/prototypes.py b/django/contrib/gis/geoip/prototypes.py
index 1cec0d5..d74ca3e 100644
|
a
|
b
|
def record_output(func):
|
| 73 | 73 | return func |
| 74 | 74 | GeoIP_record_by_addr = record_output(lgeoip.GeoIP_record_by_addr) |
| 75 | 75 | GeoIP_record_by_name = record_output(lgeoip.GeoIP_record_by_name) |
| | 76 | GeoIP_record_by_addr_v6 = record_output(lgeoip.GeoIP_record_by_addr_v6) |
| 76 | 77 | |
| 77 | 78 | |
| 78 | 79 | # For opening & closing GeoIP database files. |
| … |
… |
GeoIP_country_code_by_addr = string_output(lgeoip.GeoIP_country_code_by_addr)
|
| 107 | 108 | GeoIP_country_code_by_name = string_output(lgeoip.GeoIP_country_code_by_name) |
| 108 | 109 | GeoIP_country_name_by_addr = string_output(lgeoip.GeoIP_country_name_by_addr) |
| 109 | 110 | GeoIP_country_name_by_name = string_output(lgeoip.GeoIP_country_name_by_name) |
| | 111 | GeoIP_country_code_by_addr_v6 = string_output(lgeoip.GeoIP_country_code_by_addr_v6) |
| | 112 | GeoIP_country_name_by_addr_v6 = string_output(lgeoip.GeoIP_country_name_by_addr_v6) |
diff --git a/django/contrib/gis/geoip/tests.py b/django/contrib/gis/geoip/tests.py
index 6e1f157..e3be454 100644
|
a
|
b
|
class GeoIPTest(unittest.TestCase):
|
| 107 | 107 | d = g.country(u'whitehouse.gov') |
| 108 | 108 | self.assertEqual(u'US', d['country_code']) |
| 109 | 109 | |
| | 110 | def test07_ipv6_query(self): |
| | 111 | "Testing that GeoIP can lookup ipv6 addresses." |
| | 112 | g = GeoIP() |
| | 113 | d = g.city('2a03:2880:2110:3f01:face:b00c::') |
| | 114 | self.assertNotEqual(d, None) |
| 110 | 115 | |
| 111 | 116 | def suite(): |
| 112 | 117 | s = unittest.TestSuite() |