--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/ldt/ldt_utils/projectserializer.py Thu Jun 10 04:15:15 2010 +0200
@@ -0,0 +1,290 @@
+import xml.dom
+import Ft.Xml.Domlette
+import xml.xpath
+from datetime import datetime
+
+"""
+Serialize a project object to a cinelab compatible array
+"""
+class ProjectSerializer:
+
+ def __init__(self, project):
+ self.project = project
+ self.ldt_doc = None
+ self.medias = []
+ self.annotations = []
+ self.tags = {}
+ self.annotation_types = []
+ self.views = []
+ self.lists = []
+
+
+ def __parse_ensemble(self, ensemble_node, content):
+
+ ensemble_id = ensemble_node.getAttributeNS("id",None)
+ ensemble_author = ensemble_node.getAttributeNS("author",None)
+ ensemble_title = ensemble_node.getAttributeNS("title",None)
+ ensemble_description = ensemble_node.getAttributeNS("abstract",None)
+ ensemble_created = datetime.utcnow().iso_format()
+ ensemble_modified = ensemble_created
+
+ list_items = []
+ new_list = {
+ "id" : ensemble_id,
+ "items" : list_items,
+ "metas" : {
+ "dc:creator":ensemble_author,
+ "dc:created": ensemble_created,
+ "dc:contributor":"undefined",
+ "dc:modified": ensemble_modified,
+ "dc:title":ensemble_title,
+ "dc:description": ensemble_description,
+ "id-ref":content.iri_id,
+ "editable":"false"
+ }
+ }
+
+ self.lists.append(new_list)
+
+ for decoupage_node in ensemble_node.childNodes:
+ if decoupage_node.nodeType != xml.dom.Node.ELEMENT_NODE or decoupage_node.tagName != "decoupage" :
+ continue
+
+ decoupage_id = decoupage_node.getAttributeNS("id",None)
+ decoupage_creator = decoupage_node.getAttributeNS("author",None)
+ if not decoupage_creator:
+ decoupage_creator = "IRI"
+ decoupage_contributor = decoupage_creator
+ date_str = decoupage_node.getAttributeNS("date",None)
+ if date_str :
+ decoupage_created = datetime.strptime(date_str,"%d/%m/%Y").iso_format()
+ else :
+ decoupage_created = datetime.utcnow().iso_format()
+ decoupage_modified = decoupage_created
+
+ decoupage_title = ""
+ for txtRes in xml.xpath.Evaluate("title/text()", decoupage_node):
+ decoupage_title += txtRes.data
+
+ decoupage_description = ""
+ for txtRes in xml.xpath.Evaluate("abstract/text()", decoupage_node):
+ decoupage_description += txtRes.data
+
+
+
+ list_items.append({"id-ref":decoupage_id})
+
+ new_annotation_types = {
+ "id":decoupage_id,
+ "dc:creator":decoupage_creator,
+ "dc:created":decoupage_created,
+ "dc:contributor":decoupage_contributor,
+ "dc:modified":decoupage_modified,
+ "dc:title":decoupage_title,
+ "dc:description":decoupage_description
+ }
+
+ self.annotation_types.append(new_annotation_types)
+
+ res = xml.xpath.Evaluate("elements/element", decoupage_node)
+ for element_node in res:
+
+ element_id = element_node.getAttributeNS("id",None)
+ element_begin = element_node.getAttributeNS("begin",None)
+ element_duration = element_node.getAttributeNS("dur",None)
+ element_media = content.iri_id
+ element_color = element_node.getAttributeNS("color",None)
+
+ element_title = ""
+ for txtRes in xml.xpath.Evaluate("title/text()", element_node):
+ element_title += txtRes.data
+
+ element_description = ""
+ for txtRes in xml.xpath.Evaluate("abstract/text()", element_node):
+ element_description += txtRes.data
+
+ element_audio_src = ""
+ element_audio_href = ""
+ res = xml.xpath.Evaluate("audio", element_node)
+ if len(res) > 0:
+ element_audio_src = res[0].getAttributeNS(None, "source")
+ element_audio_href = res[0].value
+
+
+ element_tags = []
+
+ tags = element_node.getAttributeNS("tags",None)
+
+ tags_list = map(lambda s:s.trim(),tags.split(","))
+
+ #tags
+ if tags is None or len(tags) == 0:
+ tags_list = []
+ restagnode = xml.xpath.Evaluate("tag/text()", element_node)
+ for tagnode in restagnode:
+ tags_list.append(tagnode.data)
+
+ if tags_list is None or len(tags_list) == 0:
+ tags_list = []
+ restagnode = xml.xpath.Evaluate("tags/tag/text()", element_node)
+ for tagnode in restagnode:
+ tags_list.append(tagnode.data)
+
+ tag_date = datetime.utcnow().iso_format()
+ for tag_id in tags_list:
+ if tag_id not in self.tags:
+ new_tag = {
+ "id":tag_id,
+ "metas" : {
+ "dc:creator":"IRI",
+ "dc:created": tag_date,
+ "dc:contributor":"IRI",
+ "dc:modified": tag_date,
+ "dc:title":tag_id
+ }
+ }
+ self.tags[tag_id] = new_tag
+ element_tags.append({"id-ref":tag_id})
+
+ new_annotation = {
+ "begin": element_begin,
+ "end": int(element_begin) + int(element_duration),
+ "id": element_id,
+ "media": element_media,
+ "content": {
+ "mimetype": "application/x-ldt-structured",
+ "title": element_title,
+ "description": element_description,
+ "color": element_color,
+ "audio": {
+ "src" : element_audio_src,
+ "mimetype": "audio/mp3",
+ "href": element_audio_href
+ },
+ },
+ "metas": {
+ "id-ref": decoupage_id,
+ "dc:creator": decoupage_creator,
+ "dc:contributor": decoupage_contributor,
+ "dc:created": decoupage_created,
+ "dc:modified": decoupage_modified
+ }
+ }
+
+ self.annotations.append(new_annotation)
+
+
+
+ def __parse_ldt(self):
+
+ doc = xml.dom.minidom.parseString(self.project.ldt)
+ self.ldt_doc = Ft.Xml.Domlette.ConvertDocument(doc)
+ con = xml.xpath.Context.Context(doc, 1, 1, None)
+
+ res = xml.xpath.Evaluate("/iri/medias/media", context=con)
+ for mediaNode in res:
+ iri_id = mediaNode.getAttributeNS(None,"id")
+ content = Content.objects.get(iri_id=iri_id)
+ self.__parser_content(content)
+
+ res = xml.xpath.Evaluate("/iri/annotations/content",context=con)
+
+ for content_node in res:
+ content_id = content_node.getAttributeNS(None, "id")
+ content = Content.objects.get(iri_id=content_id)
+ for ensemble_node in content_node.childNodes:
+ if ensemble_node.nodeType != xml.dom.Node.ELEMENT_NODE or ensemble_node.tagName != "ensemble" :
+ continue
+ self.__parse_ensemble(ensemble_node, content)
+
+ #res = xml.xpath.Evaluate("/iri/displays/display",context=con)
+
+ #for display_node in res:
+
+
+
+ def __parse_content(self, content):
+
+ doc = Ft.Xml.Domlette.ConvertDocument(xml.dom.minidom.parse(content.iri_file_path()))
+ con = xml.xpath.Context.Context(doc, 1, 1, None)
+
+ authors = content.authors.all()
+
+ if len(authors) > 0 :
+ author = authors[0].handle
+ else :
+ author = "IRI"
+
+ if len(authors) > 1 :
+ contributor = authors[1].handle
+ else :
+ contributor = author
+
+ content_author = ""
+
+ res = xml.xpath.Evaluate("/iri/head/meta[@name='author']/@content", context=con)
+ if len(res) > 0:
+ content_author = res[0].value
+
+
+ content_date = ""
+
+ res = xml.xpath.Evaluate("/iri/head/meta[@name='date']/@content", context=con)
+ if len(res) > 0:
+ content_date = res[0].value
+
+
+ new_media = {
+ "http://advene.liris.cnrs.fr/ns/frame_of_reference/ms" : "o=0",
+ "id" : content.iri_id,
+ "url" : content.videopath.rstrip('/') + "/" + content.src,
+ "dc:creator" : author,
+ "dc:created" : content.creation_date.iso_format(),
+ "dc:contributor" : contributor,
+ "dc:modified" : content.update_date.iso_format(),
+ "dc:creator.contents" : content_author,
+ "dc:created.contents" : content_date,
+ "dc:title" : content.title,
+ "dc:description" : content.description,
+ "dc:duration" : content.get_duration(),
+ }
+
+ self.medias.append(new_media)
+
+
+ res = xml.xpath.Evaluate("/iri/body/ensembles/ensemble",context=con)
+
+ for ensemble_node in res:
+ self.__parse_ensemble(ensemble_node, content)
+
+
+ def serialize_to_cinelab(self):
+
+ res = {}
+
+ self.__parse_ldt()
+ self.__parse_contents()
+
+ project_main_media = ""
+ if len(self.medias) > 0:
+ project_main_media = self.medias[0]["id"]
+
+ res['metas'] = {
+ 'id': self.project.ldt_id,
+ 'dc:created':self.project.creation_date.iso_format(),
+ 'dc:modified':self.project.modification_date.iso_format(),
+ 'dc:contributor':self.project.changed_by,
+ 'dc:creator':self.project.created_by,
+ 'dc:title':self.project.title,
+ 'dc:description':self.project.get_description(self.ldt_doc), # get from doc, parse ldt
+ 'main_media': {"id-ref":project_main_media}
+ }
+
+ res['medias'] = self.medias
+ res['annotation-types'] = self.annotation_types
+ res['annotations'] = self.annotations
+ res['lists'] = self.lists
+ res['tags'] = self.tags.values()
+ res['views'] = self.views # ignored for the moment
+
+ return res
\ No newline at end of file