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