forked from 0x2620/pandora
merge
This commit is contained in:
commit
c6f11433f9
7 changed files with 159 additions and 111 deletions
|
@ -109,12 +109,13 @@ class Annotation(models.Model):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def set_public_id(self):
|
def set_public_id(self):
|
||||||
|
if self.id:
|
||||||
public_id = Annotation.objects.filter(item=self.item, id__lt=self.id).count()
|
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))
|
self.public_id = "%s/%s" % (self.item.itemId, ox.to26(public_id))
|
||||||
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
|
Annotation.objects.filter(id=self.id).update(public_id=self.public_id)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
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
|
#no clip or update clip
|
||||||
if not self.clip and not self.layer.private or \
|
if not self.clip and not self.layer.private or \
|
||||||
|
@ -160,5 +161,5 @@ class Annotation(models.Model):
|
||||||
return j
|
return j
|
||||||
|
|
||||||
def __unicode__(self):
|
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)
|
||||||
|
|
||||||
|
|
|
@ -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))))
|
timelines = sorted(filter(lambda t: t!= '%s%sp.png'%(prefix,height), glob("%s%sp*.png"%(prefix, height))))
|
||||||
for image in timelines:
|
for image in timelines:
|
||||||
start_offset = 0
|
start_offset = 0
|
||||||
timeline = Image.open(image).convert('RGB')
|
if start and frames + 1500 < start:
|
||||||
frames += timeline.size[0]
|
frames += 1500
|
||||||
if start and frames < start:
|
|
||||||
continue
|
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])
|
start_offset = start - (frames-timeline.size[0])
|
||||||
box = (start_offset, 0, timeline.size[0], height)
|
box = (start_offset, 0, timeline.size[0], height)
|
||||||
timeline = timeline.crop(box)
|
timeline = timeline.crop(box)
|
||||||
|
@ -307,7 +308,7 @@ def average_color(prefix, start=0, end=0):
|
||||||
box = (0, 0, end_offset, height)
|
box = (0, 0, end_offset, height)
|
||||||
timeline = timeline.crop(box)
|
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
|
p = np.sum(p, axis=0) / height #average color per frame
|
||||||
pixels.append(p)
|
pixels.append(p)
|
||||||
|
|
||||||
|
|
37
pandora/item/management/commands/update_external.py
Normal file
37
pandora/item/management/commands/update_external.py
Normal 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
|
|
@ -13,7 +13,7 @@ import uuid
|
||||||
import unicodedata
|
import unicodedata
|
||||||
from urllib import quote
|
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.db.models import Count, Q, Sum
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -340,6 +340,8 @@ class Item(models.Model):
|
||||||
#FIXME: should this really happen for annotations?
|
#FIXME: should this really happen for annotations?
|
||||||
for a in self.annotations.all():
|
for a in self.annotations.all():
|
||||||
a.item = other
|
a.item = other
|
||||||
|
a.public_id = None
|
||||||
|
a.save()
|
||||||
|
|
||||||
if hasattr(self, 'files'):
|
if hasattr(self, 'files'):
|
||||||
for f in self.files.all():
|
for f in self.files.all():
|
||||||
|
@ -516,6 +518,7 @@ class Item(models.Model):
|
||||||
else:
|
else:
|
||||||
ItemFind.objects.filter(item=self, key=key).delete()
|
ItemFind.objects.filter(item=self, key=key).delete()
|
||||||
|
|
||||||
|
with transaction.commit_on_success():
|
||||||
for key in settings.CONFIG['itemKeys']:
|
for key in settings.CONFIG['itemKeys']:
|
||||||
i = key['id']
|
i = key['id']
|
||||||
if i == 'title':
|
if i == 'title':
|
||||||
|
@ -933,7 +936,7 @@ class Item(models.Model):
|
||||||
|
|
||||||
def make_timeline(self):
|
def make_timeline(self):
|
||||||
streams = self.streams()
|
streams = self.streams()
|
||||||
if len(streams) > 1:
|
if streams.count() > 1:
|
||||||
timelines = [s.timeline_prefix for s in self.streams()]
|
timelines = [s.timeline_prefix for s in self.streams()]
|
||||||
join_timelines(timelines, self.timeline_prefix)
|
join_timelines(timelines, self.timeline_prefix)
|
||||||
|
|
||||||
|
@ -1041,6 +1044,7 @@ class Item(models.Model):
|
||||||
return icon
|
return icon
|
||||||
|
|
||||||
def load_subtitles(self):
|
def load_subtitles(self):
|
||||||
|
with transaction.commit_on_success():
|
||||||
layer = Layer.objects.get(name='subtitles')
|
layer = Layer.objects.get(name='subtitles')
|
||||||
Annotation.objects.filter(layer=layer,item=self).delete()
|
Annotation.objects.filter(layer=layer,item=self).delete()
|
||||||
offset = 0
|
offset = 0
|
||||||
|
@ -1083,7 +1087,8 @@ class Item(models.Model):
|
||||||
annotation.save()
|
annotation.save()
|
||||||
#otherwise add empty 5 seconds annotation every minute
|
#otherwise add empty 5 seconds annotation every minute
|
||||||
if not subtitles_added:
|
if not subtitles_added:
|
||||||
for i in range(int (offset / 60) * 60 + 60,
|
start = offset and int (offset / 60) * 60 + 60 or 0
|
||||||
|
for i in range(start,
|
||||||
int(offset + f.duration) - 5,
|
int(offset + f.duration) - 5,
|
||||||
60):
|
60):
|
||||||
annotation = Annotation(
|
annotation = Annotation(
|
||||||
|
|
|
@ -154,8 +154,9 @@ pandora.ui.clipList = function(videoRatio) {
|
||||||
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
|
poster: '/' + item + '/' + height + 'p' + points[0] + '.jpg',
|
||||||
rewind: true,
|
rewind: true,
|
||||||
video: partsAndPoints.parts.map(function(i) {
|
video: partsAndPoints.parts.map(function(i) {
|
||||||
return '/' + item + '/96p' + (i + 1)
|
var part = (i + 1),
|
||||||
+ '.' + pandora.user.videoFormat;
|
prefix = pandora.site.site.videoprefix.replace('PART', part);
|
||||||
|
return prefix + '/' + item + '/96p' + part + '.' + pandora.user.videoFormat;
|
||||||
}),
|
}),
|
||||||
width: width
|
width: width
|
||||||
})
|
})
|
||||||
|
|
|
@ -35,17 +35,19 @@ pandora.ui.clipPlayer = function() {
|
||||||
length = range[1] - range[0],
|
length = range[1] - range[0],
|
||||||
data = [];
|
data = [];
|
||||||
result.data.items.forEach(function(item, i) {
|
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) {
|
pandora.api.get({id: id, keys: ['durations']}, function(result) {
|
||||||
//Ox.print('API get item', id, 'result', result.data);
|
//Ox.print('API get item', id, 'result', result.data);
|
||||||
var points = [item['in'], item.out],
|
var points = [item['in'], item.out],
|
||||||
partsAndPoints = pandora.getVideoPartsAndPoints(result.data.durations, points);
|
partsAndPoints = pandora.getVideoPartsAndPoints(result.data.durations, points);
|
||||||
data[i] = {
|
data[i] = {
|
||||||
parts: partsAndPoints.parts.map(function(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
|
points: partsAndPoints.points
|
||||||
}
|
};
|
||||||
if (++counter == length) {
|
if (++counter == length) {
|
||||||
callback(data);
|
callback(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,8 +91,9 @@ pandora.ui.itemClips = function(options) {
|
||||||
poster: '/' + self.options.id + '/' + self.height + 'p' + points[0] + '.jpg',
|
poster: '/' + self.options.id + '/' + self.height + 'p' + points[0] + '.jpg',
|
||||||
rewind: true,
|
rewind: true,
|
||||||
video: partsAndPoints.parts.map(function(i) {
|
video: partsAndPoints.parts.map(function(i) {
|
||||||
return '/' + self.options.id + '/96p' + (i + 1)
|
var part = (i + 1),
|
||||||
+ '.' + pandora.user.videoFormat;
|
prefix = pandora.site.site.videoprefix.replace('PART', part);
|
||||||
|
return prefix + '/' + self.options.id + '/96p' + part + '.' + pandora.user.videoFormat;
|
||||||
}),
|
}),
|
||||||
width: self.width
|
width: self.width
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue