]> git.parisson.com Git - telemeta.git/commitdiff
fix geo navigator (needs optimization)
authorolivier <>
Wed, 27 Jan 2010 21:46:14 +0000 (21:46 +0000)
committerolivier <>
Wed, 27 Jan 2010 21:46:14 +0000 (21:46 +0000)
telemeta/models/__init__.py
telemeta/models/cremquery.py
telemeta/templates/telemeta_default/geo_continents.html
telemeta/templates/telemeta_default/geo_countries.html
telemeta/templates/telemeta_default/geo_country_collections.html
telemeta/urls.py
telemeta/web/base.py

index 3b4367b06c698b12df5842f28c727629716904f6..09106a8b88cf074e7701698b3e079d481c63c756 100644 (file)
@@ -36,3 +36,43 @@ from telemeta.models.crem import *
 #MediaCollection, MediaItem, MediaPart,  Revision, \
 #    PhysicalFormat, PublishingStatus
 
+from django.db.models.signals import post_syncdb
+
+def syncdb_callback(sender, **kwargs):
+    from django.db import connection
+    import _mysql_exceptions
+    cursor = connection.cursor()
+    print "Creating MySQL stored procedure"
+    try:
+        cursor.execute("DROP FUNCTION IF EXISTS telemeta_location_ascendant")
+    except _mysql_exceptions.Warning:
+        pass
+    try:
+        cursor.execute("""
+        CREATE FUNCTION telemeta_location_ascendant(loc CHAR(150), asc_type CHAR(16))
+          RETURNS CHAR(150) 
+          READS SQL DATA 
+          BEGIN 
+            DECLARE t, n CHAR(150); 
+            DECLARE c INT;
+            SELECT COUNT(*) INTO c FROM locations WHERE name = loc;
+            IF c = 0 THEN
+              RETURN NULL;
+            END IF;
+            SELECT name, type INTO n, t FROM locations WHERE name = loc;
+            WHILE t <> asc_type DO
+              SELECT COUNT(*) INTO c FROM location_relations WHERE location_name = n;
+              IF c = 0 THEN
+                RETURN NULL;
+              END IF;
+              SELECT parent_location_name INTO n FROM location_relations WHERE location_name = n LIMIT 1;
+              SELECT type INTO t FROM locations WHERE name = n;
+            END WHILE;  
+            RETURN n;
+          END""")
+    except _mysql_exceptions.Warning:
+        pass
+
+post_syncdb.connect(syncdb_callback)    
+    
+
index 4526bcdb9e9bc5ccf217bd9a59221d9454ceaf3e..b4452ba9dbc7e1443b2caac4980256d1b7654f7f 100644 (file)
 # Authors: Olivier Guilyardi <olivier@samalyse.com>
 #          David LIPSZYC <davidlipszyc@gmail.com>
 
+from django import db
 from django.db.models import Manager, Q
 from telemeta.models.core import EnhancedQuerySet, EnhancedManager
 import re
 from django.core.exceptions import ObjectDoesNotExist
+from django import db
+import _mysql_exceptions
 
 class CoreQuerySet(EnhancedQuerySet):
     "Base class for all query sets"
@@ -102,7 +105,11 @@ class MediaCollectionQuerySet(CoreQuerySet):
 
     def by_country(self, country):
         "Find collections by country"
-        return self.filter(items__location__type="country", items__location=country).distinct()
+        db.connection.cursor() # Need this to establish connection
+        country = db.connection.connection.literal(country)
+        return self.extra(where=["media_items.collection_id = media_collections.id",
+                                 "telemeta_location_ascendant(media_items.location_name, 'country') = %s" % country],
+                          tables=['media_items']).distinct()
     
     def by_continent(self, continent):
         "Find collections by continent"
@@ -165,28 +172,33 @@ class MediaCollectionManager(CoreManager):
         return self.get_query_set().by_change_time(*args, **kwargs)
     by_change_time.__doc__ = MediaCollectionQuerySet.by_change_time.__doc__
 
-    def stat_continents(self, order_by='num'):      
+    def stat_continents(self, order_by='nitems'):      
         "Return the number of collections by continents and countries as a tree"
         from django.db import connection
         cursor = connection.cursor()
