merge all content's projects in one (for decoupage).
authorcavaliet
Tue, 26 Nov 2013 17:05:09 +0100
changeset 1257 d2cc6ecc3aa0
parent 1256 4e8a21d731e0
child 1258 79cca551f9d0
merge all content's projects in one (for decoupage).
src/ldt/ldt/api/ldt/resources/content.py
src/ldt/ldt/ldt_utils/projectserializer.py
src/ldt/ldt/ldt_utils/segmentserializer.py
src/ldt/ldt/ldt_utils/templates/front/front_group.html
src/ldt/ldt/ldt_utils/templates/front/front_home.html
src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html
src/ldt/ldt/ldt_utils/urls.py
src/ldt/ldt/ldt_utils/views/front.py
src/ldt/ldt/static/ldt/css/front_player.css
--- a/src/ldt/ldt/api/ldt/resources/content.py	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/api/ldt/resources/content.py	Tue Nov 26 17:05:09 2013 +0100
@@ -1,10 +1,16 @@
 from django.conf.urls import url
+from django.shortcuts import get_object_or_404
 from itertools import groupby
 from ldt.indexation import get_results_list
-from ldt.ldt_utils.models import Content, Media
+from ldt.ldt_utils.models import Content, Media, Project
+from ldt.ldt_utils.projectserializer import ProjectJsonSerializer, ProjectMerger
+from ldt.security import unprotect_models, protect_models
 from tastypie import fields
 from tastypie.resources import Bundle, ModelResource, ALL_WITH_RELATIONS, ALL
 
+import logging
+logger = logging.getLogger(__name__)
+
 class MediaResource(ModelResource):
     
     class Meta:
@@ -41,6 +47,7 @@
     def prepend_urls(self):
         return [
             url(r"^(?P<resource_name>%s)/recommended/$" % self._meta.resource_name, self.wrap_view('get_recommended'), name="api_contents_recommended"),
+            url(r"^(?P<resource_name>%s)/all/(?P<iri_id>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('get_all_projects'), name="api_content_all_projects"),
             url(r"^(?P<resource_name>%s)/(?P<iri_id>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),            
         ]
 
@@ -80,5 +87,25 @@
         self.log_throttled_access(request)
         
         return  self.create_response(request, object_list)
+    
+    def get_all_projects(self, request, api_name, resource_name, iri_id=None):
+        self.method_check(request, allowed=['get'])
+        content = get_object_or_404(Content, iri_id=iri_id)
+        
+        # Unprotect the time to build the project
+        unprotect_models()
+        
+        projects = Project.objects.filter(contents__in=[content], state=2)
+        pm = ProjectMerger(content, projects)
+        proj = pm.get_merged_project(False)
+        ps = ProjectJsonSerializer(proj)
+        data = ps.serialize_to_cinelab()
+        self.log_throttled_access(request)
+        # Delete project because it is useless to keep it in database
+        proj.delete()
+        
+        protect_models()
+        
+        return self.create_response(request, data)
         
             
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/projectserializer.py	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/projectserializer.py	Tue Nov 26 17:05:09 2013 +0100
@@ -43,7 +43,7 @@
         
         
     def __parse_views(self, display_node_list):
-        logger.debug("__parse_views start")
+        
         for display_node in display_node_list:
             display_id = display_node.get(u"id", None)
             if not display_id:
@@ -94,12 +94,11 @@
                 new_display['annotation_types'] = [new_display['annotation_types'][0]] 
             
             self.views_dict[display_id] = new_display
-        logger.debug("__parse_views done")        
+        
     
     def __parse_ensemble(self, ensemble_node, content, cutting_only=None):
                 
         ensemble_id = ensemble_node.attrib[u"id"]
-        logger.debug("__parse_ensemble %s start" % ensemble_id)
         
         ensemble_author = ensemble_node.attrib[u"author"]
         ensemble_title = ensemble_node.attrib[u"title"]
@@ -321,12 +320,10 @@
             new_list["items"] = None
         self.lists_dict[ensemble_id] = new_list
         
-        logger.debug("__parse_ensemble %s done" % ensemble_id)
 
 
     def __parse_ldt(self):
         
-        logger.debug("__parse_ldt start")
         self.ldt_doc = lxml.etree.fromstring(self.project.ldt_encoded)
         
         if self.from_display:
@@ -343,8 +340,6 @@
             (set(self.ldt_doc.xpath('/iri/annotations/content[ensemble/decoupage/@id=\'%s\']/@id' % self.first_cutting)) if self.first_cutting and self.first_cutting not in self.display_cuttings_list else set())
         )
         
-        logger.debug(contents_iri_id)
-        
         contents =  dict([ (c.iri_id, c) for c in Content.objects.filter(iri_id__in=contents_iri_id).select_related('media_obj', 'stat_annotation').prefetch_related("authors")])
         m_cls = ContentType.objects.get(model='media')
         m_cls = m_cls.model_class()
@@ -399,11 +394,10 @@
         self.__parse_edits()
                                
         self.parsed = True
-        logger.debug("__parse_ldt done")
         
     
     def __parse_edits(self):
-        logger.debug("__parse_edits start")
+        
         editings = self.ldt_doc.xpath("/iri/edits/editing")
         if not editings:
             return False
@@ -438,11 +432,9 @@
                 }
             }
             self.lists_dict[e_id] = new_list
