Ticket #18349: django_ipv6_geoip.3.patch

File django_ipv6_geoip.3.patch, 6.1 KB (added by j@…, 12 years ago)

version that has tests and works

  • django/contrib/gis/geoip/base.py

    diff --git a/django/contrib/gis/geoip/base.py b/django/contrib/gis/geoip/base.py
    index e00e0a4..6bca923 100644
    a b import re  
    33from ctypes import c_char_p
    44
    55from django.core.validators import ipv4_re
     6from django.utils.ipv6 import is_valid_ipv6_address
    67from django.contrib.gis.geoip.libgeoip import GEOIP_SETTINGS
    78from django.contrib.gis.geoip.prototypes import (
    89    GeoIPRecord, GeoIPTag, GeoIP_open, GeoIP_delete, GeoIP_database_info,
    910    GeoIP_lib_version, GeoIP_record_by_addr, GeoIP_record_by_name,
    1011    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)
    1215
    1316# Regular expressions for recognizing the GeoIP free database editions.
    1417free_regex = re.compile(r'^GEO-\d{3}FREE')
    class GeoIP(object):  
    4649
    4750    # Paths to the city & country binary databases.
    4851    _city_file = ''
     52    _city6_file = ''
    4953    _country_file = ''
     54    _country6_file = ''
    5055
    5156    # Initially, pointers to GeoIP file references are NULL.
    5257    _city = None
     58    _city6 = None
    5359    _country = None
     60    _country6 = None
    5461
    5562    def __init__(self, path=None, cache=0, country=None, city=None):
    5663        """
    class GeoIP(object):  
    98105                self._country = GeoIP_open(country_db, cache)
    99106                self._country_file = country_db
    100107
     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
    101113            city_db = os.path.join(path, city or GEOIP_SETTINGS.get('GEOIP_CITY', 'GeoLiteCity.dat'))
    102114            if os.path.isfile(city_db):
    103115                self._city = GeoIP_open(city_db, cache)
    104116                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
    105122        elif os.path.isfile(path):
    106123            # Otherwise, some detective work will be needed to figure
    107124            # out whether the given database path is for the GeoIP country
    class GeoIP(object):  
    124141    def __del__(self):
    125142        # Cleaning any GeoIP file handles lying around.
    126143        if self._country: GeoIP_delete(self._country)
     144        if self._country6: GeoIP_delete(self._country6)
    127145        if self._city: GeoIP_delete(self._city)
     146        if self._city6: GeoIP_delete(self._city6)
    128147
    129148    def _check_query(self, query, country=False, city=False, city_or_country=False):
    130149        "Helper routine for checking the query and database availability."
    class GeoIP(object):  
    156175        if ipv4_re.match(query):
    157176            # If an IP address was passed in
    158177            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))
    159181        else:
    160182            # If a FQDN was passed in.
    161183            return GeoIP_record_by_name(self._city, c_char_p(query))
    class GeoIP(object):  
    163185    def country_code(self, query):
    164186        "Returns the country code for the given IP Address or FQDN."
    165187        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:
    167191            if ipv4_re.match(query):
    168192                return GeoIP_country_code_by_addr(self._country, query)
    169193            else:
    class GeoIP(object):  
    174198    def country_name(self, query):
    175199        "Returns the country name for the given IP Address or FQDN."
    176200        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:
    178204            if ipv4_re.match(query):
    179205                return GeoIP_country_name_by_addr(self._country, query)
    180206            else:
  • django/contrib/gis/geoip/prototypes.py

    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):  
    7373    return func
    7474GeoIP_record_by_addr = record_output(lgeoip.GeoIP_record_by_addr)
    7575GeoIP_record_by_name = record_output(lgeoip.GeoIP_record_by_name)
     76GeoIP_record_by_addr_v6 = record_output(lgeoip.GeoIP_record_by_addr_v6)
    7677
    7778
    7879# For opening & closing GeoIP database files.
    GeoIP_country_code_by_addr = string_output(lgeoip.GeoIP_country_code_by_addr)  
    107108GeoIP_country_code_by_name = string_output(lgeoip.GeoIP_country_code_by_name)
    108109GeoIP_country_name_by_addr = string_output(lgeoip.GeoIP_country_name_by_addr)
    109110GeoIP_country_name_by_name = string_output(lgeoip.GeoIP_country_name_by_name)
     111GeoIP_country_code_by_addr_v6 = string_output(lgeoip.GeoIP_country_code_by_addr_v6)
     112GeoIP_country_name_by_addr_v6 = string_output(lgeoip.GeoIP_country_name_by_addr_v6)
  • django/contrib/gis/geoip/tests.py

    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):  
    107107        d = g.country(u'whitehouse.gov')
    108108        self.assertEqual(u'US', d['country_code'])
    109109
     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)
    110115
    111116def suite():
    112117    s = unittest.TestSuite()
Back to Top