-        if order_by == 'num':
+        if order_by == 'nitems':
             order_by = 'items_num DESC'
-        else:
-            order_by = 'etat'
-        cursor.execute("SELECT continent, etat, count(*) AS items_num "
-            "FROM media_collections INNER JOIN media_items "
-            "ON media_collections.id = media_items.collection_id "
-            "WHERE (continent IN "
-            "  ('EUROPE', 'OCEANIE', 'ASIE', 'AMERIQUE', 'AFRIQUE')) "
-            "AND etat <> '' "
-            "GROUP BY etat ORDER BY continent, " + order_by)
+        elif order_by != 'country':
+            raise Exception("stat_continents() can only order by nitems or country")
+
+        try:
+            cursor.execute("""
+                SELECT telemeta_location_ascendant(location_name, 'continent') as continent, 
+                       telemeta_location_ascendant(location_name, 'country') as country, 
+                       count(*) AS items_num 
+                FROM media_collections INNER JOIN media_items 
+                ON media_collections.id = media_items.collection_id 
+                GROUP BY country ORDER BY continent, """ + order_by)
+        except _mysql_exceptions.Warning:
+            pass
         result_set = cursor.fetchall()
         stat = {}
         for continent, country, count in result_set:
-            if stat.has_key(continent):
-                stat[continent].append({'name':country, 'count':count})
-            else:
-                stat[continent] = [{'name':country, 'count':count}]
+            if continent and country:
+                if stat.has_key(continent):
+                    stat[continent].append({'name':country, 'count':count})
+                else:
+                    stat[continent] = [{'name':country, 'count':count}]
 
         keys = stat.keys()
         keys.sort()
index 9e2a7314eb643d4093059d816ce20a0feee30ec9..6ba9e731a4fa729cd2ef62119bc0f3aec081c5aa 100644 (file)
@@ -6,15 +6,15 @@
 {% if continents %}
 <ul class="continents">
 {% for continent in continents %}
-  <li class="name"><b><a href="{% url telemeta-geo-countries continent.name|urlencode %}">{{ continent.name }}</a></b>
+  <li class="name"><b><a href="{% url telemeta-geo-countries continent.flatname %}">{{ continent.name }}</a></b>
     <ul>
     {% for country in continent.countries|slice:":10" %}
       <li class="country_name">
-        <a href="{% url telemeta-geo-country-collections continent.name,country.name|urlencode %}">
+        <a href="{% url telemeta-geo-country-collections continent.flatname,country.flatname %}">
           {{ country.name|lower|capfirst }}</a></li>
     {% endfor %}
     {% if continent.countries.10 %}
-    <li><a href="{% url telemeta-geo-countries continent.name|urlencode %}">More..</a></li>
+    <li><a href="{% url telemeta-geo-countries continent.flatname %}">More..</a></li>
     {% endif %}
     </ul>
   </li>
index 8b25e9ee725d85a4c37e28d6eab4df6aa2d9be0b..6b1bba87a7f76b158c98a3d7b9edc6dc650e15c9 100644 (file)
@@ -1,12 +1,13 @@
 {% extends "telemeta/base.html" %}
 {% load telemeta_utils %}
+{% load i18n %}
 
 {% block content %}
-<h3><a href="{% url telemeta-geo-continents %}">WORLD</a> /
+<h3><a href="{% url telemeta-geo-continents %}">{% trans "World" %}</a> /
   {{ continent.name }}</h3>
 <ul>
 {% for country in continent.countries %}
-  <li><a href="{% url telemeta-geo-country-collections continent.name,country.name|urlencode %}">
+  <li><a href="{% url telemeta-geo-country-collections continent.flatname,country.flatname %}">
     {{ country.name|lower|capfirst }} ({{ country.count }})</a></li>
 {% endfor %}
 </ul>
index 29bb27e97bc6920533d5fe9c59b09731c9ff956c..c277105aa7409178dbd872884c27f1e34799e58c 100644 (file)
@@ -1,9 +1,10 @@
 {% extends "telemeta/base.html" %}
 {% load telemeta_utils %}
+{% load i18n %}
 
 {% block content %}