-        logger.debug("__parse_edits done")    
     
     def __parse_content(self, content, medias):
         
-        logger.debug("__parse_content %s start" % content.iri_id)
         doc = lxml.etree.parse(content.iri_file_path())
         
         authors = content.authors.all()
@@ -520,20 +512,14 @@
             res = doc.xpath("/iri/body/ensembles/ensemble")
             for ensemble_node in res:
                 self.__parse_ensemble(ensemble_node, content)
-                
-        logger.debug("__parse_content %s done" % content.iri_id)
 
     
     def serialize_to_cinelab(self):
     
         res = {}
 
-        logger.debug("serialize_to_cinelab before parse ldt")
-                
         if not self.parsed:
-            self.__parse_ldt()    
-
-            logger.debug("serialize_to_cinelab parse ldt done")
+            self.__parse_ldt()
         
         project_main_media = ""
         if len(self.medias_dict) > 0:
@@ -636,7 +622,7 @@
             media.set('id', medias[0]['id'])
                 
             ens = lxml.etree.SubElement(media, 'ensemble')
-            ens.set('title', 'Decoupages personnels') 
+            ens.set('title', 'Decoupages personnels')
             ens.set('idProject', project.ldt_id)
             ens.set('abstract', '')
             ens.set('id', 'g_' + str(uuid.uuid1()))
@@ -644,7 +630,7 @@
             for i in annotation_types:
                 cutting_infos = {'desc' : i['meta']['description']}
                 
-                dec = lxml.etree.SubElement(ens, 'decoupage') 
+                dec = lxml.etree.SubElement(ens, 'decoupage')
                 dec.set('author', contributor)
                 dec.set('id', 'c_' + str(uuid.uuid1()))
                 elements_list = lxml.etree.SubElement(dec, 'elements')
@@ -684,3 +670,65 @@
         project.save()
         
         return project.ldt
+
+
+"""
+Merge several projects in one for a given content. All ensembles are copied into one project
+"""
+class ProjectMerger:
+    
+    def __init__(self, content, projects):
+        self.content = content
+        self.projects = projects
+        
+    def get_merged_project(self, shot_by_shot=True):
+        # New project
+        contents = [ self.content, ]
+        
+        # Get user
+        user = User.objects.get(username="admin")
+        
+        proj = Project.create_project(title="Merged project",
+                     user=user, contents=contents, 
+                     description=u"", set_icon=False)
+        
+        doc = lxml.etree.fromstring(proj.ldt_encoded)
+        annot_node = doc.xpath("/iri/annotations")[0]
+        content_node = lxml.etree.SubElement(annot_node, 'content')
+        content_node.set('id', self.content.iri_id)
+        display_node = doc.xpath('/iri/displays/display')[0]
+        ctt_disp_node = display_node.xpath('content[@id="' + self.content.iri_id + '"]')[0]
+        # remove shot by shot from display
+        if not shot_by_shot:
+            dec_node = ctt_disp_node.xpath('decoupage[@id="de_PPP"]')[0]
+            if dec_node is not None:
+                ctt_disp_node.remove(dec_node)
+        
+        # Parse all projects
+        for p in self.projects:
+            p_xml = lxml.etree.fromstring(p.ldt_encoded)
+            # First version of ensemble
+            ens = p_xml.xpath('/iri/annotations/content[@id="' + self.content.iri_id + '"]/ensemble')
+            for e in ens:
+                content_node.append(e)
+                # Update display
+                for c in e.xpath('decoupage'):
+                    c_node = lxml.etree.SubElement(ctt_disp_node, 'decoupage')
+                    c_node.set(u'idens', e.get('id'))
+                    c_node.set(u'id', c.get('id'))
+            # Second version of ensemble
+            ens = p_xml.xpath('/iri/annotations/content[@id="' + self.content.iri_id + '"]/ensembles/ensemble')
+            for e in ens:
+                content_node.append(e)
+                # Update display
+                for c in e.xpath('decoupage'):
+                    c_node = lxml.etree.SubElement(ctt_disp_node, 'decoupage')
+                    c_node.set(u'idens', e.get('id'))
+                    c_node.set(u'id', c.get('id'))
+                
+        
+        proj.ldt = lxml.etree.tostring(doc, pretty_print=True)
+        
+        return proj
+        
+        
--- a/src/ldt/ldt/ldt_utils/segmentserializer.py	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/segmentserializer.py	Tue Nov 26 17:05:09 2013 +0100
@@ -98,8 +98,7 @@
         
         url = ""
         meta_item_value = ""
