web/ldt/ldt_utils/models.py
changeset 1 eb9188f2ee4f
child 9 505a1c4cac67
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/ldt/ldt_utils/models.py	Fri Oct 22 18:14:30 2010 +0200
@@ -0,0 +1,333 @@
+from django.conf import settings
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from ldt.core.models import Document, Owner
+from django.contrib.auth.models import User
+import tagging.fields
+from utils import create_ldt, copy_ldt, create_empty_iri, update_iri, generate_uuid
+import lxml.etree
+import os.path
+import uuid
+import lucene
+from ldt.ldt_utils import STORE, ANALYZER
+
+class Author(models.Model):
+
+    handle = models.CharField(max_length=512, unique=True, blank=True, null=True)
+    email = models.EmailField(unique=False, blank=True, null=True)
+    firstname = models.CharField(max_length=512, blank=True, null=True)
+    lastname = models.CharField(max_length=512, blank=True, null=True)
+    
+    def __unicode__(self):
+        return unicode(self.id) + " - " + self.handle + ", " + self.email + ", " + self.firstname + " " + self.lastname
+
+class Media(models.Model):
+    external_id = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('media.external_id'))
+    external_permalink = models.URLField(max_length=1024, verify_exists=False, null=True, blank=True, verbose_name=_('media.external_permalink'))
+    external_publication_url = models.URLField(max_length=1024, verify_exists=True, null=True, blank=True, verbose_name=_('media.external_publication_url'))
+    external_src_url = models.URLField(max_length=1024, verify_exists=False, null=True, blank=True, verbose_name=_('media.external_src_url'))
+    creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('media.creation_date'))
+    media_creation_date = models.DateTimeField(null=True, blank=True, verbose_name=_('media.media_creation_date'))
+    update_date = models.DateTimeField(auto_now=True, verbose_name=_('media.update_date'))
+    videopath = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('media.videopath'))
+    duration = models.IntegerField(null=True, blank=True, verbose_name=_('media.duration'))
+    creator = models.ForeignKey(User, blank=True, null=True, verbose_name=_('media.creator'))
+    description = models.TextField(null=True, blank=True, verbose_name=_('description'))
+    title = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('title'))
+    src = models.CharField(max_length=1024, unique=True, verbose_name=_('media.src'))
+    
+    def stream_src():
+        
+        def fget(self):
+            res_src = self.src.rstrip()
+            if self.videopath and self.videopath.startswith("rtmp://"):
+                extension = res_src.split(".")[-1]
+                res_src = {
+                    'flv': lambda s: s,
+                    'mp3': lambda s: "%s:%s" %("mp3",res_src[:-4]),
+                    'mp4': lambda s: "%s:%s" %("mp4",res_src[:-4]),
+                    'f4v': lambda s: "%s:%s" %("mp4",res_src[:-4]),
+                }.get(extension, lambda s:s)(res_src.lower())
+            return res_src
+        
+        return locals()
+    
+    stream_src = property(**stream_src())    
+    
+    def save(self, *args, **kwargs):
+        super(Media, self).save(*args, **kwargs)
+        for content in self.content_set.all():
+            content.sync_iri_file()
+    
+    def __unicode__(self):
+        strings = []
+        if self.title:
+            strings.append(unicode(self.title))
+        else:
+            strings.append(unicode(self.src))
+        if self.external_id:
+            strings.append(unicode(self.external_id))
+        return "|".join(strings)
+
+
+class Content(models.Model):
+    iri_id = models.CharField(max_length=1024, unique=True, default=generate_uuid, verbose_name=_('content.iri_id'))
+    iriurl = models.CharField(max_length=1024, verbose_name=_('content.iriurl'))
+    creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('content.creation_date'))
+    update_date = models.DateTimeField(auto_now=True, verbose_name=_('content.update_date'))
+    title = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('content.title'))
+    description = models.TextField(null=True, blank=True, verbose_name=_('content.description'))
+    authors = models.ManyToManyField(Author, blank=True, verbose_name=_('content.authors'))
+    duration = models.IntegerField(null=True, blank=True, verbose_name=_('content.duration'))
+    content_creation_date = models.DateTimeField(null=True, blank=True, verbose_name=_('content.content_creation_date'))
+    tags = tagging.fields.TagField(max_length=2048, null=True, blank=True )
+    media_obj = models.ForeignKey('Media', blank=True, null=True )
+    
+    class Meta:
+        ordering = ["title"]
+
+    def get_duration(self):
+        if self.duration is None:
+            doc = lxml.etree.parse(self.iri_file_path())
+            res = doc.xpath("/iri/body/medias/media[@id='video']/video")
+            if len(res) > 0:
+                try:
+                    self.duration = int(res[0].get(u'dur',0) or 0)
+                except:
+                    self.duration = 0
+            else:
+                self.duration = 0
+            self.save()
+        return self.duration
+    
+    def delete(self):
+        super(Content, self).delete()
+        writer = lucene.IndexWriter(STORE, ANALYZER, True, lucene.IndexWriter.MaxFieldLength.UNLIMITED)
+        writer.deleteDocuments(lucene.Term("iri_id", self.iri_id))
+        writer.commit()
+        
+    def sync_iri_file(self):
+        # create iri file if needed
+        created = False
+        try:
+            iri_file_path = self.iri_file_path()
+            if not os.path.exists(iri_file_path):
+                dir = os.path.dirname(iri_file_path)
+                if not os.path.exists(dir):
+                    os.makedirs(dir)
+                created = True
+                file = open(iri_file_path,"w")
+                create_empty_iri(file, self, "IRI")
+            else:
+                created = False
+                update_iri(iri_file_path, self, "IRI")
+                
+        except Exception, e:
+            if created:
+                if os.path.exists(iri_file_path):
+                    os.remove(iri_file_path)
+            raise e
+        
+        
+    #TODO: better manage the change in .iri name and error scenario (save in temp file + rename
+    def save(self, *args, **kwargs):
+        
+        self.sync_iri_file()        
+        # update it 
+        super(Content, self).save(*args, **kwargs)
+    
+    def __unicode__(self):
+        return str(self.id) + ": " + self.iri_id
+        
+    def iri_url(self, web_url=settings.WEB_URL):
+        if 'http' in self.iriurl or 'https' in self.iriurl:
+            return self.iriurl
+        else:
+            return unicode(web_url) + unicode(settings.MEDIA_URL)+u"media/ldt/"+unicode(self.iriurl)
+    
+    def iri_file_path(self):
+        return os.path.join(os.path.join(os.path.join(os.path.join(settings.MEDIA_ROOT, "media"), "ldt"), self.iri_id), os.path.basename(self.iriurl))
+
+    def iri_url_template(self):
+        return "${web_url}${media_url}media/ldt/" + unicode(self.iri_id) + "/" + os.path.basename(self.iriurl)
+
+
+    def __get_empty_media(self):
+        if settings.EMPTY_MEDIA_EXTERNALID:
+            empty_media = Media.objects.get(externalid=settings.EMPTY_MEDIA_EXTERNALID)
+            return empty_media
+        else:
+            return None
+            
+    
+    def stream_src():
+        
+        def fget(self):
+            if self.media_obj is not None:
+                return self.media_obj.stream_src
+            else:
+                return None
+        
+        return locals()
+    
+    stream_src = property(**stream_src())
+    
+    def videopath(): #@NoSelf
+        doc = """simulate videopath""" #@UnusedVariable
+       
+        def fget(self):
+            if self.media_obj is None:
+                empty_media = self.__get_empty_media()
+                if empty_media:
+                    return empty_media.videopath
+                else: 
+                    return None
+            else:
+                return self.media_obj.videopath
+           
+        def fset(self, value):
+            if self.media_obj is not None:
+                self.media_obj.videopath = value
+                      
+        return locals()
+       
+    videopath = property(**videopath())
+
+    def src(): #@NoSelf
+        doc = """simulate videopath""" #@UnusedVariable
+       
+        def fget(self):
+            if self.media_obj is None:
+                empty_media = self.__get_empty_media()
+                if empty_media:
+                    return empty_media.src
+                else:
+                    return None
+            else:
+                return self.media_obj.src
+           
+        def fset(self, value):
+            if self.media_obj is None or self.media_obj.src != value:
+                media, created = Media.objects.get_or_create(src=value, defaults={'src':value})                
+                self.media_obj = media
+                self.save()
+                      
+        return locals()
+       
+    src = property(**src())
+
+    def external_id(): #@NoSelf
+        doc = """simulate externalid""" #@UnusedVariable
+       
+        def fget(self):
+            if self.media_obj is None:
+                empty_media = self.__get_empty_media()
+                if empty_media:
+                    return empty_media.external_id
+                else: 
+                    return None
+            else:
+                return self.media_obj.external_id
+           
+        def fset(self, value):
+            if self.media_obj is not None:
+                self.media_obj.external_id = value
+                      
+        return locals()
+       
+    external_id = property(**external_id())
+
+        
+        
+class Project(Document):  
+    STATE_CHOICES=(
+    (1, 'edition'),
+    (2, 'published'),
+    (3, 'moderated'),
+    (4, 'rejected'),
+    (5, 'deleted')
+    )
+    ldt_id = models.CharField(max_length=1024, unique=True)
+    ldt = models.TextField(null=True)
+    title = models.CharField(max_length=1024)
+    contents = models.ManyToManyField(Content)
+    creation_date = models.DateTimeField(auto_now_add=True)
+    modification_date = models.DateTimeField(auto_now=True)
+    created_by = models.CharField(_("created by"), max_length=70)
+    changed_by = models.CharField(_("changed by"), max_length=70)
+    state = models.IntegerField(choices=STATE_CHOICES, default=1)
+    
+    class Meta:
+        ordering = ["title"]
+
+    
+    def __unicode__(self):
+        return unicode(self.id) + u": " + unicode(self.ldt_id)
+    
+    def get_description(self, doc=None):
+        
+        if doc is None:
+            doc = lxml.etree.fromstring(self.ldt)
+        
+        res = doc.xpath("/iri/project")
+        if len(res) > 0:
+            return res[0].get(u'abstract')
+        else:
+            return None
+        
+
+    @staticmethod
+    def create_project(user, title, contents):
+        owner = Owner.objects.get(user=user)
+        project = Project(title=title, owner=owner)
+        project.ldt_id = str(uuid.uuid1())
+        project.created_by=user.username
+        project.changed_by=user.username
+        project.state = 1
+        project.save()
+        for content in contents:
+            project.contents.add(content)
+        project.save()
+        return create_ldt(project, user)
+
+    def copy_project(self, user, title):
+        owner = Owner.objects.get(user=user)
+        project = Project(title=title, owner=owner)
+        project = copy_ldt(self, project, user)
+        project.save()
+        for content in self.contents.all():
+            project.contents.add(content)
+        project.save()
+        return project
+    
+    def checkAccess(self, user):
+        if (user and user.is_staff) or self.state == 2: 
+            return True
+        else:
+            return False
+        
+
+class Segment(models.Model):
+    
+    project_obj = models.ForeignKey(Project, null=True)
+    content = models.ForeignKey(Content)
+    project_id = models.CharField(max_length=1024, unique=False, blank=True, null=True)
+    iri_id = models.CharField(max_length=1024, unique=False)
+    ensemble_id = models.CharField(max_length=1024, unique=False)
+    cutting_id = models.CharField(max_length=1024, unique=False)    
+    element_id = models.CharField(max_length=1024, unique=False)
+    tags = tagging.fields.TagField(max_length=2048, null=True, blank=True, unique=False)
+    title = models.CharField(max_length=2048, unique=False, null=True, blank=True)
+    duration = models.IntegerField(null=True)
+    start_ts = models.IntegerField(null=True)
+    author = models.CharField(max_length=1024, unique=False, null=True, blank=True)
+    date = models.CharField(max_length=128, unique=False, null=True, blank=True)
+    abstract = models.TextField(null=True, blank=True)
+    
+    def __unicode__(self):
+        return "/".join((unicode(self.project_id), unicode(self.iri_id), unicode(self.ensemble_id), unicode(self.cutting_id), unicode(self.element_id)))
+    
+    class Meta:
+        unique_together = (('project_id', 'iri_id', 'ensemble_id', 'cutting_id', 'element_id'),)
+
+