-<h3><a href="{% url telemeta-geo-continents %}">WORLD</a> /
-  <a href="{% url telemeta-geo-countries continent|urlencode %}">{{ continent }}</a> 
+<h3><a href="{% url telemeta-geo-continents %}">{% trans "World" %}</a> /
+  <a href="{% url telemeta-geo-countries continent_flatname %}">{{ continent }}</a> 
   / {{ country }}</h3>
 
 {% with object_list as collections %}
index 224938006a5a0c9532e5bf2170ee59e76ff6de38..711ae65c8ec7347cb3733390a26c73a60deeb2a5 100644 (file)
@@ -136,9 +136,9 @@ urlpatterns = patterns('',
 
     # Geographic browsing
     url(r'^geo/$', web_view.list_continents, name="telemeta-geo-continents"),
-    url(r'^geo/(?P<continent>[A-Za-z]+)/$', web_view.list_countries, 
+    url(r'^geo/(?P<continent>[a-z_]+)/$', web_view.list_countries, 
         name="telemeta-geo-countries"),
-    url('^geo/(?P<continent>[A-Za-z]+)/(?P<country>[-A-Za-z0-9%;.,"& \']+)/$', 
+    url(r'^geo/(?P<continent>[a-z_]+)/(?P<country>[a-z_]+)/$', 
         web_view.list_country_collections, 
         name="telemeta-geo-country-collections"),
     url(r'^dynjs/continents.js$', web_view.get_continents_js, name="telemeta-continents-js"),
index 57d34314045ad8156c53959c4346537634088a79..6e057e8de8d4bcd306191a7ae192fa660cd8c0a2 100644 (file)
@@ -55,6 +55,7 @@ from telemeta.analysis.vamp import *
 import telemeta.interop.oai as oai
 from telemeta.interop.oaidatasource import TelemetaOAIDataSource
 from django.core.exceptions import ObjectDoesNotExist
+from telemeta.util.unaccent import unaccent
 
 class WebView(Component):
     """Provide web UI methods"""
@@ -336,8 +337,27 @@ class WebView(Component):
         context = Context({'item': item, 'host': request.META['HTTP_HOST']})
         return HttpResponse(template.render(context), mimetype=mimetype)
 
+    def make_continents_flatnames(self, continents):
+        map = {}
+        for c in continents:
+            flat = unaccent(c['name']).lower()
+            flat = re.sub('[^a-z]', '_', flat)
+            while map.has_key(flat):
+                flat = '_' + flat
+            c['flatname'] = flat
+            map[flat] = c['name']
+            for d in c['countries']:
+                flat = unaccent(d['name']).lower()
+                flat = re.sub('[^a-z]', '_', flat)
+                while map.has_key(flat):
+                    flat = '_' + flat
+                d['flatname'] = flat
+                map[flat] = d['name']
+        return map
+
     def list_continents(self, request):
         continents = MediaCollection.objects.stat_continents()
+        self.make_continents_flatnames(continents)
         return render_to_response('telemeta/geo_continents.html', 
                     {'continents': continents })
 
@@ -348,19 +368,22 @@ class WebView(Component):
 
     def list_countries(self, request, continent):                    
         continents = MediaCollection.objects.stat_continents()
+        self.make_continents_flatnames(continents)
         for c in continents:
-            if c["name"] == continent:
+            if c["flatname"] == continent:
                 break
-        if c["name"] != continent:
+        if c["flatname"] != continent:
             raise Http404
 
         return render_to_response('telemeta/geo_countries.html', {'continent': c })
 
     def list_country_collections(self, request, continent, country):
-        objects = MediaCollection.objects.by_country(country)
+        continents = MediaCollection.objects.stat_continents()
+        map = self.make_continents_flatnames(continents)
+        objects = MediaCollection.objects.by_country(map[country])
         return list_detail.object_list(request, objects, 
             template_name='telemeta/geo_country_collections.html', paginate_by=20,
-            extra_context={'country': country, 'continent': continent})
+            extra_context={'country': map[country], 'continent_flatname': continent, 'continent': map[continent]})
 
     def handle_oai_request(self, request):
         url         = 'http://' + request.META['HTTP_HOST'] + request.path