-         
-        logger.debug("__parse_content start")   
+        
         if use_forbidden_url(self.content):
             url = settings.FORBIDDEN_STREAM_URL
         elif self.content.videopath:
@@ -108,8 +107,6 @@
         else:
             url = self.content.src
         
-        logger.debug("__parse_content url %s " % url)
-        
         media = {
              "http://advene.liris.cnrs.fr/ns/frame_of_reference/ms" : "o=0",
              "id" : self.content.iri_id,
@@ -195,16 +192,12 @@
     
     def serialize_to_cinelab(self):
         
-        logger.debug("serialize_to_cinelab start")
         if not self.segments:
             return None
         
         self.__parse_content()
-        logger.debug("serialize_to_cinelab parse content done")
         self.__parse_segments()
-        logger.debug("serialize_to_cinelab parse segments done")
         self.__parse_views()
-        logger.debug("serialize_to_cinelab parse views done")
         
         res = {}
         res['views'] = self.views 
@@ -214,7 +207,5 @@
         res['annotations'] = self.annotations
         res['annotation-types'] = self.annotation_types
         
-        logger.debug("serialize_to_cinelab done")
-        
         return res
     
\ No newline at end of file
--- a/src/ldt/ldt/ldt_utils/templates/front/front_group.html	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_group.html	Tue Nov 26 17:05:09 2013 +0100
@@ -89,9 +89,9 @@
     </li>
     {% for content in content_list %}
     <li class="li_media">
-        <a href="{% url 'ldt.ldt_utils.views.front.annot_content' content.iri_id %}">{% thumbnail content.image "134x75" format="PNG" crop="center" as im %}<img src="{{ im.url }}" class="img_media" width="{{ im.width }}" height="{{ im.height }}" alt="{% trans 'open this media' %}" title="{% trans 'open this media' %}">{% endthumbnail %}</a>
+        <a href="{% url 'ldt.ldt_utils.views.front.all_projects_for_media' content.iri_id %}">{% thumbnail content.image "134x75" format="PNG" crop="center" as im %}<img src="{{ im.url }}" class="img_media" width="{{ im.width }}" height="{{ im.height }}" alt="{% trans 'open this media' %}" title="{% trans 'open this media' %}">{% endthumbnail %}</a>
         <div class="bulle_annot" title="{% blocktrans count nb=content.nb_annotations %}{{nb}} annotation on this media{% plural %}{{nb}} annotations on this media{% endblocktrans %}">{{content.nb_annotations}}</div>
-        <p><a href="{% url 'ldt.ldt_utils.views.front.annot_content' content.iri_id %}" title="{% trans 'open this media' %}"><b>{% if content.title|length > 69 %}{{content.title|slice:":69"}}...{% else %}{{content.title}}{% endif %}</b></a></p>
+        <p><a href="{% url 'ldt.ldt_utils.views.front.all_projects_for_media' content.iri_id %}" title="{% trans 'open this media' %}"><b>{% if content.title|length > 69 %}{{content.title|slice:":69"}}...{% else %}{{content.title}}{% endif %}</b></a></p>
         <p class="font_11">{% trans 'by' %} IRI | {{content.duration|str_duration:"h"}}</p>
     </li>
     {% endfor %}
--- a/src/ldt/ldt/ldt_utils/templates/front/front_home.html	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/front/front_home.html	Tue Nov 26 17:05:09 2013 +0100
@@ -109,11 +109,11 @@
     {% for group in active_groups %}
     <li class="li_media">
         <div class="img_groupes_actifs">
-            <a href="{% url 'ldt.ldt_utils.views.front.group_info' group_id=group.id %}">{% thumbnail group.get_profile.image "54x40" format="PNG" crop="center" as im %}<img src="{{ im.url }}" class="img_media" width="{{ im.width }}" height="{{ im.height }}" alt="{% trans 'group picture' %}" title="{% trans 'view more infos on this group'%}">{% endthumbnail %}</a>
+            <a href="{% url 'ldt.ldt_utils.views.front.group_medias' group_id=group.id %}">{% thumbnail group.get_profile.image "54x40" format="PNG" crop="center" as im %}<img src="{{ im.url }}" class="img_media" width="{{ im.width }}" height="{{ im.height }}" alt="{% trans 'group picture' %}" title="{% trans 'view more infos on this group'%}">{% endthumbnail %}</a>
         </div>
         <div class="txt_groupes_actifs">
             <div class="bulle_people" title="{% blocktrans count nb=group.nb_users %}{{nb}} user in this group{% plural %}{{nb}} users in this group{% endblocktrans %}">{{ group.nb_users }}</div>
-            <p><a href="{% url 'ldt.ldt_utils.views.front.group_info' group_id=group.id %}" class="under" title="{% trans 'view more infos on this group'%}"><b>{{group.name}}</b></a></p>
+            <p><a href="{% url 'ldt.ldt_utils.views.front.group_medias' group_id=group.id %}" class="under" title="{% trans 'view more infos on this group'%}"><b>{{group.name}}</b></a></p>
             <p>{% if group.get_profile.description|striptags|length > 69 %}{{group.get_profile.description|striptags|slice:":69"}}...{% else %}{{group.get_profile.description|striptags}}{% endif %}</p>
         </div>
     </li>
--- a/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html	Tue Nov 26 17:05:09 2013 +0100
@@ -40,7 +40,7 @@
     {% if external_url %}
             video: "{{ external_url }}",
     {% endif %}
-            height: 300,
+            height: {% if player_height %}{{ player_height }}{% else %}300{% endif %},
             autostart: true,
             url_transform: function(url) {
                 // Adaptation to jwplayer 6
--- a/src/ldt/ldt/ldt_utils/urls.py	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/urls.py	Tue Nov 26 17:05:09 2013 +0100
@@ -46,6 +46,7 @@
     url(r'^front/groups/$', 'views.front.group_list'),
     url(r'^front/group/(?P<group_id>.*)/medias/$', 'views.front.group_medias'),
     url(r'^front/group/(?P<group_id>.*)/$', 'views.front.group_info'),
+    url(r'^front/player/all/(?P<content_iri_id>.*)/$', 'views.front.all_projects_for_media'),
     url(r'^front/player/(?P<content_iri_id>.*)/$', 'views.front.annot_content'),
     url(r'^front/player/(?P<content_iri_id>.*)/(?P<project_id>.*)/(?P<cutting_id>.*)$', 'views.front.annot_content'),
     url(r'^front/player/(?P<content_iri_id>.*)/(?P<project_id>.*)$', 'views.front.annot_content', name='front_player_content_project'),
--- a/src/ldt/ldt/ldt_utils/views/front.py	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/ldt_utils/views/front.py	Tue Nov 26 17:05:09 2013 +0100
@@ -104,6 +104,7 @@
                               context_instance=RequestContext(request))
 
 
+
 def all_contents(request):
     # Get the page number parameter if possible
     page = request.GET.get("page") or 1
@@ -186,6 +187,40 @@
                               context_instance=RequestContext(request))
 
 
