This commit is contained in:
rolux 2011-10-29 16:58:47 +00:00
commit c6f11433f9
7 changed files with 159 additions and 111 deletions

View file

@ -109,12 +109,13 @@ class Annotation(models.Model):
return self.value
def set_public_id(self):
public_id = Annotation.objects.filter(item=self.item, id__lt=self.id).count()
self.public_id = "%s/%s" % (self.item.itemId, ox.to26(public_id))
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
if self.id:
public_id = Annotation.objects.filter(item=self.item, id__lt=self.id).count()
self.public_id = "%s/%s" % (self.item.itemId, ox.to26(public_id))
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
def save(self, *args, **kwargs):
set_public_id = not self.id
set_public_id = not self.id or not self.public_id
#no clip or update clip
if not self.clip and not self.layer.private or \
@ -160,5 +161,5 @@ class Annotation(models.Model):
return j
def __unicode__(self):
return u"%s/%s-%s" %(self.item, self.start, self.end)
return u"%s %s-%s" %(self.public_id, self.start, self.end)

View file

@ -294,11 +294,12 @@ def average_color(prefix, start=0, end=0):
timelines = sorted(filter(lambda t: t!= '%s%sp.png'%(prefix,height), glob("%s%sp*.png"%(prefix, height))))
for image in timelines:
start_offset = 0
timeline = Image.open(image).convert('RGB')
frames += timeline.size[0]
if start and frames < start:
if start and frames + 1500 < start:
frames += 1500
continue
elif start and frames > start > frames-timeline.size[0]:
timeline = Image.open(image)
frames += timeline.size[0]
if 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)
@ -307,7 +308,7 @@ def average_color(prefix, start=0, end=0):
box = (0, 0, end_offset, height)
timeline = timeline.crop(box)
p = np.asarray(timeline, dtype=np.float32)
p = np.asarray(timeline.convert('RGB'), dtype=np.float32)
p = np.sum(p, axis=0) / height #average color per frame
pixels.append(p)

View file

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from optparse import make_option
import os
from os.path import join, dirname, basename, splitext, exists
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
import monkey_patch.models
from ... import models
class Command(BaseCommand):
"""
rebuild sort/search cache for all items.
"""
help = 'listen to rabbitmq and execute encoding tasks.'
args = ''
option_list = BaseCommand.option_list + (
make_option('--all', action='store_true', dest='all',
default=False, help='update all items, otherwise oldes N'),
make_option('-n', '--items', action='store', dest='items', type=int,
default=30, help='number of items ot update'),
)
def handle(self, **options):
offset = 0
chunk = options['all'] and 100 or options['items']
count = pos = models.Item.objects.count()
while options['all'] and offset <= count or offset < options['items']:
for i in models.Item.objects.all().order_by('modified')[offset:offset+chunk]:
print pos, i.itemId, i.modified
i.update_external()
pos -= 1
offset += chunk

View file

