Ajout de la navigation par thesaurus
authorveltr
Thu, 04 Oct 2012 12:25:12 +0200
changeset 248 91bc8521e3cb
parent 247 3a34fc74e0d2
child 249 0fa959033897
child 250 7c3f54ce68af
Ajout de la navigation par thesaurus
web/hdalab/static/hdalab/css/cattree.css
web/hdalab/static/hdalab/js/cattree.js
web/hdalab/templates/categories.html
web/hdalab/urls.py
web/hdalab/views/ajax.py
--- a/web/hdalab/static/hdalab/css/cattree.css	Sun Sep 09 21:56:43 2012 +0200
+++ b/web/hdalab/static/hdalab/css/cattree.css	Thu Oct 04 12:25:12 2012 +0200
@@ -31,19 +31,19 @@
     color: #000060;
 }
 
-ul.disciplist {
+ul.disciplist, ul.theslist {
     list-style: none; margin: 10px 5px;
 }
 
-.disciplist li {
+.disciplist li, .theslist li {
     font-size: 12px; font-weight: bold;
 }
 
-.disciplist a {
+.disciplist a, .theslist a {
     color: #000066;
 }
 
-.disciplist .selected a {
+.disciplist .selected a, .theslist .selected a {
     color: #0000ff;
 }
 
--- a/web/hdalab/static/hdalab/js/cattree.js	Sun Sep 09 21:56:43 2012 +0200
+++ b/web/hdalab/static/hdalab/js/cattree.js	Thu Oct 04 12:25:12 2012 +0200
@@ -1,3 +1,163 @@
+var trees = [
+    {
+        title: "Thésaurus de l'Architecture et de l'Urbanisme : Secteur urbain",
+        tree: {
+            label: "secteur urbain",
+            contents: [
+                {
+                    label: "banlieue",
+                    contents: [
+                        {
+                            label: "faubourg"
+                        }
+                    ]
+                },
+                {
+                    label: "îlot"
+                },
+                {
+                    label: "quartier",
+                    contents: [
+                        {
+                            label: "centre-ville"
+                        }
+                    ]
+                },
+                {
+                    label: "secteur urbain concerté",
+                    contents: [
+                        {
+                            label: "grand ensemble"
+                        },
+                        {
+                            label: "lotissement",
+                            contents: [
+                                {
+                                    label: "lotissement concerté",
+                                    contents: [
+                                        {
+                                            label: "cité-jardin"
+                                        },
+                                        {
+                                            label: "cité ouvrière"
+                                        },
+                                        {
+                                            label: "courée"
+                                        },
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                },
+            ]
+        }
+    },
+    {
+        title: "Thésaurus Garnier : Architecture d'habitation",
+        tree: {
+            label: "architecture d'habitation",
+            contents: [
+                {
+                    label: "cité-jardin"
+                },
+                {
+                    label: "édifice d'habitation",
+                    contents: [
+                        {
+                            label: "demeure",
+                            contents: [
+                                {
+                                    label: "chalet"
+                                },
+                                {
+                                    label: "château"
+                                },
+                                {
+                                    label: "château-fort",
+                                    contents: [
+                                        {
+                                            label: "chemin de ronde"
+                                        },
+                                        {
+                                            label: "donjon"
+                                        }
+                                    ]
+                                },
+                                {
+                                    label: "hôtel particulier"
+                                },
+                                {
+                                    label: "maison"
+                                },
+                                {
+                                    label: "manoir"
+                                },
+                                {
+                                    label: "palais"
+                                }
+                            ]
+                        },
+                        {
+                            label: "abri",
+                            contents: [
+                                {
+                                    label: "buron"
+                                },
+                                {
+                                    label: "cabane"
+                                },
+                                {
+                                    label: "campement",
+                                    contents: [
+                                        {
+                                            label: "tente"
+                                        },
+                                        {
+                                            label: "tipi"
+                                        },
+                                        {
+                                            label: "igloo"
+                                        }
+                                    ]
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    },
+    {
+        title: "Thésaurus Garnier : Sciences occultes",
+        tree: {
+            label: "sciences occultes",
+            contents: [
+                {
+                    label: "alchimie"
+                },
+                {
+                    label: "astrologie"
+                },
+                {
+                    label: "divination"
+                },
+                {
+                    label: "magie",
+                    contents: [
+                        {
+                            label: "sorcellerie"
+                        },
+                        {
+                            label: "sorcière"
+                        }
+                    ]
+                }
+            ]
+        }
+    }
+]
+
 function render(_data, _level) {
     _data.theme_count =
         (typeof _data.sub_categories == "object" && typeof _data.sub_categories.slice == "function" ? _data.sub_categories.length : 0)
@@ -34,56 +194,60 @@
     return _html;
 }
 
+function showData(_label, _data) {
+    $(".disciplist li, .theslist li").each(function() {
+        if ($(this).text().trim().toLowerCase() === _label.toLowerCase()) {
+            $(this).addClass("selected");
+        }
+    })
+    $(".label-name").html(_label);
+    if (_data) {
+        $("#tree").html(render(_data, 0));
+        $(".cattree p.theme").click(function() {
+            $(this).parent().toggleClass("folded")
+            return false;
+        });
+        $("li.content").mouseenter(function() {
+            $(this).find(".foldedcontent")
+            .dequeue()
+            .animate({
+                height: 5 + $(this).find("p.description").outerHeight()
+            },
+            500);
+        }).mouseleave(function() {
+            $(this).find(".foldedcontent")
+            .dequeue()
+            .animate({
+                height: "0"
+            },
+            500);
+        });
+        $(".show_more").click(function() {
+            $(this).siblings(".hidden:lt(5)").removeClass("hidden");
+            var _l = $(this).siblings(".hidden").length;
+            $(this).find(".show_more_count").html(_l);
+            if (!_l) {
+                $(this).detach();
+            } 
+        })
+        $(".results").show();
+        $(".content-count").html($(".cattree a.content").length);
+        $(".category-count").html(Math.max(0, $("p.category").length - 1));
+        $(".tag-count").html($("p.tag").length);
+    } else {
+        $("#tree").html("");
+        $(".results").hide();
+    }
+}
+
 function gettree(_label) {
-    $(".disciplist li").removeClass("selected");
+    $(".disciplist li, .theslist li").removeClass("selected");
     $("#tree").html('<div class="loading"></div>');
     $.getJSON(
         endpoints.cat_tree,
         { label: _label },
         function(_data) {
-            $(".disciplist li").each(function() {
-                if ($(this).text().trim().toLowerCase() === _label.toLowerCase()) {
-                    $(this).addClass("selected");
-                }
-            })
-            $(".label-name").html(_label);
-            if (_data) {
-                $("#tree").html(render(_data, 0));
-                $(".cattree p.theme").click(function() {
-                    $(this).parent().toggleClass("folded")
-                    return false;
-                });
-                $("li.content").mouseenter(function() {
-                    $(this).find(".foldedcontent")
-                    .dequeue()
-                    .animate({
-                        height: 5 + $(this).find("p.description").outerHeight()
-                    },
-                    500);
-                }).mouseleave(function() {
-                    $(this).find(".foldedcontent")
-                    .dequeue()
-                    .animate({
-                        height: "0"
-                    },
-                    500);
-                });
-                $(".show_more").click(function() {
-                    $(this).siblings(".hidden:lt(5)").removeClass("hidden");
-                    var _l = $(this).siblings(".hidden").length;
-                    $(this).find(".show_more_count").html(_l);
-                    if (!_l) {
-                        $(this).detach();
-                    } 
-                })
-                $(".results").show();
-                $(".content-count").html($(".cattree a.content").length);
-                $(".category-count").html(Math.max(0, $("p.category").length - 1));
-                $(".tag-count").html($("p.tag").length);
-            } else {
-                $("#tree").html("");
-                $(".results").hide();
-            }
+            showData(_label, _data);
         }
     );
 }
@@ -115,5 +279,22 @@
     gettree("peinture");
     $(".disciplist li").click(function() {
         gettree($(this).text().trim());
-    })
+    });
+    _(trees).each(function(_tree) {
+        $("<li></li>")
+            .html($('<a href="#"></a>').text(_tree.title))
+            .appendTo(".theslist")
+            .click(function() {
+                $(".disciplist li, .theslist li").removeClass("selected");
+                $("#tree").html('<div class="loading"></div>');
+                $.getJSON(
+                    endpoints.fill_tree,
+                    { tree: JSON.stringify(_tree.tree) },
+                    function(_data) {
+                        showData(_tree.title, _data);
+                    }
+                );
+                return false;
+            });
+    });
 });
\ No newline at end of file
--- a/web/hdalab/templates/categories.html	Sun Sep 09 21:56:43 2012 +0200
+++ b/web/hdalab/templates/categories.html	Thu Oct 04 12:25:12 2012 +0200
@@ -1,6 +1,6 @@
 {% extends "base.html" %}
 
-{% block title %}{{block.super}} &gt; Arbre des catégories Wikipedia{% endblock %}
+{% block title %}{{block.super}} &gt; Recherche par arbre{% endblock %}
 
 {% block css_import %}
 {{block.super}}
@@ -16,7 +16,8 @@
         <script type="text/javascript">
         endpoints = {
             cat_search: "{% url cat_search %}",
-            cat_tree: "{% url cat_tree %}"
+            cat_tree: "{% url cat_tree %}",
+            fill_tree: "{% url fill_tree %}"
         };
         </script>
         <script src="{{STATIC_URL}}hdalab/js/cattree.js"></script>
@@ -43,10 +44,12 @@
             <li><a href="#">Sculpture</a></li>
             <li><a href="#">Théâtre</a></li>
         </ul>
-        <h3>Recherche libre dans les catégories&nbsp;: </h3>
+        <h3>Recherche de catégories de Wikipédia&nbsp;: </h3>
         <p>
             <form id="catform"><input id="catsearch" /></form>
         </p>
+        <h3>Recherche dans d'autres thésaurus&nbsp;:</h3>
+        <ul class="theslist"></ul>
         <div class="results hidden">
             <h2>Résultats pour &laquo;&nbsp;<span class="label-name"></span>&nbsp;&raquo;&nbsp;:</h2>
             <p class="category-results"><span class="category-count"></span> sous-catégorie(s)</p>
--- a/web/hdalab/urls.py	Sun Sep 09 21:56:43 2012 +0200
+++ b/web/hdalab/urls.py	Thu Oct 04 12:25:12 2012 +0200
@@ -36,5 +36,6 @@
     (r'^a/tagsearch$', 'tagsearch', {}, 'tag_search'),
     (r'^a/catsearch$', 'catsearch', {}, 'cat_search'),
     (r'^a/cattree$', 'cattree', {}, 'cat_tree'),
+    (r'^a/filltree$', 'filltree', {}, 'fill_tree'),
     (r'^a/contentsbytag$', 'contentsbytag', {}, 'contentsbytag'),
 )
--- a/web/hdalab/views/ajax.py	Sun Sep 09 21:56:43 2012 +0200
+++ b/web/hdalab/views/ajax.py	Thu Oct 04 12:25:12 2012 +0200
@@ -6,7 +6,7 @@
 '''
 from django.conf import settings
 from django.core.cache import cache
-from django.db.models import Q, Count
+from django.db.models import Q, Count, Min
 from django.http import HttpResponse
 from hdabo.models import Tag, Datasheet, TaggedSheet
 from hdalab.models import HdaSession, Country, TagYears, DatasheetExtras
@@ -479,4 +479,37 @@
         outputstr = json.dumps(output)
         cache.set(cache_key, outputstr)
         
-    return HttpResponse(content=outputstr, mimetype='application/json')
\ No newline at end of file
+    return HttpResponse(content=outputstr, mimetype='application/json')
+
+def subtree(tree):
+    MAX_TAG_ORDER = 8
+    label = tree['label']
+    sub = tree.get('contents',[])
+    
+    datasheets = Datasheet.objects.filter(validated = True, taggedsheet__tag__label__iexact = label, taggedsheet__order__lte = MAX_TAG_ORDER).annotate(tagorder=Min('taggedsheet__order')).select_related('organisation').distinct()
+    
+    contents = [{ 'description': ds.description, 'title': ds.title, 'url': ds.url, 'score': MAX_TAG_ORDER - ds.tagorder, 'id': ds.id, 'hda_id': ds.hda_id, 'organization': ds.organisation.name } for ds in datasheets]
+    
+    contents = sorted(contents, key=lambda e: -e['score'])
+    
+    res = { 'category': label }
+    
+    if len(contents):
+        res['contents'] = contents
+    
+    if len(sub):
+        subcats = [subtree(st) for st in sub]
+        subcats = [sc for sc in subcats if len(sc.get('contents',[])) or len(sc.get('sub_categories',[]))]
+        res['sub_categories'] = subcats
+    
+    return res
+
+def filltree(request):
+    
+    tree = request.GET.get('tree','{}')
+    
+    treeobj = json.loads(tree)
+    
+    res = subtree(treeobj)
+        
+    return HttpResponse(content=json.dumps(res), mimetype='application/json')