# HG changeset patch # User cavaliet # Date 1385481909 -3600 # Node ID d2cc6ecc3aa05a7a0b1761cd1356cb4dfd5b34a2 # Parent 4e8a21d731e097fd9d3db61153322edebee58014 merge all content's projects in one (for decoupage). diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/api/ldt/resources/content.py --- 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%s)/recommended/$" % self._meta.resource_name, self.wrap_view('get_recommended'), name="api_contents_recommended"), + url(r"^(?P%s)/all/(?P[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('get_all_projects'), name="api_content_all_projects"), url(r"^(?P%s)/(?P[\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 diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/projectserializer.py --- 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 + + diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/segmentserializer.py --- 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 diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/templates/front/front_group.html --- 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 @@ {% for content in content_list %}
  • - {% thumbnail content.image "134x75" format="PNG" crop="center" as im %}{% trans 'open this media' %}{% endthumbnail %} + {% thumbnail content.image "134x75" format="PNG" crop="center" as im %}{% trans 'open this media' %}{% endthumbnail %}
    {{content.nb_annotations}}
    -

    {% if content.title|length > 69 %}{{content.title|slice:":69"}}...{% else %}{{content.title}}{% endif %}

    +

    {% if content.title|length > 69 %}{{content.title|slice:":69"}}...{% else %}{{content.title}}{% endif %}

    {% trans 'by' %} IRI | {{content.duration|str_duration:"h"}}

  • {% endfor %} diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/templates/front/front_home.html --- 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 %}
  • {{ group.nb_users }}
    -

    {{group.name}}

    +

    {{group.name}}

    {% if group.get_profile.description|striptags|length > 69 %}{{group.get_profile.description|striptags|slice:":69"}}...{% else %}{{group.get_profile.description|striptags}}{% endif %}

  • diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/templates/ldt/ldt_utils/partial/embed_player.html --- 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 diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/urls.py --- 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.*)/medias/$', 'views.front.group_medias'), url(r'^front/group/(?P.*)/$', 'views.front.group_info'), + url(r'^front/player/all/(?P.*)/$', 'views.front.all_projects_for_media'), url(r'^front/player/(?P.*)/$', 'views.front.annot_content'), url(r'^front/player/(?P.*)/(?P.*)/(?P.*)$', 'views.front.annot_content'), url(r'^front/player/(?P.*)/(?P.*)$', 'views.front.annot_content', name='front_player_content_project'), diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/ldt_utils/views/front.py --- 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 diff -r 4e8a21d731e0 -r d2cc6ecc3aa0 src/ldt/ldt/static/ldt/css/front_player.css --- 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 {