Merging with upstream
authorhamidouk
Wed, 18 Jan 2012 15:36:26 +0100
changeset 414 6fb6d534009a
parent 413 5a0ee726d342 (current diff)
parent 412 8d777b1d1d92 (diff)
child 416 b512f69a474a
child 417 324f5fab9eca
Merging with upstream
--- a/src/ldt/ldt/api/ldt/handlers.py	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/api/ldt/handlers.py	Wed Jan 18 15:36:26 2012 +0100
@@ -1,9 +1,11 @@
-from ldt.ldt_utils.models import Project, Content
+from ldt.ldt_utils.models import Project, Content, Segment
+from django.db.models import F, Q
 from piston.handler import BaseHandler
 from piston.utils import rc, require_extended
 from ldt.ldt_utils.utils import LdtAnnotation
 from ldt.ldt_utils.stat import add_annotation_to_stat
 from ldt.security.utils import protect_instance, unprotect_instance
+from ldt.ldt_utils.segmentserializer import SegmentSerializer
 import logging #@UnresolvedImport
 
 
@@ -222,3 +224,27 @@
         """
         return Content.objects.get(iri_id=iri_id)
     
+
+class SegmentHandler(BaseHandler):
+    allowed_methods = ('GET', )
+    model = Segment
+    exclude = (
+               ("project_obj"),
+               ("content"),
+               )
+    
+    def read(self, request, iri_id, begin, end):
+        """
+        returns a single Segment
+        """
+        
+        content = Content.objects.get(iri_id=iri_id)
+        segments = Segment.objects.filter(content=content).filter(
+                    Q(start_ts__gt=begin, start_ts__lt=end) |                            # segment start between begin and end
+                    Q(start_ts__gt=begin-F('duration'), start_ts__lt=end-F('duration')) |# segment ends between begin and end
+                    Q(start_ts__lt=begin, start_ts__gt=end-F('duration'))                # period [begin:end] is included in the segment
+                    )
+        
+        a = SegmentSerializer(content, segments, viewable_contents=[content.iri_id])
+        return a.serialize_to_cinelab()
+    
--- a/src/ldt/ldt/api/ldt/urls.py	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/api/ldt/urls.py	Wed Jan 18 15:36:26 2012 +0100
@@ -1,12 +1,15 @@
 from django.conf.urls.defaults import patterns, url
 from piston.resource import Resource
-from ldt.api.ldt.handlers import ProjectHandler, ContentHandler
+from ldt.api.ldt.handlers import ProjectHandler, ContentHandler, SegmentHandler
 
 project_handler = Resource(ProjectHandler, None)
 content_handler = Resource(ContentHandler, None)
+segment_handler = Resource(SegmentHandler, None)
 
 urlpatterns = patterns('',
     url(r'projects/(?P<project_id>[^/.]+)\.?(?P<emitter_format>.*)$', project_handler, name='project_api'),
     url(r'contents/(?P<iri_id>[^/.]+)\.?(?P<emitter_format>.*)$', content_handler, name='content_api'),
+    url(r'segments/(?P<iri_id>.*)/(?P<begin>\d+)/(?P<end>\d+)$', segment_handler),
 )
 
+
--- a/src/ldt/ldt/ldt_utils/models.py	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/models.py	Wed Jan 18 15:36:26 2012 +0100
@@ -18,6 +18,7 @@
 import mimetypes
 import os.path
 import tagging.fields
+from tagging.models import Tag
 import uuid
 
 
@@ -364,12 +365,16 @@
             admin = User.objects.filter(is_superuser=True)[0]
             
         set_current_user(admin)
-        self.front_project = Project.create_project(admin, 'front project : %s' % self.title, [self], cuttings=['chapitrage', 'contribution'] )
+        self.front_project = Project.create_project(admin, 'front project : %s' % self.title, [self], cuttings=['chapitrage', 'contributions'] )
         self.front_project.publish(allow_write=True)
         set_current_user(request_user)
             
         assign('ldt_utils.change_content', request_user, self)
         self.save()
+    
+    # Tag management
+    def get_tags(self):
+        return Tag.objects.get_for_object(self)
 
 
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ldt/ldt/ldt_utils/segmentserializer.py	Wed Jan 18 15:36:26 2012 +0100
@@ -0,0 +1,143 @@
+from django.conf import settings
+from django.utils.datastructures import SortedDict
+import uuid
+
+DATE_FORMATS = ["%d/%m/%Y", "%Y-%m-%d"]
+
+class SegmentSerializer(object):
+    """
+    Serialize a set of annotations to a cinelab compatible array
+    """
+    
+    def __init__(self, content, segments, viewable_contents=[], default_color=2194379):
+        self.content = content
+        self.segments = segments
+        self.viewable_contents = viewable_contents
+        self.default_color = default_color
+        self.views = None
+        self.annotation_types = None
+        self.medias = None
+        self.annotations = None
+        
+    
+    def __parse_views(self):
+        
+        view = {
+                "id": "0",
+                "contents": [
+                    self.content.iri_id
+                ],
+                "annotation_types": [ ],
+        }
+        
+        self.annotation_types = []
+        annotation_types = [seg.cutting_id for seg in self.segments]
+        for a in annotation_types:
+            view['annotation_types'].append(a)
+            self.annotation_types.append({
+                    "dc:contributor": "undefined",
+                    "dc:creator": "undefined",
+                    "dc:title": "cutting %s" % a,
+                    "id": "%s" % a,
+                    "dc:created": "",
+                    "dc:description": "",
+                    "dc:modified": ""
+                })
+        
+        self.views = [view]
+        
+    
+    def __parse_content(self):
+        
+        href = ""
+        meta_item_value = ""
+        if self.content.iri_id not in self.viewable_contents:
+            href = settings.FORBIDDEN_STREAM_URL
+        elif self.content.videopath:
+            href = self.content.videopath.rstrip('/') + "/" + self.content.src
+            meta_item_value = self.content.videopath.rstrip('/') + "/"
+        else:
+            href = self.content.src
+        
+        media = {
+             "http://advene.liris.cnrs.fr/ns/frame_of_reference/ms" : "o=0",
+             "id" : self.content.iri_id,
+             "href" : href,
+             "unit" : "ms",
+             "origin" : "0",
+             "meta": {
+                 "dc:creator" : "",
+                 "dc:created" : self.content.creation_date.isoformat(),
+                 "dc:contributor" : "",
+                 "dc:modified" : self.content.update_date.isoformat(),
+                 "dc:creator.contents" : "",
+                 "dc:title" : self.content.title,
+                 "dc:description" : self.content.description,
+                 "dc:duration" : self.content.get_duration(),
+                 "item": {
+                     "name" : "streamer",
+                     "value": meta_item_value,
+                 },
+             }
+        }
+        
+        self.medias = [media]
+        
+    
+    def __parse_segments(self):
+        
+        self.annotations = []
+        
+        for seg in self.segments:
+            
+            segment = {
+                'begin': seg.start_ts,
+                'end': seg.start_ts + seg.duration,
+                'tags': seg.tags,
+                'id': "s_%s" % unicode(uuid.uuid1()),
+                'color': "%s" % self.default_color,
+                'media': self.content.iri_id,
+                'content': {
+                    'mimetype': 'application/x-ldt-structured',
+                    'description': seg.abstract,
+                    'img': {
+                        'src': ''
+                    },
+                    'title': seg.title,
+                    'color': '2194379',
+                    'polemics': [ ],
+                    'audio': {
+                        'mimetype': 'audio/mp3',
+                        'src': '',
+                        'href': 'null'
+                    }
+                
+                },
+                'meta': {
+                         "dc:creator": seg.author,
+                         "dc:contributor": seg.author,
+                         "dc:created": seg.date,
+                         "dc:modified": seg.date,
+                         "id-ref": seg.iri_id,
+                         "project": seg.project_id
+                         }
+            }
+            
+            self.annotations.append(segment)
+    
+    def serialize_to_cinelab(self):
+        
+        self.__parse_content()
+        self.__parse_segments()
+        self.__parse_views()
+        
+        res = {}
+        res['views'] = self.views 
+        res['tags'] = None
+        res['lists'] = None
+        res['medias'] = self.medias
+        res['annotations'] = self.annotations
+        res['annotation-types'] = self.annotation_types
+        
+        return res
+    
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/stat.py	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/stat.py	Wed Jan 18 15:36:26 2012 +0100
@@ -1,5 +1,5 @@
 from django.conf import settings
-from ldt.ldt_utils.models import AnnotationStat, Project
+from ldt.ldt_utils.models import AnnotationStat, Project, Segment
 from django.db.models.signals import pre_delete
 import lxml.etree
 import datetime
@@ -14,11 +14,11 @@
         doc = lxml.etree.fromstring(project.ldt)
 
     number_division = settings.DIVISIONS_FOR_STAT_ANNOTATION
-    contributions = AnnotationStat.objects.filter(project=project)    
+    contributions = list(AnnotationStat.objects.filter(project=project))    
         
     for content_node in doc.xpath('/iri/annotations/content'):
         content_name = content_node.get('id')
-        content = contents.filter(iri_id=content_name)
+        content = filter_list(contents, 'iri_id', content_name)
         
         # if the content referenced in the xml belongs to the
         # fields contents of the project
@@ -121,7 +121,7 @@
     content.last_annotated = datetime.datetime.now()
     content.save()    
 
-
+import uuid
 def add_annotation_to_stat(content, project, begin, end):
     contribution_project = AnnotationStat.objects.get(project=project, content=content)
     
@@ -131,6 +131,20 @@
         contribution_project.nb_annotation += 1
     content.nb_annotation += 1
     
+#    print "before segment creation"
+#    s = Segment(project_obj=project,
+#                content=content,
+#                project_id=project.ldt_id,
+#                iri_id=content.iri_id,
+#                ensemble_id='%s' % unicode(uuid.uuid1()),
+#                cutting_id='t',    
+#                element_id='a',
+#                duration=end-begin,
+#                start_ts=begin)
+#    s.save()
+#    print s.id
+#    print "segment created"
+    
     if contribution_project.stat:
         
         number_division = settings.DIVISIONS_FOR_STAT_ANNOTATION
@@ -147,7 +161,12 @@
     content.last_annotated = datetime.datetime.now()
     content.save()
     contribution_project.save()
-
     
 
-    
\ No newline at end of file
+def filter_list(list, criteria, value):
+    new_list = []
+    for l in list:
+        if getattr(l, criteria) == value:
+            new_list.append(l)
+    
+    return new_list
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/templates/front/front_all_contents.html	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_all_contents.html	Wed Jan 18 15:36:26 2012 +0100
@@ -63,9 +63,11 @@
 {% block body %}
 {{block.super}}
 <!-- Last annotated contents -->
+{% if tag_cloud|length > 0 %}<p class="tag_link">{% trans 'Filter the medias' %} : {% for t in tag_cloud|slice:":5" %}<a href="{% url ldt.ldt_utils.views.front.all_contents %}?tag={{t.name}}">{{t.name}}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>{% endif %}
 <ul class="floatlist full_width" id="derniers_medias">
     <li class="li_h2">
-        <h2>{% trans 'All medias' %}</h2>
+        {% if tag_label %}<h2><a href="{% url ldt.ldt_utils.views.front.all_contents %}">{% trans 'All medias' %}</a>{% if tag_label %}<span class="pink"> &gt; {{tag_label}}</span>{% endif %}</h2>
+        {% else %}<h2>{% trans 'All medias' %}</h2>{% endif %}
     </li>
     {% for content in content_list %}
     <li class="li_media">
@@ -77,5 +79,9 @@
     </li>
     {% endfor %}
 </ul>
+{% if tag_cloud|length > 0 %}<p class="left tag_link">{% trans 'All tags' %} : {% for t in tag_cloud %}<a href="{% url ldt.ldt_utils.views.front.all_contents %}?tag={{t.name}}">
+  <span style="font-size:{{t.font_size|add:"10"}}px;">{{t.name}}</span>
+  </a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
+{% endif %}
 {% endblock %}
 
--- a/src/ldt/ldt/ldt_utils/templates/front/front_base.html	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_base.html	Wed Jan 18 15:36:26 2012 +0100
@@ -34,10 +34,11 @@
             </form>
         <li id="li_annotation">
             <div class="fl">
-                <a href="#"><img src="{{LDT_MEDIA_PREFIX}}img/annot_icon.png" id="annot_icon" /></a>
+                <!-- a href="#"><img src="{{LDT_MEDIA_PREFIX}}img/annot_icon.png" id="annot_icon" /></a -->
+                <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a>
             </div>
             <div class="fl">
-                <a href="{% url root-view %}">{% trans 'Annotate' %}</a>
+                <!-- a href="{% url root-view %}">{% trans 'Annotate' %}</a -->
             </div>
         </li>
         <li id="li_connexion">
--- a/src/ldt/ldt/ldt_utils/templates/front/front_home.html	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_home.html	Wed Jan 18 15:36:26 2012 +0100
@@ -14,6 +14,7 @@
 {% block body %}
 {{block.super}}
 <!-- Last annotated contents -->
+{% if tag_cloud|length > 0 %}<p class="tag_link">{% trans 'Filter the medias' %} : {% for t in tag_cloud %}<a href="{% url ldt.ldt_utils.views.front.all_contents %}?tag={{t.name}}">{{t.name}}</a>{% if not forloop.last %}, {% endif %}{% endfor %}</p>{% endif %}
 <ul class="floatlist full_width" id="derniers_medias">
     <li class="li_h2">
       <ul class="title_ul">
--- a/src/ldt/ldt/ldt_utils/views/content.py	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/views/content.py	Wed Jan 18 15:36:26 2012 +0100
@@ -70,6 +70,9 @@
         media_form = MediaForm(media_instance_val, request.FILES, prefix="media", instance=instance_media)
         picture_form = PictureForm(None, request.POST, request.FILES)
         
+        if request.user.is_staff:
+            content_form.fields['front_project'].queryset = Project.objects.filter(contents__in=[instance_content])
+        
         media_valid = media_form.is_valid()
         content_valid = content_form.is_valid()
         picture_valid = picture_form.is_valid()
@@ -288,7 +291,7 @@
         img_container = ''
     
     session_key = request.COOKIES[settings.SESSION_COOKIE_NAME]
-    cookie_name = settings.SESSION_COOKIE_NAME    
+    cookie_name = settings.SESSION_COOKIE_NAME
     content_form.fields["media_obj"].queryset = Media.safe_objects.all()
     
     return render_to_response('ldt/ldt_utils/create_content.html', {'content_form': content_form, 'media_form': media_form, 'form_status': form_status, 'create_content_action': create_content_action,
--- a/src/ldt/ldt/ldt_utils/views/front.py	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/ldt_utils/views/front.py	Wed Jan 18 15:36:26 2012 +0100
@@ -9,6 +9,7 @@
 from ldt.ldt_utils.models import Content, Project
 from ldt.ldt_utils.views.workspace import search_index as ws_search_index, search_listing as ws_search_listing
 from ldt.security.utils import add_change_attr
+from tagging.models import Tag, TaggedItem
 
 
 @login_required
@@ -19,12 +20,13 @@
     most_contents = Content.objects.order_by('-nb_annotation')[:8]
     # Get the active groups
     active_groups = Group.objects.exclude(name=settings.PUBLIC_GROUP_NAME)[:5]
-    
+    # Get the main tag list
+    tag_cloud = get_content_tags(5)
     
     is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
 
     return render_to_response("front/front_home.html",
-                              {'last_contents': last_contents, 'most_contents':most_contents, 'active_groups':active_groups,
+                              {'last_contents': last_contents, 'most_contents':most_contents, 'active_groups':active_groups, 'tag_cloud':tag_cloud,
                                'is_gecko': is_gecko},
                               context_instance=RequestContext(request))
 
@@ -49,13 +51,20 @@
 
 @login_required
 def all_contents(request):
+    # Get the tag parameter if possible
+    tag_label = request.GET.get("tag")
     # Get all the public contents group
-    content_list = add_change_attr(request.user, Content.safe_objects.all())
+    if tag_label is None :
+        content_list = add_change_attr(request.user, Content.safe_objects.all())
+    else :
+        content_list = TaggedItem.objects.get_by_model(add_change_attr(request.user, Content.safe_objects.all()), '"'+tag_label+'"')
+    # Get the main tag list
+    tag_cloud = get_content_tags()
     
     is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
 
     return render_to_response("front/front_all_contents.html",
-                              {'content_list':content_list, 
+                              {'content_list':content_list, 'tag_label':tag_label, 'tag_cloud':tag_cloud,
                                'is_gecko': is_gecko},
                               context_instance=RequestContext(request))
 
@@ -79,7 +88,7 @@
             proj = Project.safe_objects.filter(contents__in=[content])[0]
     else :
         proj = Project.safe_objects.get(ldt_id=project_id)
-        
+    
     # Vars for player
     player_id = "player_project_" + proj.ldt_id
     
@@ -111,3 +120,13 @@
 @login_required
 def search_listing(request):
     return ws_search_listing(request, front_template=True)
+
+
+def get_content_tags(limit=None, steps=10):
+    if limit is None:
+        return Tag.objects.cloud_for_model(Content, steps=steps)
+    else :
+        return Tag.objects.cloud_for_model(Content, steps=steps)[:limit]
+
+
+    
--- a/src/ldt/ldt/static/ldt/css/front_common.css	Wed Jan 18 15:36:03 2012 +0100
+++ b/src/ldt/ldt/static/ldt/css/front_common.css	Wed Jan 18 15:36:26 2012 +0100
@@ -55,7 +55,7 @@
     font-family: "DIN-Bold", Helvetica, Arial, sans-serif;
 }
 
-h2 {
+h2, h2 a {
     font-family: "DIN-Light", Helvetica, Arial, sans-serif; font-size: 21px; color: #0068c4; margin: 4px 2px;
 }
 
@@ -182,7 +182,7 @@
 /* Barre de titre */
 
 #title_bar {
-    font-family: "DIN-Light", Helvetica, Arial, sans-serif; height: 50px; font-size: 22px; margin: 0 0 1px 0;
+    font-family: "DIN-Light", Helvetica, Arial, sans-serif; height: 50px; font-size: 22px; margin: 0 0 1px 0; width: 980px;
 }
 
 #title_bar a {
@@ -213,6 +213,18 @@
     margin: 3px 10px 0 0;
 }
 
+/* Link for media tag/filter */
+.tag_link {
+    float:right;
+}
+.tag_link a {
+    color: #ff3b77;
+}
+.left {
+    float: left;
+}
+
+
 
 /* Footer */