--- a/src/spel/settings.py Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/settings.py Wed Apr 16 17:22:05 2014 +0200
@@ -132,7 +132,8 @@
'haystack',
'tastypie',
'guardian',
- 'tagging',
+ 'taggit',
+ 'taggit_templatetags',
'registration',
'oauth_provider',
'django_openid_consumer',
--- a/src/spel/static/spel/js/spectacle.js Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/static/spel/js/spectacle.js Wed Apr 16 17:22:05 2014 +0200
@@ -360,8 +360,8 @@
$('option', $('#mulsel4')).each(function(element) { $(this).removeAttr('selected').prop('selected', false); });
$('#mulsel4').multiselect('refresh');
// Then we request
- $(".annot-results").html("<br/><br/>");
- $(".annot-results").addClass("loader");
+ $(".annotation-results").html("<br/><br/>");
+ $(".annotation-results").addClass("loader");
var bla = [];
$('.chapter-data').each(function(index){
bla.push({start: $(this).attr("data-start"), end: $(this).attr("data-end"), iri_id: $(this).attr("data-content") });
--- a/src/spel/templates/partial/spel_chapters.html Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/templates/partial/spel_chapters.html Wed Apr 16 17:22:05 2014 +0200
@@ -33,7 +33,7 @@
<tr class="chapter-data" data-content="{{ s.iri_id }}" data-start="{{ s.start_ts }}" data-end="{{ s.start_ts|add:s.duration }}">
<td title="{{ s.cutting_id }}">{{ s.cutting_id|slice:":1"|upper }}</td><td>{{ s.tags|get_tags:"ref_text"|join:', ' }}</td><td>{% if annot_chapters %}{{ s.ct }}{% else %}{{ s.content.title }}{% endif %}</td>
<td>
- <span class="glyphicon glyphicon-plus-sign popinfo" data-trigger="hover" data-container="body" data-toggle="popover" data-placement="auto"
+ <span class="glyphicon glyphicon-info-sign popinfo" data-trigger="hover" data-container="body" data-toggle="popover" data-placement="auto"
data-content="<strong>Timecodes:</strong> {{ s.start_ts|str_duration }} - {{ s.start_ts|add:s.duration|str_duration }}<br/>{{ s.tags|get_tags:'group'|safe }}"></span>
<input type="checkbox" class="filter-chapter-annot" />
</td>
--- a/src/spel/templates/spel_base.html Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/templates/spel_base.html Wed Apr 16 17:22:05 2014 +0200
@@ -27,7 +27,7 @@
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
{% url 'spel_spectacle' as url %}
- <li{% if request.path == url %} class="active"{% endif %}><a href="{{ url }}">Spectacle</a></li>
+ <li{% if request.path == url %} class="active"{% endif %}><a href="{{ url }}">Théâtre</a></li>
<li><a href="#">Opéra</a></li>
{% url 'spel_corpus' as url %}
<li{% if request.path == url %} class="active"{% endif %}><a href="{{ url }}">Corpus</a></li>
--- a/src/spel/templates/spel_home.html Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/templates/spel_home.html Wed Apr 16 17:22:05 2014 +0200
@@ -4,6 +4,6 @@
{% block page_title %}Accueil{% endblock %}</title>
{% block spel_content %}
- <p><a href="{% url 'spel_spectacle' %}">Spectacle</a></p>
+ <p><a href="{% url 'spel_spectacle' %}">Théâtre</a></p>
<p><a href="#">Opéra</a></p>
{% endblock %}
--- a/src/spel/templates/spel_spectacle.html Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/templates/spel_spectacle.html Wed Apr 16 17:22:05 2014 +0200
@@ -27,7 +27,7 @@
</div>
<div class="row">
<div class="col-md-4">
- <select id="mulsel1" class="multiselect" multiple="multiple" data-title="Types d'annotations">
+ <select id="mulsel1" class="multiselect" multiple="multiple" data-title="Types de chapitres">
</select>
</div>
<div class="col-md-4">
@@ -89,7 +89,7 @@
<script type="text/javascript">
var urlMS = "{% url 'api_dispatch_list' resource_name='tags' api_name='1.0' %}?format=json&limit=500&name__startswith=modalites_sceniques:";
var urlP = "{% url 'api_dispatch_list' resource_name='tags' api_name='1.0' %}?format=json&limit=500&name__startswith=personnages:";
- var urlTI = "{% url 'api_dispatch_list' resource_name='tags' api_name='1.0' %}?format=json&limit=500&name__startswith=type_inter:";
+ var urlTI = "{% url 'api_dispatch_list' resource_name='tags' api_name='1.0' %}?format=json&limit=500&name__startswith=type_inter:&order_by=name";
var urlRT = "{% url 'api_dispatch_list' resource_name='tags' api_name='1.0' %}?format=json&limit=1000&name__startswith=ref_text:";
var urlChapters = "{% url 'spel_chapters' %}";
var urlAnnotations = "{% url 'spel_annotations' %}";
--- a/src/spel/templatetags/spel_tags.py Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/templatetags/spel_tags.py Wed Apr 16 17:22:05 2014 +0200
@@ -11,10 +11,17 @@
# Error management
if value is None :
return ""
- if not isinstance(value, (str,unicode)) :
- raise TemplateSyntaxError('get_tags value error : string is required')
+ #if not isinstance(value, (str,unicode)) :
+ #if not isinstance(value, (str,unicode)) :
+ # raise TemplateSyntaxError('get_tags value error : string is required')
# If no arg, we join all values
- a = value.split(u",")
+ #a = value.split(u",")
+ if isinstance(value, list):
+ # Simple list of strings
+ a = [t for t in value]
+ else:
+ # TaggableManager instance
+ a = [t.name for t in value.all()]
val = []
if arg is None :
for t in a:
--- a/src/spel/views.py Mon Mar 31 16:09:50 2014 +0200
+++ b/src/spel/views.py Wed Apr 16 17:22:05 2014 +0200
@@ -11,7 +11,7 @@
from django.views.generic import TemplateView
from itertools import groupby
from operator import itemgetter
-from tagging.models import Tag, TaggedItem
+from taggit.models import Tag, TaggedItem
from ldt.ldt_utils.models import Segment, Content
@@ -19,6 +19,8 @@
from ldt.ldt_utils.views.workspace import get_search_results
from django.http.response import HttpResponse
from django.db.models.query import RawQuerySet
+from django.contrib.contenttypes.models import ContentType
+from django.db.models.aggregates import Count
logger = logging.getLogger(__name__)
@@ -60,7 +62,7 @@
#logger.debug(iri_ids)
# Filter segment if necessary
annot_types_param = request.GET.get("annotation_types", "")
- seg_queryset = Segment.objects.filter(iri_id__in=iri_ids).select_related('content__title')
+ seg_queryset = Segment.objects.filter(iri_id__in=iri_ids).select_related("content__title")#.prefetch_related("tags")
annot_types = []
if annot_types_param!="":
annot_types = annot_types_param.split(",")
@@ -111,6 +113,8 @@
# Get tags from orm
all_tags = mod_scen + perso
tags = Tag.objects.filter(name__in=all_tags)
+ # seg_queryset.filter(tags__in=tags) doesn't work because taggit finds segments with one of the tags and not ALL tags
+ # So we make a correct request through TaggedItem first
# Ref text filter if possible
if ref_text and len(ref_text)>0:
# a chapter can only have on ref_text, and the search on ref_text is a OR.
@@ -119,10 +123,25 @@
for rt in ref_text:
current_tags = list(tags)
current_tags.append(rt)
- s += list(TaggedItem.objects.get_by_model(seg_queryset, current_tags))
+ #s += list(TaggedItem.objects.get_by_model(seg_queryset, current_tags))
+ seg_ids = list(TaggedItem.objects\
+ .values_list("object_id", flat=True)\
+ .filter(content_type=ContentType.objects.get_for_model(Segment))\
+ .filter(tag__in=current_tags)\
+ .annotate(count_status=Count('object_id'))\
+ .filter(count_status=len(current_tags)))
+ s += list(seg_queryset.filter(pk__in=seg_ids))
else:
# Get segments from tagged items
- s = TaggedItem.objects.get_by_model(seg_queryset, tags)
+ #s = TaggedItem.objects.get_by_model(seg_queryset, tags)
+ tags = list(tags)
+ seg_ids = list(TaggedItem.objects\
+ .values_list("object_id", flat=True)\
+ .filter(content_type=ContentType.objects.get_for_model(Segment))\
+ .filter(tag__in=tags)\
+ .annotate(count_status=Count('object_id'))\
+ .filter(count_status=len(tags)))
+ s = list(seg_queryset.filter(pk__in=seg_ids))
context = {"annot_types":annot_types, "start_date":start_date_param, "end_date":end_date_param,
"mod_scen":mod_scen, "perso":perso, "searched_ref_text":searched_ref_text, "segments": s}
@@ -156,7 +175,7 @@
# ))
# )
- raw_query = "select ldt_utils_segment.id, ldt_utils_segment.cutting_id, ldt_utils_segment.tags, ldt_utils_segment.start_ts, ldt_utils_segment.duration, ldt_utils_content.title AS ct \nfrom ldt_utils_segment \nINNER JOIN ldt_utils_content ON (ldt_utils_segment.content_id = ldt_utils_content.id) \nwhere cutting_id IN ('performance','discussion') \nAND ("
+ raw_query = "select ldt_utils_segment.id, ldt_utils_segment.cutting_id, ldt_utils_segment.start_ts, ldt_utils_segment.duration, ldt_utils_content.title AS ct \nfrom ldt_utils_segment \nINNER JOIN ldt_utils_content ON (ldt_utils_segment.content_id = ldt_utils_content.id) \nwhere cutting_id IN ('performance','discussion') \nAND ("
for i, ga in enumerate(grouped_annotations):
if i>0:
raw_query += "\n OR "
@@ -195,8 +214,25 @@
type_inter = [("type_inter: " + t) for t in type_inter_param.split(",")]
tags = Tag.objects.filter(name__in=type_inter)
# Get segments from tagged items
- tagged_segs = TaggedItem.objects.get_by_model(Segment, tags).values()
- # Prefetch all contents
+ #tagged_segs = TaggedItem.objects.get_by_model(Segment, tags).values()
+ tags = list(tags)
+ seg_ids = list(TaggedItem.objects\
+ .values_list("object_id", flat=True)\
+ .filter(content_type=ContentType.objects.get_for_model(Segment))\
+ .filter(tag__in=tags)\
+ .annotate(count_status=Count('object_id'))\
+ .filter(count_status=len(tags)))
+ tagged_segs = Segment.objects.filter(pk__in=seg_ids).prefetch_related("tags__name").values("pk", "tags__name", "project_id", "iri_id", "ensemble_id", "cutting_id", "element_id", "title", "duration", "start_ts", "author", "date", "abstract", "polemics", "id_hash", "audio_src", "audio_href")
+
+ # Because of prefetch and values, we have to parse all items in order to create a list of tags for all items
+ tagged_segs_dict = {}
+ for s in tagged_segs:
+ if s['pk'] not in tagged_segs_dict:
+ tagged_segs_dict[s['pk']] = s
+ tagged_segs_dict[s['pk']]["tags"] = []
+ tagged_segs_dict[s['pk']]["tags"].append(s['tags__name'])
+ tagged_segs = tagged_segs_dict.values()
+
all_contents = list(Content.objects.filter(iri_id__in=[s['iri_id'] for s in tagged_segs]))
for iri_id, items in groupby(tagged_segs, itemgetter('iri_id')):
# Get good content
@@ -244,7 +280,8 @@
# ))
# )
- raw_query = "select id, iri_id, cutting_id, tags, start_ts, duration, title, abstract \nfrom ldt_utils_segment \nwhere cutting_id NOT IN ('performance','discussion') \nAND ("
+ raw_query = "SELECT ldt_utils_segment.id, taggit_tag.name AS tags__name, ldt_utils_segment.iri_id, ldt_utils_segment.cutting_id, ldt_utils_segment.title, ldt_utils_segment.duration, ldt_utils_segment.start_ts, ldt_utils_segment.abstract \nFROM ldt_utils_segment \nLEFT OUTER JOIN taggit_taggeditem \nON (ldt_utils_segment.id = taggit_taggeditem.object_id) \nLEFT OUTER JOIN taggit_tag \nON (taggit_taggeditem.tag_id = taggit_tag.id) \nwhere cutting_id NOT IN ('performance','discussion') \nAND ("
+ #raw_query = "select id, iri_id, cutting_id, start_ts, duration, title, abstract \nfrom ldt_utils_segment \nwhere cutting_id NOT IN ('performance','discussion') \nAND ("
for i, ga in enumerate(grouped_chapters):
if i>0:
raw_query += "\n OR "
@@ -258,8 +295,15 @@
# Dict because of itemgetter for groupby
tagged_segs = [ dict(s.__dict__) for s in Segment.objects.raw(raw_query) ]
- for i in tagged_segs:
- i["tags"] = i["_tags_cache"] # WHY ????? Because i don't know but we need it
+ # Because of taggit_tag.name JOIN, we have to parse all items in order to create a list of tags for all items
+ tagged_segs_dict = {}
+ for s in tagged_segs:
+ if s['id'] not in tagged_segs_dict:
+ tagged_segs_dict[s['id']] = s
+ tagged_segs_dict[s['id']]["tags"] = []
+ tagged_segs_dict[s['id']]["tags"].append(s['tags__name'])
+ tagged_segs = tagged_segs_dict.values()
+
# Prefetch all contents
all_contents = list(Content.objects.filter(iri_id__in=[s['iri_id'] for s in tagged_segs]))
results = []
--- a/virtualenv/res/lib/lib_create_env.py Mon Mar 31 16:09:50 2014 +0200
+++ b/virtualenv/res/lib/lib_create_env.py Wed Apr 16 17:22:05 2014 +0200
@@ -20,7 +20,8 @@
'DJANGO': {'setup': 'django', 'url': 'https://github.com/IRI-Research/django/archive/1.5.5+IRI.tar.gz', 'local':"django-1.5.5-IRI.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
'DJANGO-EXTENSIONS': { 'setup': 'django-extensions', 'url':'https://github.com/django-extensions/django-extensions/archive/1.1.1.tar.gz', 'local':"django-extensions-1.1.1.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
'DJANGO-REGISTRATION': { 'setup': 'django-registration', 'url':'https://bitbucket.org/IRI/django-registration/get/tip.tar.gz', 'local':"IRI-django-registration-e23626c256c0.tar.gz", 'install': {'method': 'easy_install', 'option_str': '-Z', 'dict_extra_env': None}},
- 'DJANGO-TAGGING': { 'setup': 'django-tagging', 'url':'django-tagging-0.3.1-IRI.tar.gz', 'local':"django-tagging-0.3.1-IRI.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'DJANGO-TAGGIT': { 'setup': 'django-taggit', 'url':'https://github.com/alex/django-taggit/archive/0.11.2.tar.gz', 'local':"django-taggit-0.11.2.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'DJANGO-TAGGIT-TEMPLATETAGS': { 'setup': 'django-taggit-templatetags', 'url':'https://github.com/feuervogel/django-taggit-templatetags/archive/d2216c9d1888e0739a04899a36e5149b5cbb3381.zip', 'local':"django-taggit-a38ee9d8913e05b1993f90c358be5f5397f529eb.zip", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
'OAUTH2': { 'setup': 'python-oauth2', 'url':"https://github.com/simplegeo/python-oauth2/tarball/hudson-python-oauth2-211", 'local':"oauth2-1.5.211.tar.gz", 'install': {'method': 'easy_install', 'option_str': None, 'dict_extra_env': None}},
'HTTPLIB2': { 'setup': 'python-httplib2', 'url':'https://httplib2.googlecode.com/files/httplib2-0.8.tar.gz', 'local':"httplib2-0.8.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
'DJANGO-OAUTH-PLUS': { 'setup': 'django-oauth-plus', 'url':'https://pypi.python.org/packages/source/d/django-oauth-plus/django-oauth-plus-2.1.0.tar.gz', 'local':"django-oauth-plus-2.1.0.tar.gz", 'install': {'method': 'pip', 'option_str': None, 'dict_extra_env': None}},
@@ -47,7 +48,7 @@
'DEFUSEDXML' : {'setup':'defusedxml', 'url':'https://pypi.python.org/packages/source/d/defusedxml/defusedxml-0.4.1.tar.gz', 'local': 'defusedxml-0.4.1.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'DJANGO-TASTYPIE' : {'setup':'django-tastypie', 'url':'https://github.com/toastdriven/django-tastypie/archive/v0.9.15.tar.gz', 'local': 'django-tastypie-0.9.15.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
'DJANGO-CHUNCKED-UPLOADS' : {'setup': 'django-chuncked-uploads', 'url':'https://github.com/IRI-Research/django-chunked-uploads/archive/v0.5.tar.gz', 'local':'django-chunked-uploads-0.5.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
- 'LDT' : {'setup': 'ldt', 'url':'ldt-1.52.6.tar.gz', 'local':'ldt-1.52.6.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
+ 'LDT' : {'setup': 'ldt', 'url':'http://www.iri.centrepompidou.fr/dev/hg/platform/archive/1494fc70a5a2.tar.gz', 'local':'ldt-1.53.1.tar.gz', 'install' : {'method':'pip', 'option_str': None, 'dict_extra_env': None}},
}
if system_str == 'Windows':
Binary file virtualenv/res/src/django-taggit-0.11.2.tar.gz has changed
Binary file virtualenv/res/src/django-taggit-templatetags-d2216c9d1888e0739a04899a36e5149b5cbb3381.zip has changed
Binary file virtualenv/res/src/ldt-1.52.6.tar.gz has changed
Binary file virtualenv/res/src/ldt-1.53.1.tar.gz has changed
--- a/virtualenv/web/res/res_create_env.py Mon Mar 31 16:09:50 2014 +0200
+++ b/virtualenv/web/res/res_create_env.py Wed Apr 16 17:22:05 2014 +0200
@@ -14,7 +14,8 @@
'DJANGO',
'DJANGO-EXTENSIONS',
'DJANGO-REGISTRATION',
- 'DJANGO-TAGGING',
+ 'DJANGO-TAGGIT',
+ 'DJANGO-TAGGIT-TEMPLATETAGS',
'HTTPLIB2',
'OAUTH2',
'SETUPTOOLS_HG',