merge all content's projects in one (for decoupage).
--- 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 {