forked from 0x2620/pandora
rendered, editFile
This commit is contained in:
parent
8d98cb79de
commit
4f71992f2b
10 changed files with 66 additions and 36 deletions
|
@ -20,13 +20,14 @@ import chardet
|
||||||
from item import utils
|
from item import utils
|
||||||
from item.models import Item
|
from item.models import Item
|
||||||
from person.models import get_name_sort
|
from person.models import get_name_sort
|
||||||
from annotation.models import Annotation, Layer
|
|
||||||
|
|
||||||
class File(models.Model):
|
class File(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
modified = models.DateTimeField(auto_now=True)
|
modified = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
verified = models.BooleanField(default=False)
|
verified = models.BooleanField(default=False)
|
||||||
|
auto = models.BooleanField(default=True)
|
||||||
|
|
||||||
oshash = models.CharField(max_length=16, unique=True)
|
oshash = models.CharField(max_length=16, unique=True)
|
||||||
item = models.ForeignKey(Item, related_name='files')
|
item = models.ForeignKey(Item, related_name='files')
|
||||||
|
@ -75,7 +76,7 @@ class File(models.Model):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def set_state(self):
|
||||||
instance = self.get_instance()
|
instance = self.get_instance()
|
||||||
if instance:
|
if instance:
|
||||||
if instance.name.lower().startswith('extras/'):
|
if instance.name.lower().startswith('extras/'):
|
||||||
|
@ -152,6 +153,10 @@ class File(models.Model):
|
||||||
|
|
||||||
if self.type not in ('audio', 'video'):
|
if self.type not in ('audio', 'video'):
|
||||||
self.duration = None
|
self.duration = None
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if self.auto:
|
||||||
|
self.set_state()
|
||||||
super(File, self).save(*args, **kwargs)
|
super(File, self).save(*args, **kwargs)
|
||||||
|
|
||||||
#upload and data handling
|
#upload and data handling
|
||||||
|
@ -268,7 +273,7 @@ class File(models.Model):
|
||||||
'height': self.height,
|
'height': self.height,
|
||||||
'width': self.width,
|
'width': self.width,
|
||||||
'resolution': resolution,
|
'resolution': resolution,
|
||||||
'oshash': self.oshash,
|
'id': self.oshash,
|
||||||
'samplerate': self.samplerate,
|
'samplerate': self.samplerate,
|
||||||
'video_codec': self.video_codec,
|
'video_codec': self.video_codec,
|
||||||
'audio_codec': self.audio_codec,
|
'audio_codec': self.audio_codec,
|
||||||
|
|
|
@ -119,7 +119,7 @@ actions.register(encodingProfile)
|
||||||
@login_required_json
|
@login_required_json
|
||||||
def upload(request):
|
def upload(request):
|
||||||
'''
|
'''
|
||||||
oshash: string
|
id: string
|
||||||
frame: [] //multipart frames
|
frame: [] //multipart frames
|
||||||
file: [] //multipart file
|
file: [] //multipart file
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ def upload(request):
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
response = json_response({})
|
response = json_response({})
|
||||||
f = get_object_or_404_json(models.File, oshash=request.POST['oshash'])
|
f = get_object_or_404_json(models.File, oshash=request.POST['id'])
|
||||||
if 'frame' in request.FILES:
|
if 'frame' in request.FILES:
|
||||||
if f.frames.count() == 0:
|
if f.frames.count() == 0:
|
||||||
for frame in request.FILES.getlist('frame'):
|
for frame in request.FILES.getlist('frame'):
|
||||||
|
@ -164,7 +164,7 @@ class VideoChunkForm(forms.Form):
|
||||||
@login_required_json
|
@login_required_json
|
||||||
def firefogg_upload(request):
|
def firefogg_upload(request):
|
||||||
profile = request.GET['profile']
|
profile = request.GET['profile']
|
||||||
oshash = request.GET['oshash']
|
oshash = request.GET['id']
|
||||||
#handle video upload
|
#handle video upload
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
#post next chunk
|
#post next chunk
|
||||||
|
@ -203,7 +203,7 @@ def firefogg_upload(request):
|
||||||
f.save()
|
f.save()
|
||||||
response = {
|
response = {
|
||||||
#is it possible to no hardcode url here?
|
#is it possible to no hardcode url here?
|
||||||
'uploadUrl': request.build_absolute_uri('/api/upload/?oshash=%s&profile=%s' % (f.oshash, profile)),
|
'uploadUrl': request.build_absolute_uri('/api/upload/?id=%s&profile=%s' % (f.oshash, profile)),
|
||||||
'result': 1
|
'result': 1
|
||||||
}
|
}
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
|
@ -221,6 +221,7 @@ def taskStatus(request):
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(taskStatus, cache=False)
|
actions.register(taskStatus, cache=False)
|
||||||
|
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
def moveFiles(request):
|
def moveFiles(request):
|
||||||
'''
|
'''
|
||||||
|
@ -253,37 +254,34 @@ def moveFiles(request):
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(moveFiles, cache=False)
|
actions.register(moveFiles, cache=False)
|
||||||
|
|
||||||
|
|
||||||
@login_required_json
|
@login_required_json
|
||||||
def editFile(request):
|
def editFile(request):
|
||||||
'''
|
'''
|
||||||
change file / item link
|
change file / item link
|
||||||
param data {
|
param data {
|
||||||
oshash: hash of file
|
id: hash of file
|
||||||
itemId: new itemId
|
part:
|
||||||
|
id_extra: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: {'code': int, 'text': string},
|
status: {'code': int, 'text': string},
|
||||||
data: {
|
data: {
|
||||||
imdbId:string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
#FIXME: permissions, need to be checked
|
#FIXME: permissions, need to be checked
|
||||||
data = json.loads(request.POST['data'])
|
data = json.loads(request.POST['data'])
|
||||||
f = get_object_or_404_json(models.File, oshash=data['oshash'])
|
f = get_object_or_404_json(models.File, oshash=data['id'])
|
||||||
response = json_response()
|
response = json_response()
|
||||||
if f.item.id != data['itemId']:
|
if data.keys() != ('id', ):
|
||||||
if len(data['itemId']) != 7:
|
for key in data:
|
||||||
folder = f.instances.all()[0].folder
|
if key in ('is_extra', 'is_subtitle', 'is_video', 'is_version',
|
||||||
item_info = utils.parse_path(folder)
|
'part', 'language'):
|
||||||
item = get_item(item_info)
|
setattr(f, key, data[key])
|
||||||
else:
|
f.auto = False
|
||||||
item = get_item({'imdbId': data['itemId']})
|
|
||||||
f.item = item
|
|
||||||
f.save()
|
f.save()
|
||||||
#FIXME: other things might need updating here
|
|
||||||
response = json_response(text='updated')
|
|
||||||
return render_to_json_response(response)
|
return render_to_json_response(response)
|
||||||
actions.register(editFile, cache=False)
|
actions.register(editFile, cache=False)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import models
|
||||||
|
|
||||||
class ItemAdmin(admin.ModelAdmin):
|
class ItemAdmin(admin.ModelAdmin):
|
||||||
search_fields = ['itemId', 'data', 'external_data']
|
search_fields = ['itemId', 'data', 'external_data']
|
||||||
list_display = ['available', 'itemId', '__unicode__']
|
list_display = ['rendered', 'itemId', '__unicode__']
|
||||||
list_display_links = ('__unicode__', )
|
list_display_links = ('__unicode__', )
|
||||||
|
|
||||||
admin.site.register(models.Item, ItemAdmin)
|
admin.site.register(models.Item, ItemAdmin)
|
||||||
|
|
|
@ -239,7 +239,6 @@ class ItemManager(Manager):
|
||||||
#join query with operator
|
#join query with operator
|
||||||
qs = self.get_query_set()
|
qs = self.get_query_set()
|
||||||
#only include items that have hard metadata
|
#only include items that have hard metadata
|
||||||
qs = qs.filter(available=True)
|
|
||||||
conditions = parseConditions(data.get('query', {}).get('conditions', []),
|
conditions = parseConditions(data.get('query', {}).get('conditions', []),
|
||||||
data.get('query', {}).get('operator', '&'))
|
data.get('query', {}).get('operator', '&'))
|
||||||
qs = qs.filter(conditions).distinct()
|
qs = qs.filter(conditions).distinct()
|
||||||
|
|
|
@ -100,9 +100,8 @@ class Item(models.Model):
|
||||||
user = models.ForeignKey(User, null=True, related_name='items')
|
user = models.ForeignKey(User, null=True, related_name='items')
|
||||||
groups = models.ManyToManyField(Group, blank=True, related_name='items')
|
groups = models.ManyToManyField(Group, blank=True, related_name='items')
|
||||||
|
|
||||||
#only items that have data from files are available,
|
#while metadata is updated, files are set to rendered=False
|
||||||
#this is indicated by setting available to True
|
rendered = models.BooleanField(default=False, db_index=True)
|
||||||
available = models.BooleanField(default=False, db_index=True)
|
|
||||||
public = models.BooleanField(default=False, db_index=True)
|
public = models.BooleanField(default=False, db_index=True)
|
||||||
|
|
||||||
itemId = models.CharField(max_length=128, unique=True, blank=True)
|
itemId = models.CharField(max_length=128, unique=True, blank=True)
|
||||||
|
@ -133,7 +132,7 @@ class Item(models.Model):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def access(self, user):
|
def access(self, user):
|
||||||
if self.public and self.available:
|
if self.public:
|
||||||
return True
|
return True
|
||||||
elif user.is_authenticated() and \
|
elif user.is_authenticated() and \
|
||||||
(user.is_staff or self.user == user or \
|
(user.is_staff or self.user == user or \
|
||||||
|
@ -333,7 +332,8 @@ class Item(models.Model):
|
||||||
|
|
||||||
def get_json(self, fields=None):
|
def get_json(self, fields=None):
|
||||||
i = {
|
i = {
|
||||||
'id': self.itemId
|
'id': self.itemId,
|
||||||
|
'rendered': self.rendered
|
||||||
}
|
}
|
||||||
i.update(self.external_data)
|
i.update(self.external_data)
|
||||||
i.update(self.data)
|
i.update(self.data)
|
||||||
|
@ -526,7 +526,7 @@ class Item(models.Model):
|
||||||
s.volume = None
|
s.volume = None
|
||||||
|
|
||||||
if 'color' in self.data:
|
if 'color' in self.data:
|
||||||
s.hue, s.saturation, s.brightness = self.data['color']
|
s.hue, s.saturation, s.lightness = self.data['color']
|
||||||
else:
|
else:
|
||||||
s.hue = None
|
s.hue = None
|
||||||
s.saturation = None
|
s.saturation = None
|
||||||
|
@ -657,7 +657,7 @@ class Item(models.Model):
|
||||||
self.make_local_posters()
|
self.make_local_posters()
|
||||||
self.make_poster()
|
self.make_poster()
|
||||||
self.make_icon()
|
self.make_icon()
|
||||||
self.available = True
|
self.rendered = True
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -553,7 +553,9 @@ def poster(request, id, size=None):
|
||||||
if not size:
|
if not size:
|
||||||
size='large'
|
size='large'
|
||||||
poster_path = os.path.join(settings.STATIC_ROOT, 'png/posterDark.48.png')
|
poster_path = os.path.join(settings.STATIC_ROOT, 'png/posterDark.48.png')
|
||||||
return HttpFileResponse(poster_path, content_type='image/jpeg')
|
response = HttpFileResponse(poster_path, content_type='image/jpeg')
|
||||||
|
response['Cache-Control'] = 'no-cache'
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def icon(request, id, size=None):
|
def icon(request, id, size=None):
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
-e bzr+http://code.0x2620.org/python-ox/#egg=python-ox
|
-e bzr+http://code.0x2620.org/python-ox/#egg=python-ox
|
||||||
-e bzr+http://code.0x2620.org/oxtimeline/#egg=oxtimeline
|
-e bzr+http://code.0x2620.org/oxtimeline/#egg=oxtimeline
|
||||||
simplejson
|
simplejson
|
||||||
|
chardet
|
||||||
-e hg+https://django-ajax-filtered-fields.googlecode.com/hg/#egg=django-ajax-filtered-fields
|
-e hg+https://django-ajax-filtered-fields.googlecode.com/hg/#egg=django-ajax-filtered-fields
|
||||||
celery>2.1.1
|
celery>2.1.1
|
||||||
django-celery>2.1.1
|
django-celery>2.1.1
|
||||||
|
|
|
@ -105,9 +105,9 @@ Ox.FilesView = function(options, self) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
id: 'oshash',
|
id: 'id',
|
||||||
operator: '+',
|
operator: '+',
|
||||||
title: 'Hash',
|
title: 'ID',
|
||||||
unique: true,
|
unique: true,
|
||||||
visible: false,
|
visible: false,
|
||||||
width: 120
|
width: 120
|
||||||
|
|
|
@ -6,6 +6,14 @@ pandora.ui.item = function() {
|
||||||
pandora.$ui.contentPanel.replaceElement(1,
|
pandora.$ui.contentPanel.replaceElement(1,
|
||||||
Ox.Element().html(
|
Ox.Element().html(
|
||||||
'The '+pandora.site.itemName.singular+' you are looking for does not exist.'));
|
'The '+pandora.site.itemName.singular+' you are looking for does not exist.'));
|
||||||
|
} else if (!result.data.rendered &&
|
||||||
|
['clips', 'map',
|
||||||
|
'player', 'timeline'].indexOf(pandora.user.ui.itemView)>-1) {
|
||||||
|
pandora.$ui.contentPanel.replaceElement(1,
|
||||||
|
Ox.Element().css({margin: '16px'}).html(
|
||||||
|
'We are sorry, "' + result.data.title +
|
||||||
|
'" does not have a '+pandora.user.ui.itemView +
|
||||||
|
' view right now.'));
|
||||||
} else if (pandora.user.ui.itemView == 'calendar') {
|
} else if (pandora.user.ui.itemView == 'calendar') {
|
||||||
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar'));
|
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Calendar'));
|
||||||
} else if (pandora.user.ui.itemView == 'clips') {
|
} else if (pandora.user.ui.itemView == 'clips') {
|
||||||
|
@ -55,7 +63,7 @@ pandora.ui.item = function() {
|
||||||
var $form,
|
var $form,
|
||||||
$edit = Ox.Element()
|
$edit = Ox.Element()
|
||||||
.append($form = Ox.FormElementGroup({
|
.append($form = Ox.FormElementGroup({
|
||||||
elements: Ox.map(pandora.site.itemKeys, function(key) {
|
elements: Ox.map(pandora.site.sortKeys, function(key) {
|
||||||
return Ox.Input({
|
return Ox.Input({
|
||||||
id: key.id,
|
id: key.id,
|
||||||
label: key.title,
|
label: key.title,
|
||||||
|
@ -228,7 +236,14 @@ pandora.ui.item = function() {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} else if (pandora.user.ui.itemView == 'statistics') {
|
} else if (pandora.user.ui.itemView == 'statistics') {
|
||||||
pandora.$ui.contentPanel.replaceElement(1, Ox.Element().html('Statistics'));
|
var stats = Ox.Container();
|
||||||
|
Ox.TreeList({
|
||||||
|
data: result.data,
|
||||||
|
width: 256
|
||||||
|
}).appendTo(stats);
|
||||||
|
|
||||||
|
pandora.$ui.contentPanel.replaceElement(1, stats);
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'timeline') {
|
} else if (pandora.user.ui.itemView == 'timeline') {
|
||||||
var layers = [],
|
var layers = [],
|
||||||
video = result.data.stream,
|
video = result.data.stream,
|
||||||
|
|
|
@ -48,7 +48,7 @@ pandora.ui.list = function(view) { // fixme: remove view argument
|
||||||
})
|
})
|
||||||
.bindEvent({
|
.bindEvent({
|
||||||
columnchange: function(event, data) {
|
columnchange: function(event, data) {
|
||||||
var columnWidth = {}
|
var columnWidth = {};
|
||||||
pandora.UI.set(['lists', pandora.user.ui.list, 'columns'].join('|'), data.ids);
|
pandora.UI.set(['lists', pandora.user.ui.list, 'columns'].join('|'), data.ids);
|
||||||
/*
|
/*
|
||||||
data.ids.forEach(function(id) {
|
data.ids.forEach(function(id) {
|
||||||
|
@ -95,6 +95,16 @@ pandora.ui.list = function(view) { // fixme: remove view argument
|
||||||
sort: pandora.user.ui.lists[pandora.user.ui.list].sort,
|
sort: pandora.user.ui.lists[pandora.user.ui.list].sort,
|
||||||
unique: 'id'
|
unique: 'id'
|
||||||
});
|
});
|
||||||
|
} else if (view == 'info') {
|
||||||
|
that = Ox.Element().css({margin: '16px'}).html(view + ' results view still missing.');
|
||||||
|
} else if (view == 'clips') {
|
||||||
|
that = Ox.Element().css({margin: '16px'}).html(view + ' results view still missing.');
|
||||||
|
} else if (view == 'timelines') {
|
||||||
|
that = Ox.Element().css({margin: '16px'}).html(view + ' results view still missing.');
|
||||||
|
} else if (view == 'maps') {
|
||||||
|
that = Ox.Element().css({margin: '16px'}).html(view + ' results view still missing.');
|
||||||
|
} else if (view == 'calendars') {
|
||||||
|
that = Ox.Element().css({margin: '16px'}).html(view + ' results view still missing.');
|
||||||
} else if (view == 'clip') {
|
} else if (view == 'clip') {
|
||||||
that = Ox.IconList({
|
that = Ox.IconList({
|
||||||
item: function(data, sort, size) {
|
item: function(data, sort, size) {
|
||||||
|
|
Loading…
Reference in a new issue