forked from 0x2620/pandora
annotation sort
This commit is contained in:
parent
76442b5f34
commit
000362c05c
3 changed files with 58 additions and 4 deletions
|
@ -8,6 +8,7 @@ import ox
|
||||||
|
|
||||||
import utils
|
import utils
|
||||||
import managers
|
import managers
|
||||||
|
from archive import extract
|
||||||
|
|
||||||
|
|
||||||
def load_layers(layers):
|
def load_layers(layers):
|
||||||
|
@ -87,6 +88,12 @@ class Annotation(models.Model):
|
||||||
layer = models.ForeignKey(Layer)
|
layer = models.ForeignKey(Layer)
|
||||||
value = models.TextField()
|
value = models.TextField()
|
||||||
|
|
||||||
|
duration = models.FloatField(default=0, db_index=True)
|
||||||
|
hue = models.FloatField(default=0, db_index=True)
|
||||||
|
saturation = models.FloatField(default=0, db_index=True)
|
||||||
|
lightness = models.FloatField(default=0, db_index=True)
|
||||||
|
volume = models.FloatField(default=0, db_index=True)
|
||||||
|
|
||||||
def editable(self, user):
|
def editable(self, user):
|
||||||
if user.is_authenticated():
|
if user.is_authenticated():
|
||||||
if user.is_staff or \
|
if user.is_staff or \
|
||||||
|
@ -105,6 +112,14 @@ class Annotation(models.Model):
|
||||||
if not self.id:
|
if not self.id:
|
||||||
super(Annotation, self).save(*args, **kwargs)
|
super(Annotation, self).save(*args, **kwargs)
|
||||||
self.public_id = '%s/%s' % (self.item.itemId, ox.to32(self.id))
|
self.public_id = '%s/%s' % (self.item.itemId, ox.to32(self.id))
|
||||||
|
if self.duration != self.end - self.start:
|
||||||
|
self.duration = self.end - self.start
|
||||||
|
if self.duration > 0:
|
||||||
|
self.hue, self.saturation, self.lightness = extract.average_color(
|
||||||
|
self.item.timeline_prefix, self.start, self.end)
|
||||||
|
else:
|
||||||
|
self.hue = self.saturation = self.lightness = 0
|
||||||
|
#FIXME: set volume here
|
||||||
super(Annotation, self).save(*args, **kwargs)
|
super(Annotation, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def json(self, layer=False, keys=None):
|
def json(self, layer=False, keys=None):
|
||||||
|
|
|
@ -32,8 +32,28 @@ def parse_query(data, user):
|
||||||
query['qs'] = query['qs'].filter(item__in=item_query)
|
query['qs'] = query['qs'].filter(item__in=item_query)
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
def annotation_sort_key(key):
|
||||||
|
return {
|
||||||
|
'text': 'value',
|
||||||
|
'position': 'start',
|
||||||
|
}.get(key, key)
|
||||||
|
|
||||||
def order_query(qs, sort):
|
def order_query(qs, sort):
|
||||||
qs = qs.order_by('start')
|
order_by = []
|
||||||
|
print sort
|
||||||
|
for e in sort:
|
||||||
|
operator = e['operator']
|
||||||
|
if operator != '-':
|
||||||
|
operator = ''
|
||||||
|
if e['key'].startswith('clip:'):
|
||||||
|
key = annotation_sort_key(e['key'][len('clip:'):])
|
||||||
|
else:
|
||||||
|
#key mgith need to be changed, see order_sort in item/views.py
|
||||||
|
key = "item__sort__%s" % e['key']
|
||||||
|
order = '%s%s' % (operator, key)
|
||||||
|
order_by.append(order)
|
||||||
|
if order_by:
|
||||||
|
qs = qs.order_by(*order_by, nulls_last=True)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def findAnnotations(request):
|
def findAnnotations(request):
|
||||||
|
@ -70,7 +90,7 @@ def findAnnotations(request):
|
||||||
if qs.count() > 0:
|
if qs.count() > 0:
|
||||||
response['data']['position'] = utils.get_positions(ids, [qs[0].itemId])[0]
|
response['data']['position'] = utils.get_positions(ids, [qs[0].itemId])[0]
|
||||||
elif 'positions' in data:
|
elif 'positions' in data:
|
||||||
ids = [i.get_id() for i in qs]
|
ids = [i.public_id for i in qs]
|
||||||
response['data']['positions'] = utils.get_positions(ids, data['positions'])
|
response['data']['positions'] = utils.get_positions(ids, data['positions'])
|
||||||
else:
|
else:
|
||||||
response['data']['items'] = qs.count()
|
response['data']['items'] = qs.count()
|
||||||
|
|
|
@ -279,20 +279,39 @@ def timeline(video, prefix):
|
||||||
p.wait()
|
p.wait()
|
||||||
|
|
||||||
|
|
||||||
def average_color(prefix):
|
def average_color(prefix, start=0, end=0):
|
||||||
height = 64
|
height = 64
|
||||||
width = 1500
|
|
||||||
frames = 0
|
frames = 0
|
||||||
pixels = []
|
pixels = []
|
||||||
color = np.asarray([0, 0, 0], dtype=np.float32)
|
color = np.asarray([0, 0, 0], dtype=np.float32)
|
||||||
|
|
||||||
|
if end:
|
||||||
|
start = int(start * 25)
|
||||||
|
end = int(end * 25)
|
||||||
for image in sorted(glob("%s.%d.*.png" % (prefix, height))):
|
for image in sorted(glob("%s.%d.*.png" % (prefix, height))):
|
||||||
|
start_offset = 0
|
||||||
timeline = Image.open(image)
|
timeline = Image.open(image)
|
||||||
frames += timeline.size[0]
|
frames += timeline.size[0]
|
||||||
|
if start and frames < start:
|
||||||
|
continue
|
||||||
|
elif start and frames > start > frames-timeline.size[0]:
|
||||||
|
start_offset = start - (frames-timeline.size[0])
|
||||||
|
box = (start_offset, 0, timeline.size[0], height)
|
||||||
|
timeline = timeline.crop(box)
|
||||||
|
if end and frames > end:
|
||||||
|
end_offset = timeline.size[0] - (frames - end)
|
||||||
|
box = (0, 0, end_offset, height)
|
||||||
|
timeline = timeline.crop(box)
|
||||||
|
|
||||||
p = np.asarray(timeline, dtype=np.float32)
|
p = np.asarray(timeline, dtype=np.float32)
|
||||||
p = np.sum(p, axis=0) / height #average color per frame
|
p = np.sum(p, axis=0) / height #average color per frame
|
||||||
pixels.append(p)
|
pixels.append(p)
|
||||||
|
|
||||||
|
if end and frames >= end:
|
||||||
|
break
|
||||||
|
|
||||||
|
if end:
|
||||||
|
frames = end - start
|
||||||
for i in range(0, len(pixels)):
|
for i in range(0, len(pixels)):
|
||||||
p = np.sum(pixels[i], axis=0) / frames
|
p = np.sum(pixels[i], axis=0) / frames
|
||||||
color += p
|
color += p
|
||||||
|
|
Loading…
Reference in a new issue