src/ldt/ldt/api/ldt/handlers.py
changeset 197 6dfdc12e338a
parent 196 b939a58d13b0
child 199 3d919c59b46f
equal deleted inserted replaced
196:b939a58d13b0 197:6dfdc12e338a
     1 from ldt.ldt_utils.models import Project
     1 from ldt.ldt_utils.models import Project
     2 from piston.handler import BaseHandler
     2 from piston.handler import BaseHandler
     3 from piston.utils import rc, require_extended
     3 from piston.utils import rc, require_extended
     4 from ldt.ldt_utils.utils import LdtAnnotation
     4 from ldt.ldt_utils.utils import LdtAnnotation
     5 import logging #@UnresolvedImport
     5 import logging #@UnresolvedImport
       
     6 import lxml.etree
     6 
     7 
     7 
     8 
     8 class ProjectHandler(BaseHandler):
     9 class ProjectHandler(BaseHandler):
     9     allowed_methods = ('GET', 'PUT',)
    10     allowed_methods = ('GET', 'PUT',)
    10     model = Project   
    11     model = Project   
    18     @require_extended
    19     @require_extended
    19     def update(self, request, project_id):
    20     def update(self, request, project_id):
    20         """
    21         """
    21         This method is called when a PUT request is sent to http://<plateform_location>/api/ldt/projects/<project_id>.format. The
    22         This method is called when a PUT request is sent to http://<plateform_location>/api/ldt/projects/<project_id>.format. The
    22         request should contain a content-type header whose value can be either "application/json" or "text/xml" and a valid utf-8
    23         request should contain a content-type header whose value can be either "application/json" or "text/xml" and a valid utf-8
    23         encoded JSON/Cinelab or LDT/XML file.
    24         encoded JSON Cinelab or LDT XML file.
    24             <project_id> is the ldt_id field of the project. If <projet_id> does not match any project on the platform, a 410 ("Gone")
    25             <project_id> is the ldt_id field of the project. If <projet_id> does not match any project on the platform, a 410 ("Gone")
    25             error will be returned.
    26             error will be returned.
    26             <format> can be 'json', 'yaml', 'xml', 'pickle'
    27             <format> is the format of the data sent back by the server. It can be 'json', 'yaml', 'xml' or 'pickle'.
    27         
    28         
    28         If the submitted file is not valid or if the file refers to a media that is not contained in the project, a 500  ("Bad Request")
    29         If the submitted file is not valid or if the file refers to a media that is not contained in the project, a 500  ("Bad Request")
    29         error will be returned. If the "type" field of an annotation matches an already existing cutting, it will be added to that 
    30         error will be returned. If the "type" field of an annotation matches an already existing cutting, it will be added to that 
    30         cutting. Otherwise, a new cutting will be added (as well as a new ensemble if needed). Several annotations can be added at 
    31         cutting. Otherwise, a new cutting will be added (as well as a new ensemble if needed). Several annotations can be added at 
    31         the same time if the submitted file contains multiple annotations. In addition to annotations, the submitted file should contain a 
    32         the same time if the submitted file contains multiple annotations. The server returns a 201 ("Created") code if annotations have
    32         meta section with two fields :"date" and "creator". The server returns a 201 ("Created") code if annotations have been added.   
    33         been added successfully.   
    33         
    34         
    34         Example :
    35         Example :
       
    36         
       
    37         Remark : Both files below contain the minimum necessary fields and attributes for the handler to work. If one field or attribute is
       
    38         missing (e.g. author, or date) during submission, an error will occur.
    35         
    39         
    36         A platform is reachable at http://localhost/. It contains a project with ID a0593b58-f258-11df-80e1-00145ea4a2be. This project has
    40         A platform is reachable at http://localhost/. It contains a project with ID a0593b58-f258-11df-80e1-00145ea4a2be. This project has
    37         a content milosforman_amadeus, which has a cutting Salieri. The following JSON file exists in the current directory :
    41         a content milosforman_amadeus, which has a cutting Salieri. The following JSON file exists in the current directory :
    38     
    42     
    39         {
    43         {
    66             }
    70             }
    67         }
    71         }
    68             
    72             
    69         If we send a PUT request with curl :    
    73         If we send a PUT request with curl :    
    70         $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.JSON -H  "content-type:application/json"
    74         $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.JSON -H  "content-type:application/json"
    71         A new cutting titled "New cutting name" will be created with one annotation inside, and the annotation "Annotation about Salieri"
    75         A new cutting titled "New cutting name" will be created with the first annotation inside, and the annotation "Annotation about Salieri"
    72         will be added to the Salieri cutting.
    76         will be added to the Salieri cutting. 
       
    77         
       
    78         Similar results can be obtained using the following xml file :
       
    79         
       
    80         <iri>
       
    81           <annotations>
       
    82             <content id="milosforman_amadeus">
       
    83               <ensemble>
       
    84                 <decoupage>
       
    85                   <title>New cutting name</title>
       
    86                   <abstract/>
       
    87                   <elements>
       
    88                     <element begin="50000" dur="895000" date="2011-09-10T09:12:58" author="John Doe">
       
    89                       <title>new annotation</title>
       
    90                       <abstract/>
       
    91                       <audio source=""/>
       
    92                       <tags>
       
    93                         <tag>json</tag>
       
    94                       </tags>
       
    95                     </element>            
       
    96                   </elements>
       
    97                 </decoupage>
       
    98                 <decoupage >
       
    99                   <title>Salieri</title>
       
   100                   <abstract/>
       
   101                   <elements>
       
   102                     <element begin="700000" dur="500000" date="2011-09-10T09:12:58" author="John Doe">
       
   103                       <title>Annotation about Salieri</title>
       
   104                       <abstract/>
       
   105                       <audio source=""/>
       
   106                       <tags>
       
   107                           <tag>xml</tag>
       
   108                           <tag>test</tag>
       
   109                           <tag>blop</tag>
       
   110                       </tags>
       
   111                     </element>            
       
   112                   </elements>
       
   113                 </decoupage>
       
   114             </ensemble>
       
   115            </content>
       
   116           </annotations>
       
   117         </iri>
       
   118         
       
   119         and the command :
       
   120         
       
   121         $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.LDT -H  "content-type:text/xml"
    73           
   122           
    74         """    
   123         """    
    75         
   124         
    76         try:
   125         try:
    77             project = Project.objects.get(ldt_id=project_id)
   126             project = Project.objects.get(ldt_id=project_id)
    78         except Project.DoesNotExist:
   127         except Project.DoesNotExist:
    79             return rc.NOT_HERE   
   128             return rc.NOT_HERE 
    80         
   129 
       
   130         adder = LdtAnnotation(project)           
       
   131           
    81         if request.content_type == 'application/json':
   132         if request.content_type == 'application/json':
    82             
   133             
    83             logging.debug("request json " + repr(request))       
   134             logging.debug("request json " + repr(request.data))       
    84             adder = LdtAnnotation(project)           
       
    85 
   135 
    86             meta = request.data['meta']
   136             meta = request.data['meta']
    87             author = meta['creator']
   137             author = meta['creator']
    88             date = meta['created']
   138             date = meta['created']
    89             new_annotations = request.data['annotations']
   139             new_annotations = request.data['annotations']
    92                 dur = str(a['end'] - a['begin'])
   142                 dur = str(a['end'] - a['begin'])
    93                 begin = str(a['begin'])
   143                 begin = str(a['begin'])
    94                 if not adder.add(a['media'], a['type'], a['content']['data'], '', a['tags'], begin, dur, author, date):
   144                 if not adder.add(a['media'], a['type'], a['content']['data'], '', a['tags'], begin, dur, author, date):
    95                     return rc.BAD_REQUEST
   145                     return rc.BAD_REQUEST
    96 
   146 
    97             return rc.ALL_OK            
   147             return rc.ALL_OK
    98             
   148             
    99         elif request.content_type == "text/xml":        
   149         elif request.content_type == "text/xml":        
   100             logging.debug("request xml" + repr(request))
   150             logging.debug("request xml" + repr(request))
   101             data = request.data
       
   102             ldt_str = data["ldt"] 
       
   103             
   151             
   104             logging.debug("request data" + repr(ldt_str))
   152             ldtdoc = lxml.etree.fromstring(request.raw_post_data) 
   105             
   153             
   106             if not ldt_str:  
   154             for content in ldtdoc.xpath('/iri/annotations/content'):
   107                 return rc.ALL_OK
   155                 content_id = content.get('id')
   108                         
   156                 
   109             project.ldt = ldt_str
   157                 for decoupage in content.xpath('ensemble/decoupage'):
   110             
   158                     dec_title = decoupage.xpath('title')[0].text
   111             project.save()
   159                     author = decoupage.get('author')                                            
       
   160                     
       
   161                     for element in decoupage.xpath('elements/element'):
       
   162                         begin = element.get('begin')
       
   163                         dur = element.get('dur')
       
   164                         date = element.get('date')
       
   165                         title = element.xpath('title')[0].text
       
   166                         abstract = element.xpath('abstract')[0].text
       
   167                         tags = []
       
   168                         for tag in element.xpath('tags/tag'):
       
   169                             tags.append(tag.text)
       
   170                             
       
   171                         if not adder.add(content_id, dec_title, title, abstract, tags, begin, dur, author, date):
       
   172                             return rc.BAD_REQUEST
   112         
   173         
   113             return rc.ALL_OK
   174             return rc.ALL_OK
   114         
   175         
   115         return rc.NOT_IMPLEMENTED
   176         return rc.NOT_IMPLEMENTED