web/ldt/ldt_utils/projectserializer.py
changeset 8 d0a1c6d22b0e
child 10 84e31387a741
equal deleted inserted replaced
7:881514514df1 8:d0a1c6d22b0e
       
     1 import xml.dom
       
     2 import Ft.Xml.Domlette
       
     3 import xml.xpath
       
     4 from datetime import datetime
       
     5 
       
     6 """
       
     7 Serialize a project object to a cinelab compatible array
       
     8 """
       
     9 class ProjectSerializer:
       
    10     
       
    11     def __init__(self, project):
       
    12         self.project = project
       
    13         self.ldt_doc = None
       
    14         self.medias = []
       
    15         self.annotations = []
       
    16         self.tags = {}
       
    17         self.annotation_types = []
       
    18         self.views = []
       
    19         self.lists = []
       
    20         
       
    21     
       
    22     def __parse_ensemble(self, ensemble_node, content):
       
    23         
       
    24         ensemble_id = ensemble_node.getAttributeNS("id",None)
       
    25         ensemble_author = ensemble_node.getAttributeNS("author",None)
       
    26         ensemble_title = ensemble_node.getAttributeNS("title",None)
       
    27         ensemble_description = ensemble_node.getAttributeNS("abstract",None)
       
    28         ensemble_created = datetime.utcnow().iso_format()
       
    29         ensemble_modified = ensemble_created 
       
    30         
       
    31         list_items = []
       
    32         new_list = {
       
    33             "id" : ensemble_id,
       
    34             "items" : list_items,
       
    35             "metas" : {
       
    36                 "dc:creator":ensemble_author,
       
    37                 "dc:created": ensemble_created,
       
    38                 "dc:contributor":"undefined",
       
    39                 "dc:modified": ensemble_modified,
       
    40                 "dc:title":ensemble_title,
       
    41                 "dc:description": ensemble_description,
       
    42                 "id-ref":content.iri_id,
       
    43                 "editable":"false"
       
    44             }
       
    45         }
       
    46         
       
    47         self.lists.append(new_list)
       
    48         
       
    49         for decoupage_node in ensemble_node.childNodes:
       
    50             if decoupage_node.nodeType != xml.dom.Node.ELEMENT_NODE or decoupage_node.tagName != "decoupage" :
       
    51                 continue
       
    52             
       
    53             decoupage_id = decoupage_node.getAttributeNS("id",None)
       
    54             decoupage_creator = decoupage_node.getAttributeNS("author",None)
       
    55             if not decoupage_creator:
       
    56                 decoupage_creator = "IRI"
       
    57             decoupage_contributor = decoupage_creator
       
    58             date_str = decoupage_node.getAttributeNS("date",None)
       
    59             if date_str :
       
    60                 decoupage_created = datetime.strptime(date_str,"%d/%m/%Y").iso_format()
       
    61             else :
       
    62                 decoupage_created = datetime.utcnow().iso_format()
       
    63             decoupage_modified = decoupage_created
       
    64             
       
    65             decoupage_title = ""
       
    66             for txtRes in xml.xpath.Evaluate("title/text()", decoupage_node): 
       
    67                     decoupage_title += txtRes.data
       
    68 
       
    69             decoupage_description = ""
       
    70             for txtRes in xml.xpath.Evaluate("abstract/text()", decoupage_node): 
       
    71                     decoupage_description += txtRes.data
       
    72             
       
    73 
       
    74             
       
    75             list_items.append({"id-ref":decoupage_id})
       
    76             
       
    77             new_annotation_types = {
       
    78                 "id":decoupage_id,
       
    79                 "dc:creator":decoupage_creator,
       
    80                 "dc:created":decoupage_created,
       
    81                 "dc:contributor":decoupage_contributor,
       
    82                 "dc:modified":decoupage_modified,
       
    83                 "dc:title":decoupage_title,
       
    84                 "dc:description":decoupage_description
       
    85             }
       
    86             
       
    87             self.annotation_types.append(new_annotation_types)            
       
    88                         
       
    89             res = xml.xpath.Evaluate("elements/element", decoupage_node)
       
    90             for element_node in res:
       
    91                 
       
    92                 element_id = element_node.getAttributeNS("id",None)
       
    93                 element_begin = element_node.getAttributeNS("begin",None)
       
    94                 element_duration = element_node.getAttributeNS("dur",None)
       
    95                 element_media = content.iri_id
       
    96                 element_color = element_node.getAttributeNS("color",None)
       
    97                 
       
    98                 element_title = ""
       
    99                 for txtRes in xml.xpath.Evaluate("title/text()", element_node): 
       
   100                     element_title += txtRes.data 
       
   101         
       
   102                 element_description = ""
       
   103                 for txtRes in xml.xpath.Evaluate("abstract/text()", element_node): 
       
   104                     element_description += txtRes.data 
       
   105                 
       
   106                 element_audio_src = ""
       
   107                 element_audio_href = ""
       
   108                 res = xml.xpath.Evaluate("audio", element_node)
       
   109                 if len(res) > 0:
       
   110                     element_audio_src = res[0].getAttributeNS(None, "source")
       
   111                     element_audio_href = res[0].value
       
   112                 
       
   113                 
       
   114                 element_tags = []
       
   115                 
       
   116                 tags = element_node.getAttributeNS("tags",None)
       
   117                 
       
   118                 tags_list = map(lambda s:s.trim(),tags.split(","))
       
   119 
       
   120                 #tags                                
       
   121                 if tags is None or len(tags) == 0:
       
   122                     tags_list = []
       
   123                     restagnode = xml.xpath.Evaluate("tag/text()", element_node)
       
   124                     for tagnode in restagnode:
       
   125                         tags_list.append(tagnode.data)
       
   126                         
       
   127                 if tags_list is None or len(tags_list) == 0:
       
   128                     tags_list = []
       
   129                     restagnode = xml.xpath.Evaluate("tags/tag/text()", element_node)
       
   130                     for tagnode in restagnode:
       
   131                         tags_list.append(tagnode.data)
       
   132                 
       
   133                 tag_date = datetime.utcnow().iso_format()
       
   134                 for tag_id in tags_list:
       
   135                     if tag_id not in self.tags:
       
   136                         new_tag = {
       
   137                             "id":tag_id,
       
   138                             "metas" : {
       
   139                                 "dc:creator":"IRI",
       
   140                                 "dc:created": tag_date,
       
   141                                 "dc:contributor":"IRI",
       
   142                                 "dc:modified": tag_date,
       
   143                                 "dc:title":tag_id
       
   144                             }
       
   145                         }
       
   146                         self.tags[tag_id] = new_tag
       
   147                     element_tags.append({"id-ref":tag_id})
       
   148 
       
   149                 new_annotation = {
       
   150                     "begin": element_begin,
       
   151                     "end": int(element_begin) + int(element_duration),
       
   152                     "id": element_id,
       
   153                     "media": element_media,
       
   154                     "content": {
       
   155                         "mimetype": "application/x-ldt-structured",
       
   156                         "title": element_title,
       
   157                         "description": element_description,
       
   158                         "color": element_color,
       
   159                         "audio": {
       
   160                             "src" : element_audio_src,
       
   161                             "mimetype": "audio/mp3",
       
   162                             "href": element_audio_href
       
   163                         },
       
   164                     },
       
   165                     "metas": {
       
   166                         "id-ref": decoupage_id,
       
   167                         "dc:creator": decoupage_creator,
       
   168                         "dc:contributor": decoupage_contributor,
       
   169                         "dc:created": decoupage_created,
       
   170                         "dc:modified": decoupage_modified
       
   171                     }
       
   172                 }
       
   173                 
       
   174                 self.annotations.append(new_annotation)
       
   175         
       
   176 
       
   177     
       
   178     def __parse_ldt(self):
       
   179         
       
   180         doc = xml.dom.minidom.parseString(self.project.ldt)
       
   181         self.ldt_doc = Ft.Xml.Domlette.ConvertDocument(doc)
       
   182         con = xml.xpath.Context.Context(doc, 1, 1, None)
       
   183         
       
   184         res = xml.xpath.Evaluate("/iri/medias/media", context=con)
       
   185         for mediaNode in res:
       
   186             iri_id = mediaNode.getAttributeNS(None,"id")
       
   187             content = Content.objects.get(iri_id=iri_id)
       
   188             self.__parser_content(content)
       
   189             
       
   190         res = xml.xpath.Evaluate("/iri/annotations/content",context=con)               
       
   191         
       
   192         for content_node in res:
       
   193             content_id = content_node.getAttributeNS(None, "id")
       
   194             content = Content.objects.get(iri_id=content_id)
       
   195             for ensemble_node in content_node.childNodes:
       
   196                 if ensemble_node.nodeType != xml.dom.Node.ELEMENT_NODE or ensemble_node.tagName != "ensemble" :
       
   197                     continue
       
   198                 self.__parse_ensemble(ensemble_node, content)
       
   199             
       
   200         #res = xml.xpath.Evaluate("/iri/displays/display",context=con)
       
   201         
       
   202         #for display_node in res:
       
   203             
       
   204     
       
   205     
       
   206     def __parse_content(self, content):
       
   207         
       
   208         doc = Ft.Xml.Domlette.ConvertDocument(xml.dom.minidom.parse(content.iri_file_path()))
       
   209         con = xml.xpath.Context.Context(doc, 1, 1, None)
       
   210         
       
   211         authors = content.authors.all()
       
   212         
       
   213         if len(authors) > 0 :
       
   214             author = authors[0].handle
       
   215         else :
       
   216             author = "IRI"
       
   217         
       
   218         if len(authors) > 1 :
       
   219             contributor = authors[1].handle
       
   220         else :
       
   221             contributor = author
       
   222         
       
   223         content_author = ""
       
   224         
       
   225         res = xml.xpath.Evaluate("/iri/head/meta[@name='author']/@content", context=con)
       
   226         if len(res) > 0:
       
   227             content_author = res[0].value
       
   228         
       
   229         
       
   230         content_date = ""
       
   231         
       
   232         res = xml.xpath.Evaluate("/iri/head/meta[@name='date']/@content", context=con)
       
   233         if len(res) > 0:
       
   234             content_date = res[0].value
       
   235 
       
   236         
       
   237         new_media = {
       
   238              "http://advene.liris.cnrs.fr/ns/frame_of_reference/ms" : "o=0",
       
   239              "id" : content.iri_id,
       
   240              "url" : content.videopath.rstrip('/') + "/" + content.src,
       
   241              "dc:creator" : author,
       
   242              "dc:created" : content.creation_date.iso_format(),
       
   243              "dc:contributor" : contributor,
       
   244              "dc:modified" : content.update_date.iso_format(),
       
   245              "dc:creator.contents" : content_author,
       
   246              "dc:created.contents" : content_date,
       
   247              "dc:title" : content.title,
       
   248              "dc:description" : content.description,
       
   249              "dc:duration" : content.get_duration(),
       
   250         }
       
   251         
       
   252         self.medias.append(new_media)
       
   253         
       
   254         
       
   255         res = xml.xpath.Evaluate("/iri/body/ensembles/ensemble",context=con)
       
   256         
       
   257         for ensemble_node in res:
       
   258             self.__parse_ensemble(ensemble_node, content)
       
   259 
       
   260     
       
   261     def serialize_to_cinelab(self):
       
   262     
       
   263         res = {}
       
   264         
       
   265         self.__parse_ldt()
       
   266         self.__parse_contents()
       
   267         
       
   268         project_main_media = ""
       
   269         if len(self.medias) > 0:
       
   270             project_main_media = self.medias[0]["id"]
       
   271         
       
   272         res['metas'] = {
       
   273              'id': self.project.ldt_id,
       
   274              'dc:created':self.project.creation_date.iso_format(),
       
   275              'dc:modified':self.project.modification_date.iso_format(),
       
   276              'dc:contributor':self.project.changed_by,
       
   277              'dc:creator':self.project.created_by,
       
   278              'dc:title':self.project.title,
       
   279              'dc:description':self.project.get_description(self.ldt_doc), # get from doc, parse ldt
       
   280              'main_media': {"id-ref":project_main_media}
       
   281             }
       
   282         
       
   283         res['medias'] =  self.medias
       
   284         res['annotation-types'] = self.annotation_types
       
   285         res['annotations'] = self.annotations
       
   286         res['lists'] = self.lists
       
   287         res['tags'] = self.tags.values()
       
   288         res['views'] = self.views # ignored for the moment
       
   289         
       
   290         return res