]> git.ipfire.org Git - ipfire.org.git/commitdiff
Use new geoip database.
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 29 Nov 2012 17:33:14 +0000 (18:33 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 29 Nov 2012 17:33:14 +0000 (18:33 +0100)
www/templates/mirrors-item.html
www/templates/mirrors.html
www/translations/webapp.pot
www/webapp/backend/geoip.py
www/webapp/backend/mirrors.py
www/webapp/handlers_mirrors.py

index 2cbb5c66a173e5740154351d64097bc27d7dffd3..cc375a2d7de6a6df774a283f190b4fc811ab0b90 100644 (file)
                </tr>
                {% if item.prefer_for_countries %}
                        <tr>
-                               <td>{{ _("Preferred for") }}:</td>
+                               <td>{{ _("Preferred for") }}</td>
                                <td>{{ locale.list(item.prefer_for_countries_names) }}</td>
                        </tr>
                {% end %}
+               {% if client_distance %}
+                       <tr>
+                               <td>{{ _("Your distance to this mirror") }}</td>
+                               <td>{{ "%.1f km" % client_distance }}</td>
+                       </tr>
+               {% end %}
        </table>
 
        <a class="btn pull-right" href="{{ item.url }}">{{ _("Go to mirror") }}</a>
        <p>
                {{ _("The mirror <em>%s</em> is located in %s.") % (item.hostname, item.location_str) }}
        </p>
-       <p>
-               <img class="map"
-                       src="http://maps.google.com/maps/api/staticmap?center={{ item.coordiante_str }}&size=640x280&zoom=6&markers=color:blue|label:.|{{ item.coordiante_str }}&sensor=false"
-                       alt="{{ _("Location of the server") }}" />
-       </p>
+
+       {% if item.longitude and item.latitude %}
+               <iframe width="100%" height="350" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"
+                       src="http://www.openstreetmap.org/export/embed.html?bbox={{ item.longitude - 4 }},{{ item.latitude - 4 }},{{ item.longitude + 4 }},{{ item.latitude + 4 }}&amp;layer=mapquest&amp;marker={{ item.latitude }},{{ item.longitude }}" style="border: 1px solid black">
+               </iframe>
+               <p>
+                       <a href="http://www.openstreetmap.org/?lat={{ item.latitude }}&amp;lon={{ item.longitude }}&amp;zoom=8&amp;layers=M&amp;mlat={{ item.latitude }}&amp;mlon={{ item.longitude }}" target="_blank">{{ _("View larger map") }}</a>
+                       -
+                       &copy; <a href="http://www.openstreetmap.org/" target="_blank">OpenStreetMap</a> contributors, CC-BY-SA
+               </p>
+               <p class="muted ac">
+                       {{ _("The location of the mirror server is estimated by the IP address.") }}
+               </p>
+       {% else %}
+               {{ _("The location of the mirror server could not be estimated.") }}
+       {% end %}
 {% end block %}
index 0e71908788319d0a50fcbf0cd562b2a28e290780..1937f80f6882afed68f56bf6be085bcfcbc777fc 100644 (file)
@@ -21,7 +21,7 @@
                </p>
        {% end %}
 
-       {% if other_mirrors %}
+       {% if preferred_mirrors %}
                <h2>{{ _("Mirror servers nearby") }}</h2>
                {{ modules.MirrorsTable(preferred_mirrors) }}
 
@@ -29,6 +29,6 @@
                {{ modules.MirrorsTable(other_mirrors) }}
        {% else %}
                <h2>{{ _("Worldwide mirror servers") }}</h2>
-               {{ modules.MirrorsTable(preferred_mirrors) }}
+               {{ modules.MirrorsTable(other_mirrors) }}
        {% end %}
 {% end block %}
index f7986937872776b5b504a57cf01fe85a34c518c2..8b7e827ba6aede8775626e46a40d0246a3ab7295 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-11-08 21:41+0100\n"
+"POT-Creation-Date: 2012-11-29 18:31+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -22,12 +22,12 @@ msgstr ""
 msgid "Wish"
 msgstr ""
 
-#: templates/wishlist/wish.html:16
+#: templates/wishlist/wish.html:18
 #, python-format
 msgid "Launched: %s"
 msgstr ""
 
-#: templates/wishlist/wish.html:20
+#: templates/wishlist/wish.html:23
 #, python-format
 msgid "Funding ends: %s"
 msgstr ""
@@ -203,18 +203,34 @@ msgid "Preferred for"
 msgstr ""
 
 #: templates/mirrors-item.html:37
+msgid "Your distance to this mirror"
+msgstr ""
+
+#: templates/mirrors-item.html:43
 msgid "Go to mirror"
 msgstr ""
 
-#: templates/mirrors-item.html:42
+#: templates/mirrors-item.html:48
 msgid "Mirror location"
 msgstr ""
 
-#: templates/mirrors-item.html:44
+#: templates/mirrors-item.html:50
 #, python-format
 msgid "The mirror <em>%s</em> is located in %s."
 msgstr ""
 
+#: templates/mirrors-item.html:58
+msgid "View larger map"
+msgstr ""
+
+#: templates/mirrors-item.html:63
+msgid "The location of the mirror server is estimated by the IP address."
+msgstr ""
+
+#: templates/mirrors-item.html:66
+msgid "The location of the mirror server could not be estimated."
+msgstr ""
+
 #: templates/admin-downloads-mirrors.html:5 templates/admin-downloads.html:5
 msgid "Download statistics"
 msgstr ""
@@ -1411,7 +1427,7 @@ msgstr ""
 msgid "%s to %s"
 msgstr ""
 
-#: webapp/backend/wishlist.py:128
+#: webapp/backend/wishlist.py:135
 msgid "Checkout this crowdfunding wish from #ipfire:"
 msgstr ""
 
index 123bc772a82ea37f518cb79a30b76adfc0b305a0..767488b06363dc633a51b5af502b209332bbc485 100644 (file)
@@ -9,54 +9,48 @@ from misc import Singleton
 class GeoIP(object):
        __metaclass__ = Singleton
 
-       def __init__(self):
-               self.__country_codes = self.db.query("SELECT code, name FROM iso3166_countries")
-
        @property
        def db(self):
                return Databases().geoip
 
-       @property
-       def memcached(self):
-               return Memcached()
-
-       def __encode_ip(self, addr):
+       def _encode_ip(self, addr):
                # We get a tuple if there were proxy headers.
                addr = addr.split(", ")
                if addr:
                        addr = addr[-1]
 
-               # ip is calculated as described in http://ipinfodb.com/ip_database.php
+               # ip is calculated as described in http://dev.maxmind.com/geoip/csv
                a1, a2, a3, a4 = addr.split(".")
 
-               return int(((int(a1) * 256 + int(a2)) * 256 + int(a3)) * 256 + int(a4) + 100)
+               try:
+                       a1 = int(a1)
+                       a2 = int(a2)
+                       a3 = int(a3)
+                       a4 = int(a4)
+               except ValueError:
+                       return 0
+
+               return (16777216 * a1) + (65536 * a2) + (256 * a3) + a4
 
        def get_country(self, addr):
-               addr = self.__encode_ip(addr)
+               addr = self._encode_ip(addr)
 
-               mem_id = "geoip-country-%s" % addr
-               ret = self.memcached.get(mem_id)
+               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)
 
