diff -r 5bb249eefdd1 -r 22ab430e9b64 web/ldt/ldt_utils/models.py --- a/web/ldt/ldt_utils/models.py Tue Nov 16 12:20:59 2010 +0100 +++ b/web/ldt/ldt_utils/models.py Tue Nov 16 14:15:07 2010 +0100 @@ -4,48 +4,330 @@ from ldt.core.models import Document, Owner from django.contrib.auth.models import User import tagging.fields -from utils import generate_uuid +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 -#from django.core.management.validation import max_length + +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 Annotation(models.Model): - id = models.CharField(max_length=1024, primary_key=True, unique=True, default=generate_uuid, verbose_name=_('annotation.id')) - uri = models.CharField(max_length=1024, verbose_name=_('annotation.uri')) - tags = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('annotation.tags')) - title = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('annotation.title')) - description = models.TextField(null=True, blank=True, verbose_name=_('annotation.description')) - text = models.TextField(null=True, blank=True, verbose_name=_('annotation.text')) - color = models.CharField(max_length=1024, verbose_name=_('annotation.color')) - creator = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('creator.title')) - contributor = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('contributor.title')) - creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('annotation.creation_date')) - update_date = models.DateTimeField(auto_now=True, verbose_name=_('annotation.update_date')) +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.title) + 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_annotation(id, uri=None, tags=None, title=None, description=None, text=None, color=None, creator=None, contributor=None, creation_date=None, update_date=None): - annotation = Annotation(id=id, uri=uri, tags=tags, title=title, description=description, text=text, color=color, creator=creator, contributor=contributor, creation_date=creation_date, update_date=update_date) - annotation.save() - - return annotation - + 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) -#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 + 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'),) + +