Corrections in Completion
authorveltr
Wed, 05 Sep 2012 19:11:34 +0200
changeset 238 f818b9430585
parent 237 9da0ed5afe8d
child 239 3a7ecd3ad34f
Corrections in Completion
web/hdalab/static/hdalab/css/completion.css
web/hdalab/static/hdalab/img/small-loader.gif
web/hdalab/static/hdalab/js/completion.js
web/hdalab/templates/completion.html
web/hdalab/urls.py
web/hdalab/views/ajax.py
--- a/web/hdalab/static/hdalab/css/completion.css	Fri Aug 31 10:48:51 2012 +0200
+++ b/web/hdalab/static/hdalab/css/completion.css	Wed Sep 05 19:11:34 2012 +0200
@@ -145,25 +145,33 @@
     width: 100%; font-size: 16px; font-weight: bold; border-style: none; border-bottom: 1px solid #000;
 }
 
-#tagsearch.grise {
-    color: #666; font-style: italic; font-weight: normal;
+#tagsearch.waiting {
+    background: url(../img/small-loader.gif) no-repeat right;
 }
 
 ul.ui-autocomplete {
-    width: 180px; font-family: "Open Sans";
-    max-height: 600px; overflow-y: auto; overflow-x: hidden; padding-right: 20px;
+    font-family: "Open Sans"; max-width: 230px;
+    max-height: 400px; overflow-y: auto; overflow-x: hidden;
+}
+
+.wpinfo {
+    margin-left: 240px;
+}
+
+.ui-menu-item:hover .acwp {
+    display: block;
+}
+
+.acnb {
+    float: right; font-size: 12px; margin: 2px 0 0 2px;
 }
 
 h4.actitle {
-    font-size: 14px; font-weight: bold;
-}
-
-.acimgwrap {
-    float: left; width: 80px; text-align: center;
+    font-size: 13px; font-weight: bold;
 }
 
 img.acimg {
-    max-width: 80px; max-height: 60px;
+    max-width: 80px; max-height: 60px; float: left; margin: 5px 2px 2px 0;
 }
 
 p.acabstract {
Binary file web/hdalab/static/hdalab/img/small-loader.gif has changed
--- a/web/hdalab/static/hdalab/js/completion.js	Fri Aug 31 10:48:51 2012 +0200
+++ b/web/hdalab/static/hdalab/js/completion.js	Wed Sep 05 19:11:34 2012 +0200
@@ -28,7 +28,7 @@
                     + _d.description.replace(/(^.{0,160})([\s]|$)(.*)/,'$1…')
                     + '</p><ul class="content-tags">'
                     + _d.tags.map(function(_t) {
-                        return '<li class="content-tag-item"><a href="#" onclick="tagInfo(this.getAttribute(\'original-label\'), true); return false;" original-label="'
+                        return '<li class="content-tag-item"><a href="#" onclick="getContents(this.textContent.trim()); return false;" original-label="'
                             + _t.label
                             + '"'
                             + (_t.match ? ' class="tagmatch"' : '')
@@ -50,11 +50,9 @@
 
 function getContents(label) {
     $.getJSON(
-        gomNs.urls['filter'],
+        gomNs.urls['contentsbytag'],
         {
-            label: label,
-            tagcount: 0,
-            contentcount: 30
+            label: label
         },
         showResults
     );
@@ -64,24 +62,60 @@
     $(" #tagform ").submit(function() {
         return false;
     });
+    var cache = {}, /*CACHE => http://jqueryui.com/demos/autocomplete/#remote-with-cache */
+        lastXhr;
     $( "#tagsearch" ).autocomplete({
-        source: gomNs.urls['tag_search'],
+        source: function( request, response ) {
+            var term = request.term;
+            if ( term in cache ) {
+                $("#tagsearch").removeClass("waiting");
+                response( cache[ term ] );
+                return;
+            }
+            $("#tagsearch").addClass("waiting");
+            lastXhr = $.getJSON( gomNs.urls['tag_search'], request, function( data, status, xhr ) {
+                cache[ term ] = data;
+                if ( xhr === lastXhr ) {
+                    response( data );
+                    $("#tagsearch").removeClass("waiting");
+                }
+            });
+        },
         minLength: 2,
+        focus: function( event, ui ) {
+            var _title = $('<h4>')
+                .addClass("actitle")
+                .html(
+                    ui.item.value.replace(
+                        new RegExp('('
+                            + $("#tagsearch").val().replace(/(\W)/g, '\\$1')
+                            + ')','gi') ,
+                        '<strong>$1</strong>')
+                );
+            $(".wpinfo").html(_title);
+            if (ui.item.thumbnail) {
+                var _img = $('<img>')
+                    .addClass("acimg")
+                    .attr("src",ui.item.thumbnail);
+                $(".wpinfo").append(_img);
+            }
+            if (ui.item.abstract) {
+                var _abstract = $('<p>')
+                    .addClass("acabstract")
+                    .text( ui.item.abstract.replace(/(^.{0,240})([\s]|$)(.*)/,'$1…') );
+                $(".wpinfo").append(_abstract);
+            }
+            $(".wpinfo").append('<div class="clear"></div>');
+        },
         select: function( event, ui ) {
-            getContents(ui.item.original_label);
-        }
-    })
-    .addClass("grise")
-    .focusin(function() {
-        $(this).removeClass("grise");
-    })
-    .focusout(function() {
-        if (!$(this).val()) {
-            $(this).addClass("grise");
+            getContents(ui.item.label);
         }
     })
     .data("autocomplete")._renderItem = function(ul, item) {
         var _contents = $('<a>'),
+            _nb = $('<span>')
+                .addClass("acnb")
+                .text(item.nb),
             _title = $('<h4>')
                 .addClass("actitle")
                 .html(
@@ -90,25 +124,8 @@
                             + $("#tagsearch").val().replace(/(\W)/g, '\\$1')
                             + ')','gi') ,
                         '<strong>$1</strong>')
-                ),
-            _clear = $('<div>').addClass('clear');
-        _contents.append(_title);
-        if (item.thumbnail) {
-            var _img = $('<img>')
-                    .addClass("acimg")
-                    .attr("src",item.thumbnail),
-                _imgwrap = $('<div>')
-                    .addClass("acimgwrap")
-                    .append(_img);
-            _contents.append(_imgwrap);
-        }
-        if (item.abstract) {
-            var _abstract = $('<p>')
-                .addClass("acabstract")
-                .text( item.abstract.replace(/(^.{0,240})([\s]|$)(.*)/,'$1…') );
-            _contents.append(_abstract);
-        }
-        _contents.append(_clear);
+                );
+        _contents.append(_nb).append(_title);
         return $( "<li>" )
             .data( "item.autocomplete", item )
             .append( _contents )
--- a/web/hdalab/templates/completion.html	Fri Aug 31 10:48:51 2012 +0200
+++ b/web/hdalab/templates/completion.html	Wed Sep 05 19:11:34 2012 +0200
@@ -23,7 +23,7 @@
         <script type="text/javascript">
         gomNs.languageCode = '{{LANGUAGE_CODE}}';
         gomNs.urls = {
-            'filter': "{% url filter %}",
+            'contentsbytag': "{% url contentsbytag %}",
             'tag_search': "{% url tag_search %}"
         };
         </script>
@@ -59,6 +59,9 @@
                         <form id="tagform">
                             <input id="tagsearch" placeholder="{% trans "Rechercher un tag" %}" />
                         </form>
+                        <div class="wpinfo">
+                            
+                        </div>
                     </div>
                 </div>
                 <div class="bloc" id="bloc_translationinfo">
--- a/web/hdalab/urls.py	Fri Aug 31 10:48:51 2012 +0200
+++ b/web/hdalab/urls.py	Wed Sep 05 19:11:34 2012 +0200
@@ -36,4 +36,5 @@
     (r'^a/tagsearch$', 'tagsearch', {}, 'tag_search'),
     (r'^a/catsearch$', 'catsearch', {}, 'cat_search'),
     (r'^a/cattree$', 'cattree', {}, 'cat_tree'),
+    (r'^a/contentsbytag$', 'contentsbytag', {}, 'contentsbytag'),
 )
--- a/web/hdalab/views/ajax.py	Fri Aug 31 10:48:51 2012 +0200
+++ b/web/hdalab/views/ajax.py	Wed Sep 05 19:11:34 2012 +0200
@@ -184,6 +184,7 @@
 def tagsearch(request):
     
     q = request.GET.get('term',None)
+    maxcount = int(request.GET.get('count','40'))
     lang = request.GET.get('lang',request.LANGUAGE_CODE)
     
     stemming_langs = [ 'fr', 'en', 'de', 'it' ]
@@ -201,13 +202,13 @@
                 qs = qs.filter( label__icontains = q )
         else:
             if lang in stemming_langs:
-                qs = qs.filter( Q(label__iregex=q ) | Q(dbpedia_fields__translations__label__iregex=q, dbpedia_fields__translations__language_code=lang), ~Q(dbpedia_uri = None))
+                qs = qs.filter(dbpedia_fields__translations__label__iregex=qrx, dbpedia_fields__translations__language_code=lang)
             else:
-                qs = qs.filter( Q(label__icontains=q ) | Q(dbpedia_fields__translations__label__icontains=q, dbpedia_fields__translations__language_code=lang), ~Q(dbpedia_uri = None))
+                qs = qs.filter(dbpedia_fields__translations__label__icontains=q, dbpedia_fields__translations__language_code=lang)
     else:
         qs = Tag.objects.filter(~Q(dbpedia_uri = None))
            
-    qs = qs.annotate(nb=Count('datasheet',distinct=True)).order_by('-nb')[:20]
+    qs = qs.annotate(nb=Count('datasheet',distinct=True)).order_by('-nb')[:maxcount]
     
     qslist = list(qs)
     
@@ -231,7 +232,6 @@
             resobj['abstract'] = dbfields.abstract if dbfields is not None else None
         if q is None or resobj['value'].lower().find(lq) != -1:
             res.append(resobj)
-    res.sort(key=lambda resobj: resobj['value'])
     
     return HttpResponse(content=json.dumps(res), mimetype='application/json')
 
@@ -258,7 +258,7 @@
     label = request.GET.get('label', None)
     country = request.GET.get('country', None)
     contentlist = request.GET.get('contentlist', None)
-    max_tag_order = request.GET.get('mto', 12)
+    max_tag_order = int(request.GET.get('mto', '12'))
     content_count = request.GET.get('contentcount', 12)
     tag_count = request.GET.get('tagcount', 30)
     
@@ -419,3 +419,61 @@
         cache.set(cache_key, outputstr)
         
     return HttpResponse(content=outputstr, mimetype='application/json')
+
+def contentsbytag(request):
+    
+    lang = request.GET.get('lang',request.LANGUAGE_CODE)
+    label = request.GET.get('label', None).strip().lower()
+    max_tag_order = int(request.GET.get('mto', '30'))
+    content_count = int(request.GET.get('contentcount', '30'))
+    
+    cache_key = fix_cache_key("contentsbytag-%s"%unicode(label).encode("utf-8"))
+    
+    outputstr = cache.get(cache_key)
+    
+    if outputstr is None:
+        
+        matchtagids = []
+        
+        contentqs = Datasheet.objects.filter(validated=True)
+        
+        no_translate_langs = [ 'fr' ]
+        if lang in no_translate_langs:
+            tagsqs = Tag.objects.filter( label__iexact = label )
+        else:
+            tagsqs = Tag.objects.select_related('dbpedia_fields').filter(dbpedia_fields__translations__label__iexact = label, dbpedia_fields__translations__language_code=lang)
+            
+        contentqs = contentqs.select_related('taggedsheet__tag').filter(taggedsheet__tag__in=tagsqs).distinct()
+        
+        cont_count = contentqs.count()
+        
+        contenus = dict([(content.id, {'score' : 0, 'tags' : [], 'id':content.id, 'title': content.title, 'description': content.description, 'url': content.url}) for content in contentqs[0:content_count]])
+        contentids = contenus.keys()
+        
+        qs = DatasheetExtras.objects.select_related('insee').filter(datasheet__in = contentids)
+        for dse in qs:
+            contenus[dse.datasheet_id]['coords'] = {'city_name': dse.insee.city_name, 'latitude': dse.insee.latitude, 'longitude': dse.insee.longitude}
+        
+        qs = list(TaggedSheet.objects.select_related('tag', 'tag__dbpedia_fields').filter(datasheet__in = contentids).order_by('order'))
+        
+        if lang in no_translate_langs:
+            translations = {}
+        else:
+            transqs = DbpediaFieldsTranslation.objects.filter(master__in = [ts.tag.dbpedia_fields for ts in qs], language_code = lang)
+            translations = dict([(trans.master_id,trans.label) for trans in transqs])
+        
+        for ts in qs:
+            translated_label = translations.get(ts.tag.dbpedia_fields.id, ts.tag.label) if ts.tag.dbpedia_fields is not None else ts.tag.label
+            match_tag = ( label == translated_label.lower() )
+            contenus[ts.datasheet_id]['tags'].append({'id': ts.tag.id, 'label':ts.tag.label, 'order':ts.order, 'match': match_tag , 'translated_label': translated_label})
+            
+            if match_tag:
+                contenus[ts.datasheet_id]['score'] += 2*max_tag_order - ts.order
+            
+        contenus = sorted(contenus.values(),key=lambda e: -e['score'])
+        
+        output = {'count': cont_count, 'contents': contenus}
+        outputstr = json.dumps(output)
+        cache.set(cache_key, outputstr)
+        
+    return HttpResponse(content=outputstr, mimetype='application/json')
\ No newline at end of file