]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blobdiff - webapp/backend/geoip.py
Major update of the webapp.
[people/shoehn/ipfire.org.git] / webapp / backend / geoip.py
index 43f92da3acf57d59dff1b65eaa7ca489f3973327..0fe4310face8e05a3431c37a1917c5e0d3ec8bb3 100644 (file)
@@ -1,93 +1,76 @@
 #!/usr/bin/python
 
+import IPy
 import re
 
-from databases import Databases
-from memcached import Memcached
-from misc import Singleton
+import countries
 
-class GeoIP(object):
-       __metaclass__ = Singleton
+from misc import Object
 
-       @property
-       def db(self):
-               return Databases().geoip
+class GeoIP(Object):
+       def guess_address_family(self, addr):
+               if ":" in addr:
+                       return 6
 
-       def _encode_ip(self, addr):
-               # We get a tuple if there were proxy headers.
-               addr = addr.split(", ")
-               if addr:
-                       addr = addr[-1]
+               return 4
 
-               # ip is calculated as described in http://dev.maxmind.com/geoip/csv
-               a1, a2, a3, a4 = addr.split(".")
+       def get_country(self, addr):
+               ret = self.get_all(addr)
 
-               try:
-                       a1 = int(a1)
-                       a2 = int(a2)
-                       a3 = int(a3)
-                       a4 = int(a4)
-               except ValueError:
-                       return 0
+               if ret:
+                       return ret.country
 
-               return (16777216 * a1) + (65536 * a2) + (256 * a3) + a4
+       def get_location(self, addr):
+               family = self.guess_address_family(addr)
 
-       def get_country(self, addr):
-               addr = self._encode_ip(addr)
+               if family == 6:
+                       query = "SELECT *, NULL AS city, NULL AS postal_code FROM geoip_ipv6 WHERE %s \
+                               BETWEEN start_ip AND end_ip LIMIT 1"
+               elif family == 4:
+                       query = "SELECT * FROM geoip_ipv4 WHERE inet_to_bigint(%s) \
+                               BETWEEN start_ip AND end_ip LIMIT 1"
 
-               ret = self.db.get("SELECT locations.country_code AS country_code FROM addresses \
-                       JOIN locations ON locations.id = addresses.location \
-                       WHERE %s BETWEEN start_ip_num AND end_ip_num LIMIT 1", addr)
+               return self.db.get(query, addr)
 
-               if ret:
-                       return ret.country_code
+       def get_asn(self, addr):
+               family = self.guess_address_family(addr)
 
-       def get_all(self, addr):
-               addr = self._encode_ip(addr)
-               if not addr:
-                       return
+               if family == 6:
+                       query = "SELECT asn FROM geoip_asnv6 WHERE %s \
+                               BETWEEN start_ip AND end_ip LIMIT 1"
+               elif family == 4:
+                       query = "SELECT asn FROM geoip_asnv4 WHERE inet_to_bigint(%s) \
+                               BETWEEN start_ip AND end_ip LIMIT 1"
 
-               ret = self.db.get("SELECT locations.* FROM addresses \
-                       JOIN locations ON locations.id = addresses.location \
-                       WHERE %s BETWEEN start_ip_num AND end_ip_num LIMIT 1", addr)
+               ret = self.db.get(query, addr)
 
-               if not ret:
-                       return
+               if ret:
+                       return ret.asn
 
-               # If location was not determinable
-               if ret.latitude == 0 and ret.longitude == 0:
-                       return None
+       def get_all(self, addr):
+               location = self.get_location(addr)
 
-               return ret
+               if location:
+                       location["asn"] = self.get_asn(addr)
 
-       def get_country_name(self, code):
-               name = "Unkown"
+               return location
 
-               codes = {
-                       "A1" : "Anonymous Proxy",
-                       "A2" : "Satellite Provider",
-                       "EU" : "Europe",
-                       "AP" : "Asia/Pacific Region",
-               }
+       _countries = {
+               "A1" : "Anonymous Proxy",
+               "A2" : "Satellite Provider",
+               "AP" : "Asia/Pacific Region",
+               "EU" : "Europe",
+       }
 
+       def get_country_name(self, code):
                # Return description of some exceptional codes.
                try:
-                       return codes[code]
+                       return self._countries[code]
                except KeyError:
                        pass
 
-               ret = self.db.get("SELECT name FROM iso3166_countries WHERE code = %s LIMIT 1", code)
-               if ret:
-                       name = ret.name
-
-               # Fix some weird strings
-               name = re.sub(r"(.*) (.* Republic of)", r"\2 \1", name)
-
-               return name
-
-
-if __name__ == "__main__":
-       g = GeoIP()
+               country = countries.get_by_code(code)
+               if not country:
+                       return code
 
-       print g.get_country("123.123.123.123")
-       print g.get_all("123.123.123.123")
+               return country