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'),)