from django.conf import settings
from django.utils.datastructures import SortedDict
from ldt.ldt_utils.models import Project
import lxml.etree
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):
"""
viewable_contents should contain all contents from project that a user is allowed to see. The settings.FORBIDDDEN_STREAM_URL
will be displayed if a content is not found in viewable_contents, and the real stream will be displayed if it is.
"""
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
self.tags = {}
self.xml_docs = {}
def __get_cutting_title(self, project_id, content_id, ensemble_id, cutting_id):
if not self.xml_docs.has_key(project_id):
project = Project.objects.get(ldt_id=project_id)
doc = lxml.etree.fromstring(project.ldt)
self.xml_docs[project_id] = doc
else:
doc = self.xml_docs[project_id]
cutting = doc.xpath('/iri/annotations/content[@id=\'%s\']/ensemble[@id=\'%s\']/decoupage[@id=\'%s\']/title' % (content_id, ensemble_id, cutting_id))
if not cutting:
return None
cutting = cutting[0]
return cutting.text
def __parse_views(self):
view = {
"id": "0",
"contents": [
self.content.iri_id
],
"annotation_types": [ ],
}
stat = {
"id": "stat",
"contents": [
self.content.iri_id
],
"meta": {
"stat": self.content.stat_annotation
}
}
self.annotation_types = []
annotation_types = []
for seg in self.segments:
title = self.__get_cutting_title(seg.project_id, seg.iri_id, seg.ensemble_id, seg.cutting_id)
annotation_types.append({'id': seg.cutting_id, 'title': title})
for a in annotation_types:
view['annotation_types'].append(a['id'])
self.annotation_types.append({
"dc:contributor": "undefined",
"dc:creator": "undefined",
"dc:title": a['title'],
"id": a['id'],
"dc:created": "",
"dc:description": "",
"dc:modified": ""
})
self.views = [view, stat]
def __parse_content(self):
href = ""
meta_item_value = ""
if "Content" in settings.USE_GROUP_PERMISSIONS and self.content:
if self.content 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_tags = []
for tag in seg.tags.split(';'):
if not self.tags.has_key(tag):
new_tag = {
"meta": {
"dc:contributor": "IRI",
"dc:created": seg.date,
"dc:title": tag,
"dc:modified": seg.date,
"dc:creator": "IRI"
},
"id": unicode(uuid.uuid1())
}
self.tags[tag] = new_tag
segment_tags.append({'id-ref': self.tags[tag]['id']})
segment = {
'begin': seg.start_ts,
'end': seg.start_ts + seg.duration,
'tags': seg.tags,
'id': seg.element_id,
'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': self.default_color,
'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.cutting_id,
"project": seg.project_id
},
'tags': segment_tags
}
self.annotations.append(segment)
def serialize_to_cinelab(self):
if not self.segments:
return None
self.__parse_content()
self.__parse_segments()
self.__parse_views()
res = {}
res['views'] = self.views
res['tags'] = self.tags.values() if len(self.tags) > 0 else None
res['lists'] = None
res['medias'] = self.medias
res['annotations'] = self.annotations
res['annotation-types'] = self.annotation_types
return res