-               if not ret:
-                       ret = self.db.get("SELECT * FROM ip_group_country WHERE ip_start <= %s \
-                               ORDER BY ip_start DESC LIMIT 1;", addr).country_code.lower()
-                       self.memcached.set(mem_id, ret, 3600)
-
-               return ret
+               if ret:
+                       return ret.country_code
 
        def get_all(self, addr):
-               addr = self.__encode_ip(addr)
+               addr = self._encode_ip(addr)
 
-               mem_id = "geoip-all-%s" % addr
-               ret = self.memcached.get(mem_id)
+               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)
 
                if not ret:
-                       # XXX should be done with a join
-                       location = self.db.get("SELECT location FROM ip_group_city WHERE ip_start <= %s \
-                               ORDER BY ip_start DESC LIMIT 1;", addr).location
-
-                       ret = self.db.get("SELECT * FROM locations WHERE id = %s", int(location))
-                       self.memcached.set(mem_id, ret, 3600)
+                       return
 
                # If location was not determinable
                if ret.latitude == 0 and ret.longitude == 0:
@@ -65,13 +59,24 @@ class GeoIP(object):
                return ret
 
        def get_country_name(self, code):
-               name = "Unknown"
-
-               code = code.upper()
-               for country in self.__country_codes:
-                       if country.code == code:
-                               name = country.name
-                               break
+               name = "Unkown"
+
+               codes = {
+                       "A1" : "Anonymous Proxy",
+                       "A2" : "Satellite Provider",
+                       "EU" : "Europe",
+                       "AP" : "Asia/Pacific Region",
+               }
+
+               # Return description of some exceptional codes.
+               try:
+                       return codes[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)
index 87c237dd050eab872c225cec557bea153f591b09..38040464e699d3149363eba81908b6a0bcf83bf6 100644 (file)
@@ -148,9 +148,13 @@ class Mirrors(object):
                mirrors = []
                all_mirrors = self.list()
 
