New search feature on top right corner. Advanced search included in published projects tab. Colored icons. Change css to avoid scroll on contents and projects table.
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import ugettext_lazy as _
from ldt.core.models import Document, Owner
import ldt.indexation
from utils import (create_ldt, copy_ldt, create_empty_iri, update_iri,
generate_uuid)
import lucene
import lxml.etree
import mimetypes
import os.path
import tagging.fields
import uuid
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.CharField(max_length=1024, 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'))
mimetype_field = models.CharField(max_length=512, null=True, blank=True, verbose_name=_('media.mimetype'))
def mimetype(): #@NoSelf
def fget(self):
if self.mimetype_field :
return self.mimetype_field
elif self.src:
return mimetypes.guess_type(self.src.rstrip())
else:
return None
def fset(self, value):
self.mimetype_field = value
return locals()
mimetype = property(**mimetype())
def stream_src(): #@NoSelf
def fget(self):
res_src = self.src.rstrip()
if self.videopath and self.videopath.startswith("rtmp://") and "mp3:" not in res_src and "mp4:" not in res_src:
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),
'f4v': lambda s: "%s:%s" % ("mp4", res_src),
'mov': lambda s: "%s:%s" % ("mp4", res_src),
}.get(extension, lambda s:s)(res_src)
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 ContentManager(models.Manager):
def get_by_natural_key(self, iri_id):
return self.get(iri_id=iri_id)
class Content(models.Model):
objects = ContentManager()
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 natural_key(self):
return self.iri_id
# added for import
def get_by_natural_key(self, iri_id):
return self.get(iri_id=iri_id)
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 mimetype(): #@NoSelf
def fget(self):
if self.media_obj:
return self.media_obj.mimetype
else:
return None
return locals()
mimetype = property(**mimetype())
def delete(self):
super(Content, self).delete()
writer = ldt.indexation.get_writer()
try:
writer.deleteDocuments(lucene.Term("iri_id", self.iri_id))
writer.commit()
finally:
writer.close()
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"ldt/" + unicode(self.iriurl)
def iri_file_path(self):
return os.path.join(os.path.join(os.path.join(settings.MEDIA_ROOT, "ldt"), self.iri_id), os.path.basename(self.iriurl))
def iri_url_template(self):
return "${web_url}${media_url}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(external_id=settings.EMPTY_MEDIA_EXTERNALID)
return empty_media
else:
return None
def stream_src(): #@NoSelf
def fget(self):
if self.media_obj is not None:
return self.media_obj.stream_src
else:
empty_media = self.__get_empty_media()
if empty_media:
return empty_media.stream_src
else:
return ""
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}) #@UnusedVariable
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) + u"::" + unicode(self.title)
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
def stream_mode(): #@NoSelf
def fget(self):
modes = []
for content in self.contents.all():
mimetype = content.mimetype
if mimetype:
mode = mimetype.split("/")[0]
if "audio" == mode or "video" == mode:
modes.append(mode)
else:
modes.append("video")
else:
modes.append("video")
def filter_video(current, item):
if not current:
return item
elif current == item:
return item
else:
return "video"
return reduce(filter_video, modes)
return locals()
stream_mode = property(**stream_mode())
@staticmethod
def create_project(user, title, contents):
owner = Owner.objects.get(user=user) #@UndefinedVariable
project = Project(title=title, owner=owner)
project.ldt_id = str(uuid.uuid1()) #@UndefinedVariable
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) #@UndefinedVariable
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'),)