2010-11-26 15:07:24 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
|
|
|
from __future__ import division, with_statement
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
from django.contrib.auth.models import User
|
2011-11-02 14:42:07 +00:00
|
|
|
from django.conf import settings
|
2011-01-28 08:43:46 +00:00
|
|
|
import ox
|
2010-11-26 15:07:24 +00:00
|
|
|
|
2011-10-02 18:16:28 +00:00
|
|
|
from archive import extract
|
|
|
|
from clip.models import Clip
|
|
|
|
|
2011-11-03 11:31:46 +00:00
|
|
|
from item.utils import sort_string
|
2011-06-17 07:44:45 +00:00
|
|
|
import managers
|
2011-10-27 08:44:05 +00:00
|
|
|
import utils
|
|
|
|
from tasks import update_matching_events, update_matching_places
|
|
|
|
|
2010-12-28 14:04:28 +00:00
|
|
|
|
2011-02-11 10:21:25 +00:00
|
|
|
|
2010-11-28 16:03:23 +00:00
|
|
|
class Annotation(models.Model):
|
2011-06-17 07:44:45 +00:00
|
|
|
objects = managers.AnnotationManager()
|
2011-01-01 11:44:42 +00:00
|
|
|
|
2010-11-26 15:07:24 +00:00
|
|
|
#FIXME: here having a item,start index would be good
|
|
|
|
created = models.DateTimeField(auto_now_add=True)
|
|
|
|
modified = models.DateTimeField(auto_now=True)
|
|
|
|
user = models.ForeignKey(User)
|
2011-01-06 03:11:00 +00:00
|
|
|
item = models.ForeignKey('item.Item', related_name='annotations')
|
2011-10-02 18:16:28 +00:00
|
|
|
clip = models.ForeignKey('clip.Clip', null=True, related_name='annotations')
|
2010-11-26 15:07:24 +00:00
|
|
|
|
2011-10-18 12:01:01 +00:00
|
|
|
public_id = models.CharField(max_length=128, unique=True, null=True)
|
2010-11-26 15:07:24 +00:00
|
|
|
#seconds
|
2011-08-23 10:47:59 +00:00
|
|
|
start = models.FloatField(default=-1, db_index=True)
|
2011-01-18 09:54:14 +00:00
|
|
|
end = models.FloatField(default=-1)
|
2010-11-26 15:07:24 +00:00
|
|
|
|
2011-11-02 14:06:34 +00:00
|
|
|
layer = models.CharField(max_length=255, db_index=True)
|
2010-11-26 15:07:24 +00:00
|
|
|
value = models.TextField()
|
2011-12-26 14:30:30 +00:00
|
|
|
findvalue = models.TextField()
|
2011-11-03 11:31:46 +00:00
|
|
|
sortvalue = models.CharField(max_length=1000, null=True, blank=True, db_index=True)
|
2010-11-26 15:07:24 +00:00
|
|
|
|
|
|
|
def editable(self, user):
|
|
|
|
if user.is_authenticated():
|
2012-01-02 15:08:38 +00:00
|
|
|
if user.get_profile().capability('canEditAnnotations') or \
|
2011-01-21 09:31:49 +00:00
|
|
|
self.user == user or \
|
|
|
|
user.groups.filter(id__in=self.groups.all()).count() > 0:
|
2010-11-26 15:07:24 +00:00
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2011-09-30 22:28:35 +00:00
|
|
|
def set_public_id(self):
|
2011-10-29 14:12:28 +00:00
|
|
|
if self.id:
|
2011-12-18 09:35:49 +00:00
|
|
|
public_id = Annotation.objects.filter(item=self.item, id__lt=self.id).count() + 1
|
2012-01-03 09:16:45 +00:00
|
|
|
if public_id > 1:
|
|
|
|
previous = Annotation.objects.filter(item=self.item,
|
|
|
|
id__lt=self.id).order_by('-id')[0]
|
|
|
|
if not previous.public_id:
|
|
|
|
previous.set_public_id()
|
|
|
|
public_id = ox.fromAZ(previous.public_id.split('/')[-1]) + 1
|
2011-12-18 09:35:49 +00:00
|
|
|
self.public_id = "%s/%s" % (self.item.itemId, ox.toAZ(public_id))
|
2011-10-29 14:12:28 +00:00
|
|
|
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
|
2011-09-30 22:28:35 +00:00
|
|
|
|
2012-01-10 16:00:41 +00:00
|
|
|
@classmethod
|
|
|
|
def public_layers(self):
|
|
|
|
layers = []
|
|
|
|
for layer in settings.CONFIG['layers']:
|
|
|
|
if not layer.get('private', False):
|
|
|
|
layers.append(layer['id'])
|
|
|
|
return layers
|
|
|
|
|
2011-12-26 14:30:30 +00:00
|
|
|
def get_layer(self):
|
|
|
|
for layer in settings.CONFIG['layers']:
|
|
|
|
if layer['id'] == self.layer:
|
|
|
|
return layer
|
|
|
|
return {}
|
|
|
|
|
2011-08-23 10:47:59 +00:00
|
|
|
def save(self, *args, **kwargs):
|
2011-10-29 14:12:28 +00:00
|
|
|
set_public_id = not self.id or not self.public_id
|
2011-12-26 14:30:30 +00:00
|
|
|
layer = self.get_layer()
|
2011-11-03 11:44:53 +00:00
|
|
|
if self.value:
|
2011-12-26 14:43:04 +00:00
|
|
|
self.value = utils.cleanup_value(self.value, layer['type'])
|
2011-12-26 14:30:30 +00:00
|
|
|
self.findvalue = ox.stripTags(self.value).strip()
|
2011-12-26 14:43:04 +00:00
|
|
|
sortvalue = sort_string(self.findvalue)
|
2011-11-03 11:44:53 +00:00
|
|
|
if sortvalue:
|
|
|
|
self.sortvalue = sortvalue[:1000]
|
|
|
|
else:
|
|
|
|
self.sortvalue = None
|
|
|
|
else:
|
|
|
|
self.sortvalue = None
|
2011-10-04 09:39:00 +00:00
|
|
|
|
|
|
|
#no clip or update clip
|
2011-12-26 14:30:30 +00:00
|
|
|
private = layer.get('private', False)
|
2011-12-05 13:48:59 +00:00
|
|
|
if not private:
|
|
|
|
if not self.clip or self.start != self.clip.start or self.end != self.clip.end:
|
|
|
|
self.clip, created = Clip.get_or_create(self.item, self.start, self.end)
|
2011-10-04 09:39:00 +00:00
|
|
|
|
2011-08-23 10:47:59 +00:00
|
|
|
super(Annotation, self).save(*args, **kwargs)
|
2011-10-25 16:22:10 +00:00
|
|
|
if set_public_id:
|
|
|
|
self.set_public_id()
|
2011-11-02 13:26:38 +00:00
|
|
|
|
2011-12-18 09:47:12 +00:00
|
|
|
if self.clip:
|
|
|
|
Clip.objects.filter(**{
|
|
|
|
'id': self.clip.id,
|
|
|
|
self.layer: False
|
|
|
|
}).update(**{self.layer: True})
|
2011-11-02 13:26:38 +00:00
|
|
|
|
2012-01-02 17:35:10 +00:00
|
|
|
if filter(lambda l: l['type'] == 'place' or l.get('hasPlaces'),
|
|
|
|
settings.CONFIG['layers']):
|
2012-01-13 16:26:07 +00:00
|
|
|
#update_matching_places.delay(self.id)
|
|
|
|
#editAnnotations needs to be in snyc
|
|
|
|
update_matching_places(self.id)
|
2012-01-02 17:35:10 +00:00
|
|
|
if filter(lambda l: l['type'] == 'event' or l.get('hasEvents'),
|
|
|
|
settings.CONFIG['layers']):
|
2012-01-13 16:26:07 +00:00
|
|
|
#update_matching_events.delay(self.id)
|
|
|
|
#editAnnotations needs to be in snyc
|
|
|
|
update_matching_events(self.id)
|
2011-01-18 09:54:14 +00:00
|
|
|
|
2012-01-12 19:32:54 +00:00
|
|
|
def json(self, layer=False, keys=None, user=None):
|
2011-06-01 11:03:07 +00:00
|
|
|
j = {
|
2010-12-28 14:04:28 +00:00
|
|
|
'user': self.user.username,
|
|
|
|
}
|
2012-01-12 19:32:54 +00:00
|
|
|
for key in ('id', 'in', 'out', 'value', 'created', 'modified'):
|
|
|
|
j[key] = getattr(self, {
|
2011-10-04 09:39:00 +00:00
|
|
|
'duration': 'clip__duration',
|
|
|
|
'hue': 'clip__hue',
|
2011-09-30 14:16:11 +00:00
|
|
|
'id': 'public_id',
|
|
|
|
'in': 'start',
|
2011-10-04 09:39:00 +00:00
|
|
|
'lightness': 'clip__lightness',
|
2011-09-30 14:16:11 +00:00
|
|
|
'out': 'end',
|
2011-10-04 09:39:00 +00:00
|
|
|
'saturation': 'clip__saturation',
|
|
|
|
'volume': 'clip__volume',
|
2012-01-12 19:32:54 +00:00
|
|
|
}.get(key, key))
|
|
|
|
|
|
|
|
l = self.get_layer()
|
|
|
|
if l['type'] == 'place':
|
|
|
|
qs = self.places.all()
|
|
|
|
if qs.count() > 0:
|
|
|
|
j['place'] = qs[0].json(user=user)
|
|
|
|
elif l['type'] == 'event':
|
|
|
|
qs = self.events.all()
|
|
|
|
if qs.count() > 0:
|
|
|
|
j['event'] = qs[0].json(user=user)
|
|
|
|
|
2011-10-19 15:55:29 +00:00
|
|
|
if layer or (keys and 'layer' in keys):
|
2011-11-02 14:42:07 +00:00
|
|
|
j['layer'] = self.layer
|
2011-06-16 20:00:10 +00:00
|
|
|
if keys:
|
|
|
|
_j = {}
|
|
|
|
for key in keys:
|
|
|
|
if key in j:
|
|
|
|
_j[key] = j[key]
|
|
|
|
j = _j
|
2011-08-19 14:43:05 +00:00
|
|
|
if 'videoRatio' in keys:
|
|
|
|
streams = self.item.streams()
|
|
|
|
if streams:
|
|
|
|
j['videoRatio'] = streams[0].aspect_ratio
|
2011-06-01 11:03:07 +00:00
|
|
|
return j
|
2010-12-28 14:04:28 +00:00
|
|
|
|
2010-11-28 16:31:53 +00:00
|
|
|
def __unicode__(self):
|
2011-10-29 14:45:27 +00:00
|
|
|
return u"%s %s-%s" %(self.public_id, self.start, self.end)
|
2011-06-04 16:19:06 +00:00
|
|
|
|