+               location = GeoIP().get_all(addr)
+               if not location:
+                       return None
+
                while all_mirrors and len(mirrors) <= 2 and distance <= 270:
                        for mirror in all_mirrors:
-                               if mirror.distance_to(addr) <= distance:
+                               if mirror.distance_to(location) <= distance:
                                        mirrors.append(mirror)
                                        all_mirrors.remove(mirror)
 
@@ -241,15 +245,17 @@ class MirrorSet(object):
 
                mirrors = []
 
-               while len(mirrors) <= 2 and distance <= 270:
-                       for mirror in self._mirrors:
-                               if mirror in mirrors:
-                                       continue
+               location = GeoIP().get_all(addr)
+               if location:
+                       while len(mirrors) <= 2 and distance <= 270:
+                               for mirror in self._mirrors:
+                                       if mirror in mirrors:
+                                               continue
 
-                               if mirror.distance_to(addr) <= distance:
-                                       mirrors.append(mirror)
+                                       if mirror.distance_to(location) <= distance:
+                                               mirrors.append(mirror)
 
-                       distance *= 1.2
+                               distance *= 1.2
 
                return MirrorSet(mirrors)
 
@@ -269,6 +275,9 @@ class Mirror(object):
 
                self.reload()
 
+               self.__location = None
+               self.__country_name = None
+
        def __repr__(self):
                return "<%s %s>" % (self.__class__.__name__, self.url)
 
@@ -314,7 +323,7 @@ class Mirror(object):
 
        @property
        def location(self):
-               if not hasattr(self, "__location"):
+               if self.__location is None:
                        self.__location = GeoIP().get_all(self.address)
 
                return self.__location
@@ -342,11 +351,14 @@ class Mirror(object):
 
        @property
        def country_code(self):
-               return GeoIP().get_country(self.address).lower() or "unknown"
+               return self.location.country_code.lower() or "unknown"
 
        @property
        def country_name(self):
-               return GeoIP().get_country_name(self.country_code)
+               if self.__country_name is None:
+                       self.__country_name = GeoIP().get_country_name(self.country_code)
+
+               return self.__country_name
 
        @property
        def city(self):
@@ -484,12 +496,11 @@ class Mirror(object):
        def prefer_for_countries_names(self):
                return sorted([GeoIP().get_country_name(c) for c in self.prefer_for_countries])
 
-       def distance_to(self, addr):
-               location = GeoIP().get_all(addr)
+       def distance_to(self, location, ignore_preference=False):
                if not location:
                        return 0
 
-               if location.country_code.lower() in self.prefer_for_countries:
+               if not ignore_preference and location.country_code.lower() in self.prefer_for_countries:
                        return 0
 
                distance_vector = (
index 8ae911df546aa2c665071afc1c920149b4506fa7..d1a8a640fa90d6f153877148b283dd813d37a670 100644 (file)
@@ -24,13 +24,18 @@ class MirrorIndexHandler(BaseHandler):
 
 class MirrorItemHandler(BaseHandler):
        def get(self, id):
-               _ = self.locale.translate
-
                mirror = self.mirrors.get(id)
                if not mirror:
                        raise tornado.web.HTTPError(404)
 
-               self.render("mirrors-item.html", item=mirror)
+               ip_addr = self.get_argument("addr", self.request.remote_ip)
+               client_location = self.geoip.get_all(ip_addr)
+
+               client_distance = mirror.distance_to(client_location, ignore_preference=True)
+               client_distance *= 111.32 # to km
+
+               self.render("mirrors-item.html", item=mirror,
+                       client_distance=client_distance)
 
 
 class MirrorHandler(BaseHandler):