]>
Commit | Line | Data |
---|---|---|
940227cb MT |
1 | #!/usr/bin/python |
2 | ||
638e9782 MT |
3 | import re |
4 | ||
940227cb | 5 | from databases import Databases |
0673d1b0 | 6 | from memcached import Memcached |
940227cb MT |
7 | from misc import Singleton |
8 | ||
9 | class GeoIP(object): | |
10 | __metaclass__ = Singleton | |
11 | ||
638e9782 MT |
12 | def __init__(self): |
13 | self.__country_codes = self.db.query("SELECT code, name FROM iso3166_countries") | |
14 | ||
940227cb MT |
15 | @property |
16 | def db(self): | |
17 | return Databases().geoip | |
18 | ||
0673d1b0 MT |
19 | @property |
20 | def memcached(self): | |
21 | return Memcached() | |
22 | ||
940227cb | 23 | def __encode_ip(self, addr): |
65afea2f MT |
24 | # We get a tuple if there were proxy headers. |
25 | addr = addr.split(", ") | |
26 | if addr: | |
27 | addr = addr[-1] | |
28 | ||
940227cb MT |
29 | # ip is calculated as described in http://ipinfodb.com/ip_database.php |
30 | a1, a2, a3, a4 = addr.split(".") | |
31 | ||
32 | return int(((int(a1) * 256 + int(a2)) * 256 + int(a3)) * 256 + int(a4) + 100) | |
33 | ||
34 | def get_country(self, addr): | |
0673d1b0 MT |
35 | addr = self.__encode_ip(addr) |
36 | ||
37 | mem_id = "geoip-country-%s" % addr | |
38 | ret = self.memcached.get(mem_id) | |
39 | ||
40 | if not ret: | |
41 | ret = self.db.get("SELECT * FROM ip_group_country WHERE ip_start <= %s \ | |
42 | ORDER BY ip_start DESC LIMIT 1;", addr).country_code.lower() | |
43 | self.memcached.set(mem_id, ret, 3600) | |
44 | ||
45 | return ret | |
940227cb MT |
46 | |
47 | def get_all(self, addr): | |
0673d1b0 MT |
48 | addr = self.__encode_ip(addr) |
49 | ||
50 | mem_id = "geoip-all-%s" % addr | |
51 | ret = self.memcached.get(mem_id) | |
52 | ||
53 | if not ret: | |
54 | # XXX should be done with a join | |
55 | location = self.db.get("SELECT location FROM ip_group_city WHERE ip_start <= %s \ | |
56 | ORDER BY ip_start DESC LIMIT 1;", addr).location | |
57 | ||
58 | ret = self.db.get("SELECT * FROM locations WHERE id = %s", int(location)) | |
59 | self.memcached.set(mem_id, ret, 3600) | |
60 | ||
61 | # If location was not determinable | |
62 | if ret.latitude == 0 and ret.longitude == 0: | |
63 | return None | |
64 | ||
65 | return ret | |
940227cb | 66 | |
638e9782 MT |
67 | def get_country_name(self, code): |
68 | name = "Unknown" | |
69 | ||
70 | code = code.upper() | |
71 | for country in self.__country_codes: | |
72 | if country.code == code: | |
73 | name = country.name | |
74 | break | |
75 | ||
76 | # Fix some weird strings | |
77 | name = re.sub(r"(.*) (.* Republic of)", r"\2 \1", name) | |
78 | ||
79 | return name | |
80 | ||
940227cb MT |
81 | |
82 | if __name__ == "__main__": | |
83 | g = GeoIP() | |
84 | ||
85 | print g.get_country("123.123.123.123") | |
86 | print g.get_all("123.123.123.123") |