@ -13,7 +13,7 @@ import uuid
import unicodedata
from urllib import quote
from django.db import models
from django.db import models, transaction
from django.db.models import Count, Q, Sum
from django.core.files.base import ContentFile
from django.conf import settings
@ -340,6 +340,8 @@ class Item(models.Model):
#FIXME: should this really happen for annotations?
for a in self.annotations.all():
a.item = other
a.public_id = None
a.save()
if hasattr(self, 'files'):
for f in self.files.all():
@ -516,45 +518,46 @@ class Item(models.Model):
else:
ItemFind.objects.filter(item=self, key=key).delete()
for key in settings.CONFIG['itemKeys']:
i = key['id']
if i == 'title':
save(i, u'\n'.join([self.get('title', 'Untitled'),
self.get('originalTitle', '')]))
elif i == 'rightslevel':
save(i, self.level)
elif i == 'filename':
save(i,
'\n'.join([f.path for f in self.files.all()]))
elif key['type'] == 'layer':
qs = Annotation.objects.filter(layer__name=i, item=self).order_by('start')
save(i, '\n'.join([l.value for l in qs]))
elif i != '*' and i not in self.facet_keys:
value = self.get(i)
if isinstance(value, list):
value = u'\n'.join(value)
save(i, value)
with transaction.commit_on_success():
for key in settings.CONFIG['itemKeys']:
i = key['id']
if i == 'title':
save(i, u'\n'.join([self.get('title', 'Untitled'),
self.get('originalTitle', '')]))
elif i == 'rightslevel':
save(i, self.level)
elif i == 'filename':
save(i,
'\n'.join([f.path for f in self.files.all()]))
elif key['type'] == 'layer':
qs = Annotation.objects.filter(layer__name=i, item=self).order_by('start')
save(i, '\n'.join([l.value for l in qs]))
elif i != '*' and i not in self.facet_keys:
value = self.get(i)
if isinstance(value, list):
value = u'\n'.join(value)
save(i, value)
for key in self.facet_keys:
if key == 'character':
values = self.get('cast', '')
if values:
values = filter(lambda x: x.strip(),
[f['character'] for f in values])
for key in self.facet_keys:
if key == 'character':
values = self.get('cast', '')
if values:
values = filter(lambda x: x.strip(),
[f['character'] for f in values])
values = list(set(values))
elif key == 'name':
values = []
for k in map(lambda x: x['id'],
filter(lambda x: x.get('sort') == 'person',
settings.CONFIG['itemKeys'])):
values += self.get(k, [])
values = list(set(values))
elif key == 'name':
values = []
for k in map(lambda x: x['id'],
filter(lambda x: x.get('sort') == 'person',
settings.CONFIG['itemKeys'])):
values += self.get(k, [])
values = list(set(values))
else:
values = self.get(key, '')
if isinstance(values, list):
save(key, '\n'.join(values))
else:
save(key, values)
else:
values = self.get(key, '')
if isinstance(values, list):
save(key, '\n'.join(values))
else:
save(key, values)
def update_sort(self):
try:
@ -933,7 +936,7 @@ class Item(models.Model):
def make_timeline(self):
streams = self.streams()
if len(streams) > 1:
if streams.count() > 1:
timelines = [s.timeline_prefix for s in self.streams()]
join_timelines(timelines, self.timeline_prefix)
@ -1041,61 +1044,63 @@ class Item(models.Model):
return icon
def load_subtitles(self):
layer = Layer.objects.get(name='subtitles')
Annotation.objects.filter(layer=layer,item=self).delete()
offset = 0
language = ''
subtitles = self.files.filter(selected=True, is_subtitle=True, available=True)
languages = [f.language for f in subtitles]
if languages:
if 'en' in languages:
language = 'en'
elif '' in languages:
language = ''
else:
language = languages[0]
with transaction.commit_on_success():
layer = Layer.objects.get(name='subtitles')
Annotation.objects.filter(layer=layer,item=self).delete()
offset = 0
language = ''
subtitles = self.files.filter(selected=True, is_subtitle=True, available=True)
languages = [f.language for f in subtitles]
if languages:
if 'en' in languages:
language = 'en'
elif '' in languages:
language = ''
else:
language = languages[0]
#loop over all videos
for f in self.files.filter(Q(is_audio=True)|Q(is_video=True)) \
.filter(selected=True).order_by('part'):
subtitles_added = False
prefix = os.path.splitext(f.path)[0]
if f.instances.all().count() > 0:
user = f.instances.all()[0].volume.user
else:
#FIXME: allow annotations from no user instead?
user = User.objects.all().order_by('id')[0]
#if there is a subtitle with the same prefix, import
q = subtitles.filter(path__startswith=prefix,
language=language)
if q.count() == 1:
s = q[0]
for data in s.srt(offset):
subtitles_added = True
annotation = Annotation(
item=self,
layer=layer,
start=data['in'],
end=data['out'],
value=data['value'],
user=user
)
annotation.save()
#otherwise add empty 5 seconds annotation every minute
if not subtitles_added:
for i in range(int (offset / 60) * 60 + 60,
int(offset + f.duration) - 5,
60):
annotation = Annotation(
item=self,
layer=layer,
start=i,
end=i + 5,
value='',
user=user
)
annotation.save()
offset += f.duration
#loop over all videos
for f in self.files.filter(Q(is_audio=True)|Q(is_video=True)) \
.filter(selected=True).order_by('part'):
subtitles_added = False
prefix = os.path.splitext(f.path)[0]
if f.instances.all().count() > 0:
user = f.instances.all()[0].volume.user
else:
#FIXME: allow annotations from no user instead?
user = User.objects.all().order_by('id')[0]
#if there is a subtitle with the same prefix, import
q = subtitles.filter(path__startswith=prefix,
language=language)
if q.count() == 1:
s = q[0]
for data in s.srt(offset):
subtitles_added = True
annotation = Annotation(
item=self,
layer=layer,
start=data['in'],
end=data['out'],
value=data['value'],
user=user
)
annotation.save()
#otherwise add empty 5 seconds annotation every minute
if not subtitles_added:
start = offset and int (offset / 60) * 60 + 60 or 0
for i in range(start,
int(offset + f.duration) - 5,
60):
annotation = Annotation(
item=self,
layer=layer,
start=i,
end=i + 5,
value='',
user=user
)
annotation.save()
offset += f.duration
self.update_find()
def delete_item(sender, **kwargs):

View file

@ -154,8 +154,9 @@ pandora.ui.clipList = function(videoRatio) {
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
rewind: true,
video: partsAndPoints.parts.map(function(i) {
return '/' + item + '/96p' + (i + 1)
+ '.' + pandora.user.videoFormat;
var part = (i + 1),
prefix = pandora.site.site.videoprefix.replace('PART', part);
return prefix + '/' + item + '/96p' + part + '.' + pandora.user.videoFormat;
}),
width: width
})

View file

@ -35,17 +35,19 @@ pandora.ui.clipPlayer = function() {
length = range[1] - range[0],
data = [];
result.data.items.forEach(function(item, i) {
var id = item.id.split('/')[0]
var id = item.id.split('/')[0];
pandora.api.get({id: id, keys: ['durations']}, function(result) {
//Ox.print('API get item', id, 'result', result.data);
var points = [item['in'], item.out],
partsAndPoints = pandora.getVideoPartsAndPoints(result.data.durations, points);
data[i] = {
parts: partsAndPoints.parts.map(function(i) {
return '/' + id + '/96p' + (i + 1) + '.' + pandora.user.videoFormat;
var part = (i + 1),
prefix = pandora.site.site.videoprefix.replace('PART', part);
return prefix + '/' + id + '/96p' + part + '.' + pandora.user.videoFormat;
}),
points: partsAndPoints.points
}
};
if (++counter == length) {
callback(data);
}

View file

@ -91,8 +91,9 @@ pandora.ui.itemClips = function(options) {
poster: '/' + self.options.id + '/' + self.height + 'p' + points[0] + '.jpg',
rewind: true,
video: partsAndPoints.parts.map(function(i) {
return '/' + self.options.id + '/96p' + (i + 1)
+ '.' + pandora.user.videoFormat;
var part = (i + 1),
prefix = pandora.site.site.videoprefix.replace('PART', part);
return prefix + '/' + self.options.id + '/96p' + part + '.' + pandora.user.videoFormat;
}),
width: self.width
})
@ -105,4 +106,4 @@ pandora.ui.itemClips = function(options) {
return that;
};
};