+
+
+def all_projects_for_media(request, content_iri_id):
+        # Get the wanted content
+    content = Content.objects.get(iri_id=content_iri_id)
+    # Get the content src to see if it is a youtube/dailymotion video
+    annotation_block = False
+    external_url = None
+    if content.src is not None:
+        for external_src in settings.EXTERNAL_STREAM_SRC:
+            if  external_src in content.src:
+                external_url = content.src
+                break
+               
+    # Vars for player
+    player_id = "player_project_anything"
+    
+    json_url = reverse("api_content_all_projects", kwargs={'api_name': '1.0', 'resource_name': 'contents', 'iri_id': content_iri_id})
+    
+    player_width = 854
+    player_height = 480
+    stream_mode = "video"
+    
+    is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1)
+
+
+    return render_to_response("front/front_player.html",
+                              {'content': content, 'player_id': player_id, 
+                              'json_url': json_url, 'player_width':player_width, 'player_height':player_height, 'stream_mode':stream_mode, 'external_url':external_url,
+                               'is_gecko': is_gecko, 'annotation_block':annotation_block},
+                              context_instance=RequestContext(request))
+
+
+
 def search_index(request):
     language_code = request.LANGUAGE_CODE[:2]
     nb = 0
@@ -211,4 +246,4 @@
     return render_to_response('front/front_search_results.html', {'results': results, 'nb_results' : nb, 'nb_segment':nb_segment, 'search' : search, 'field': field, 'tag_label':content_tag, 'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code, 'baseurl': baseurl}, context_instance=RequestContext(request))
 
 
-
+    
\ No newline at end of file
--- a/src/ldt/ldt/static/ldt/css/front_player.css	Tue Nov 19 17:59:07 2013 +0100
+++ b/src/ldt/ldt/static/ldt/css/front_player.css	Tue Nov 26 17:05:09 2013 +0100
@@ -1,5 +1,5 @@
 #player_col_g {
-    float: left; width: 550px; margin: 10px 0;
+    float: left; margin: 10px 0;/* width: 550px;*/
 }
 
 #top_media {