- simplify metadata db structure

- better sort values if field is empty
- switch to python-ox, faster imdb import
- move files backend into own app
This commit is contained in:
j 2010-07-12 16:56:14 +02:00
parent d6a95727a6
commit 9defcd3c9f
16 changed files with 1493 additions and 914 deletions

View file

25
pandora/archive/admin.py Normal file
View file

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from django.contrib import admin
#from forms import FileAdminForm, MovieAdminForm, ArchiveFileAdminForm
import models
class FileAdmin(admin.ModelAdmin):
search_fields = ['path', 'video_codec']
#form = FileAdminForm
admin.site.register(models.File, FileAdmin)
class FileInstanceAdmin(admin.ModelAdmin):
search_fields = ['path', 'archive__name']
#form = ArchiveFileAdminForm
admin.site.register(models.FileInstance, FileInstanceAdmin)
class ArchiveAdmin(admin.ModelAdmin):
search_fields = ['name']
admin.site.register(models.Archive, ArchiveAdmin)

View file

@ -0,0 +1,240 @@
# -*- coding: utf-8 -*-
from south.db import db
from django.db import models
from archive.models import *
class Migration:
def forwards(self, orm):
# Adding model 'Volume'
db.create_table('archive_volume', (
('id', orm['archive.Volume:id']),
('start', orm['archive.Volume:start']),
('end', orm['archive.Volume:end']),
('name', orm['archive.Volume:name']),
))
db.send_create_signal('archive', ['Volume'])
# Adding model 'Frame'
db.create_table('archive_frame', (
('id', orm['archive.Frame:id']),
('created', orm['archive.Frame:created']),
('modified', orm['archive.Frame:modified']),
('file', orm['archive.Frame:file']),
('position', orm['archive.Frame:position']),
('frame', orm['archive.Frame:frame']),
))
db.send_create_signal('archive', ['Frame'])
# Adding model 'Archive'
db.create_table('archive_archive', (
('id', orm['archive.Archive:id']),
('created', orm['archive.Archive:created']),
('modified', orm['archive.Archive:modified']),
('published', orm['archive.Archive:published']),
('name', orm['archive.Archive:name']),
('user', orm['archive.Archive:user']),
))
db.send_create_signal('archive', ['Archive'])
# Adding model 'File'
db.create_table('archive_file', (
('id', orm['archive.File:id']),
('created', orm['archive.File:created']),
('modified', orm['archive.File:modified']),
('verified', orm['archive.File:verified']),
('oshash', orm['archive.File:oshash']),
('movie', orm['archive.File:movie']),
('name', orm['archive.File:name']),
('sort_name', orm['archive.File:sort_name']),
('part', orm['archive.File:part']),
('version', orm['archive.File:version']),
('language', orm['archive.File:language']),
('season', orm['archive.File:season']),
('episode', orm['archive.File:episode']),
('size', orm['archive.File:size']),
('duration', orm['archive.File:duration']),
('info', orm['archive.File:info']),
('video_codec', orm['archive.File:video_codec']),
('pixel_format', orm['archive.File:pixel_format']),
('display_aspect_ratio', orm['archive.File:display_aspect_ratio']),
('width', orm['archive.File:width']),
('height', orm['archive.File:height']),
('framerate', orm['archive.File:framerate']),
('audio_codec', orm['archive.File:audio_codec']),
('channels', orm['archive.File:channels']),
('samplerate', orm['archive.File:samplerate']),
('bits_per_pixel', orm['archive.File:bits_per_pixel']),
('pixels', orm['archive.File:pixels']),
('is_audio', orm['archive.File:is_audio']),
('is_video', orm['archive.File:is_video']),
('is_extra', orm['archive.File:is_extra']),
('is_main', orm['archive.File:is_main']),
('is_subtitle', orm['archive.File:is_subtitle']),
('is_version', orm['archive.File:is_version']),
))
db.send_create_signal('archive', ['File'])
# Adding model 'FileInstance'
db.create_table('archive_fileinstance', (
('id', orm['archive.FileInstance:id']),
('created', orm['archive.FileInstance:created']),
('modified', orm['archive.FileInstance:modified']),
('published', orm['archive.FileInstance:published']),
('accessed', orm['archive.FileInstance:accessed']),
('path', orm['archive.FileInstance:path']),
('folder', orm['archive.FileInstance:folder']),
('file', orm['archive.FileInstance:file']),
('archive', orm['archive.FileInstance:archive']),
))
db.send_create_signal('archive', ['FileInstance'])
def backwards(self, orm):
# Deleting model 'Volume'
db.delete_table('archive_volume')
# Deleting model 'Frame'
db.delete_table('archive_frame')
# Deleting model 'Archive'
db.delete_table('archive_archive')
# Deleting model 'File'
db.delete_table('archive_file')
# Deleting model 'FileInstance'
db.delete_table('archive_fileinstance')
models = {
'archive.archive': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_archives'", 'to': "orm['auth.User']"}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}),
'volumes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['archive.Volume']", 'symmetrical': 'False'})
},
'archive.file': {
'audio_codec': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'bits_per_pixel': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'channels': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'display_aspect_ratio': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'duration': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'framerate': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'info': ('fields.DictField', [], {'default': '{}'}),
'is_audio': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_extra': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_main': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_subtitle': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_version': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_video': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '8'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}),
'oshash': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
'part': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
'pixel_format': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'pixels': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'samplerate': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
'sort_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}),
'verified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'version': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
'video_codec': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'width': ('django.db.models.fields.IntegerField', [], {'default': '0'})
},
'archive.fileinstance': {
'accessed': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'archive': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['archive.Archive']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'instances'", 'to': "orm['archive.File']"}),
'folder': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'path': ('django.db.models.fields.CharField', [], {'max_length': '2048'}),
'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
},
'archive.frame': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'frames'", 'to': "orm['archive.File']"}),
'frame': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'position': ('django.db.models.fields.FloatField', [], {})
},
'archive.volume': {
'end': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'start': ('django.db.models.fields.CharField', [], {'max_length': '1'})
},
'auth.group': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'unique_together': "(('content_type', 'codename'),)"},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'backend.movie': {
'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdb': ('fields.DictField', [], {'default': '{}', 'editable': 'False'}),
'json': ('fields.DictField', [], {'default': '{}', 'editable': 'False'}),
'metadata': ('fields.DictField', [], {'default': '{}', 'editable': 'False'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movieId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}),
'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'scene_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'stream_high': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'stream_low': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'stream_mid': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'})
},
'contenttypes.contenttype': {
'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['archive']

View file

182
pandora/archive/models.py Normal file
View file

@ -0,0 +1,182 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from datetime import datetime
import os.path
import random
import re
from decimal import Decimal
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
from django.core.files.base import ContentFile
from django.utils import simplejson as json
from django.conf import settings
from oxdjango import fields
import ox
from ox import stripTags
from ox.normalize import canonicalTitle, canonicalName
from firefogg import Firefogg
from backend import utils
from backend import extract
from pandora.backend.models import Movie
def parse_decimal(string):
string = string.replace(':', '/')
if '/' not in string:
string = '%s/1' % string
d = string.split('/')
return Decimal(d[0]) / Decimal(d[1])
#ARCHIVE stuff
class Volume(models.Model):
start = models.CharField(max_length=1)
end = models.CharField(max_length=1)
name = models.CharField(max_length=255)
class Archive(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
published = models.DateTimeField(default=datetime.now, editable=False)
name = models.CharField(max_length=255)
user = models.ForeignKey(User, related_name='owned_archives')
users = models.ManyToManyField(User, related_name='archives')
volumes = models.ManyToManyField(Volume, related_name='archives')
def editable(self, user):
return self.users.filter(username=user.username).count() > 0
class File(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
verified = models.BooleanField(default = False)
oshash = models.CharField(max_length=16)
movie = models.ForeignKey(Movie, related_name='files')
name = models.CharField(max_length=2048, default="") # canoncial path/file
sort_name = models.CharField(max_length=2048, default="") # sort path/file name
part = models.CharField(default="", max_length=255)
version = models.CharField(default="", max_length=255) # sort path/file name
language = models.CharField(default="", max_length=8)
season = models.IntegerField(default = -1)
episode = models.IntegerField(default = -1)
size = models.BigIntegerField(default = 0)
duration = models.IntegerField(default = 0)
info = fields.DictField(default={})
video_codec = models.CharField(max_length=255)
pixel_format = models.CharField(max_length=255)
display_aspect_ratio = models.CharField(max_length=255)
width = models.IntegerField(default = 0)
height = models.IntegerField(default = 0)
framerate = models.CharField(max_length=255)
audio_codec = models.CharField(max_length=255)
channels = models.IntegerField(default = 0)
samplerate = models.IntegerField(default = 0)
bits_per_pixel = models.FloatField(default=-1)
pixels = models.BigIntegerField(default=0)
is_audio = models.BooleanField(default = False)
is_video = models.BooleanField(default = False)
is_extra = models.BooleanField(default = False)
is_main = models.BooleanField(default = False)
is_subtitle = models.BooleanField(default = False)
is_version = models.BooleanField(default = False)
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
if self.name and not self.sort_name:
self.sort_name = canonicalTitle(self.name)
if self.info:
for key in ('duration', 'size'):
setattr(self, key, self.info.get(key, 0))
if 'video' in self.info and self.info['video']:
self.video_codec = self.info['video'][0]['codec']
self.width = self.info['video'][0]['width']
self.height = self.info['video'][0]['height']
self.framerate = self.info['video'][0]['framerate']
if 'display_aspect_ratio' in self.info['video'][0]:
self.display_aspect_ratio = self.info['video'][0]['display_aspect_ratio']
else:
self.display_aspect_ratio = "%s:%s" % (self.width, self.height)
self.is_video = True
self.is_audio = False
else:
self.is_video = False
if 'audio' in self.info and self.info['audio']:
self.audio_codec = self.info['audio'][0]['codec']
self.samplerate = self.info['audio'][0]['samplerate']
self.channels = self.info['audio'][0]['channels']
if not self.is_video:
self.is_audio = True
else:
self.is_audio = False
if self.framerate:
self.pixels = int(self.width * self.height * float(parse_decimal(self.framerate)) * self.duration)
if not self.is_audio and not self.is_video and self.name.endswith('.srt'):
self.is_subtitle = True
if self.name and self.name.startswith('Extra/'):
self.is_extra = True
self.is_main = False
else:
self.is_extra = False
self.is_main = True
super(File, self).save(*args, **kwargs)
def json(self):
r = {}
for k in self:
r[k] = unicode(self[k])
return r
class FileInstance(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
published = models.DateTimeField(default=datetime.now, editable=False)
accessed = models.DateTimeField(default=datetime.now, editable=False)
path = models.CharField(max_length=2048)
folder = models.CharField(max_length=255)
file = models.ForeignKey(File, related_name='instances')
archive = models.ForeignKey(Archive, related_name='files')
def __unicode__(self):
return u'%s <%s> in %s'% (self.path, self.oshash, self.archive.name)
@property
def movieId(self):
return File.objects.get(oshash=self.oshash).movieId
class Frame(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
file = models.ForeignKey(File, related_name="frames")
position = models.FloatField()
frame = models.ImageField(default=None, null=True, upload_to=lambda f, x: frame_path(f))
#FIXME: frame path should be renamed on save to match current position
def __unicode__(self):
return '%s at %s' % (self.file, self.position)

23
pandora/archive/tests.py Normal file
View file

@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

164
pandora/archive/views.py Normal file
View file

@ -0,0 +1,164 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
import os.path
import re
from datetime import datetime
from urllib2 import unquote
import mimetypes
from django import forms
from django.core.paginator import Paginator
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.db.models import Q, Avg, Count, Sum
from django.http import HttpResponse, Http404
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from django.template import RequestContext
from django.conf import settings
try:
import simplejson as json
except ImportError:
from django.utils import simplejson as json
from oxdjango.decorators import login_required_json
from oxdjango.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from oxdjango.http import HttpFileResponse
import ox
import models
from backend.utils import oxid, parsePath
import backend.models
#@login_required_json
def api_update(request):
'''
param data
{archive: string, files: json}
return {'status': {'code': int, 'text': string},
'data': {info: object, rename: object}}
'''
data = json.loads(request.POST['data'])
archive = data['archive']
folder = data['folder']
files = data['files']
needs_data = []
rename = []
archive, created = models.Archive.objects.get_or_create(name=archive, user=request.user)
if archive.editable(request.user):
print 'editing'
same_folder = models.FileInstance.objects.filter(folder=folder)
if same_folder.count() > 0:
movie = same_folder[0].file.movie
else:
movie = None
for filename in files:
data = files[filename]
oshash = data['oshash']
path = os.path.join(folder, filename)
instance = models.FileInstance.objects.filter(file__oshash=oshash)
if instance.count()>0:
instance = instance[0]
if path != instance.path: #file was movied
instance.path = path
instance.folder = folder
f.save()
print "file movied, so other shit"
else:
#look if oshash is known
f = models.File.objects.filter(oshash=oshash)
if f.count() > 0:
f = f[0]
instance = models.FileInstance()
instance.file = f
instance.path=data['path']
instance.folder=folder
instance.save()
movie = f.movie
#new oshash, add to database
else:
if not movie:
movie_info = parsePath(folder)
movie = backend.models.getMovie(movie_info)
f = models.File()
f.oshash = oshash
f.info = data
del f.info['oshash']
f.name = filename
f.movie = movie
f.save()
instance = models.FileInstance()
instance.archive = archive
instance.file = f
instance.path = path
instance.folder = folder
instance.save()
response = json_response({'info': needs_data, 'rename': rename})
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
@login_required_json
def api_addArchive(request):
'''
ARCHIVE API NEEDS CLEANUP
param data
{name: string}
return {'status': {'code': int, 'text': string},
'data': {}}
'''
data = json.loads(request.POST['data'])
try:
archive = models.Archive.objects.get(name=data['name'])
response = {'status': {'code': 401, 'text': 'archive with this name exists'}}
except models.Archive.DoesNotExist:
archive = models.Archive(name=data['name'])
archive.user = request.user
archive.save()
archive.users.add(request.user)
response = json_response({})
response['status']['text'] = 'archive created'
return render_to_json_response(response)
@login_required_json
def api_editArchive(request):
'''
ARCHIVE API NEEDS CLEANUP
param data
{id: string, key: value,..}
return {'status': {'code': int, 'text': string},
'data': {}}
'''
data = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Archive, name=data['name'])
if item.editable(request.user):
response = json_response(status=501, text='not implemented')
item.edit(data)
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
@login_required_json
def api_removeArchive(request):
'''
ARCHIVE API NEEDS CLEANUP
param data
string id
return {'status': {'code': int, 'text': string}}
'''
response = json_response({})
itemId = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Archive, movieId=itemId)
if item.editable(request.user):
response = json_response(status=501, text='not implemented')
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)

View file

@ -3,41 +3,27 @@
from django.contrib import admin
from forms import FileAdminForm, MovieAdminForm, ArchiveFileAdminForm
#from forms import FileAdminForm, MovieAdminForm, ArchiveFileAdminForm
import models
'''
#class MovieImdbAdmin(admin.ModelAdmin):
# search_fields = ['imdbId', 'title']
#admin.site.register(models.MovieImdb, MovieImdbAdmin)
class MovieImdbInline(admin.StackedInline):
model = models.MovieImdb
class MovieOxdbInline(admin.StackedInline):
model = models.MovieOxdb
'''
class MovieAdmin(admin.ModelAdmin):
search_fields = ['movieId', 'imdb__title', 'oxdb__title']
form = MovieAdminForm
#form = MovieAdminForm
#inlines = [MovieImdbInline, MovieOxdbInline]
admin.site.register(models.Movie, MovieAdmin)
class FileAdmin(admin.ModelAdmin):
search_fields = ['path', 'video_codec']
form = FileAdminForm
admin.site.register(models.File, FileAdmin)
class ArchiveFileAdmin(admin.ModelAdmin):
search_fields = ['path', 'archive__name']
form = ArchiveFileAdminForm
admin.site.register(models.ArchiveFile, ArchiveFileAdmin)
class ArchiveAdmin(admin.ModelAdmin):
search_fields = ['name']
admin.site.register(models.Archive, ArchiveAdmin)

View file

@ -10,7 +10,7 @@ ajax_filtered_js = (
settings.STATIC_URL + 'js/jquery/jquery.js',
settings.STATIC_URL + 'js/ajax_filtered_fields.js',
)
"""
class FileAdminForm(forms.ModelForm):
movie = ForeignKeyByLetter(models.Movie, field_name='imdb__title')
@ -39,4 +39,4 @@ class MovieAdminForm(forms.ModelForm):
class Media:
js = ajax_filtered_js
"""

View file

@ -46,7 +46,7 @@ class MovieManager(Manager):
query: {
conditions: [
{
value: "war""
value: "war"
}
{
key: "year",
@ -59,10 +59,10 @@ class MovieManager(Manager):
operator: "^"
}
],
operator: "&"
operator: ","
}
'''
query_operator = data['query'].get('operator', '&')
query_operator = data['query'].get('operator', ',')
conditions = []
for condition in data['query']['conditions']:
k = condition.get('key', 'all')

View file

@ -0,0 +1,647 @@
# -*- coding: utf-8 -*-
from south.db import db
from django.db import models
from backend.models import *
class Migration:
def forwards(self, orm):
# Deleting unique_together for [imdb] on movie.
db.delete_unique('backend_movie', ['imdb_id'])
# Adding model 'Facet'
db.create_table('backend_facet', (
('id', orm['backend.facet:id']),
('movie', orm['backend.facet:movie']),
('key', orm['backend.facet:key']),
('value', orm['backend.facet:value']),
('value_sort', orm['backend.facet:value_sort']),
))
db.send_create_signal('backend', ['Facet'])
# Adding field 'Movie.metadata'
db.add_column('backend_movie', 'metadata', orm['backend.movie:metadata'])
# Adding field 'MovieSort.director_desc'
db.add_column('backend_moviesort', 'director_desc', orm['backend.moviesort:director_desc'])
# Adding field 'MovieSort.writer_desc'
db.add_column('backend_moviesort', 'writer_desc', orm['backend.moviesort:writer_desc'])
# Adding field 'MovieSort.country_desc'
db.add_column('backend_moviesort', 'country_desc', orm['backend.moviesort:country_desc'])
# Adding field 'MovieFind.location'
db.add_column('backend_moviefind', 'location', orm['backend.moviefind:location'])
# Adding field 'MovieFind.actor'
db.add_column('backend_moviefind', 'actor', orm['backend.moviefind:actor'])
# Adding field 'MovieSort.producer_desc'
db.add_column('backend_moviesort', 'producer_desc', orm['backend.moviesort:producer_desc'])
# Adding field 'MovieSort.cinematographer_desc'
db.add_column('backend_moviesort', 'cinematographer_desc', orm['backend.moviesort:cinematographer_desc'])
# Adding field 'MovieSort.title_desc'
db.add_column('backend_moviesort', 'title_desc', orm['backend.moviesort:title_desc'])
# Adding field 'MovieSort.language_desc'
db.add_column('backend_moviesort', 'language_desc', orm['backend.moviesort:language_desc'])
# Adding field 'MovieSort.year_desc'
db.add_column('backend_moviesort', 'year_desc', orm['backend.moviesort:year_desc'])
# Adding field 'MovieFind.character'
db.add_column('backend_moviefind', 'character', orm['backend.moviefind:character'])
# Adding field 'MovieSort.editor_desc'
db.add_column('backend_moviesort', 'editor_desc', orm['backend.moviesort:editor_desc'])
# Adding field 'MovieFind.keyword'
db.add_column('backend_moviefind', 'keyword', orm['backend.moviefind:keyword'])
# Deleting field 'Movie.extra'
db.delete_column('backend_movie', 'extra_id')
# Deleting field 'MovieFind.cast'
db.delete_column('backend_moviefind', 'cast')
# Dropping ManyToManyField 'Person.movies'
db.delete_table('backend_person_movies')
# Deleting field 'Movie.oxdb'
db.delete_column('backend_movie', 'oxdb_id')
# Deleting field 'MovieFind.keywords'
db.delete_column('backend_moviefind', 'keywords')
# Deleting field 'MovieFind.locations'
db.delete_column('backend_moviefind', 'locations')
# Deleting model 'movieoxdb'
db.delete_table('backend_movieoxdb')
# Deleting model 'review'
db.delete_table('backend_review')
# Deleting model 'archive'
db.delete_table('backend_archive')
# Deleting model 'alternativetitle'
db.delete_table('backend_alternativetitle')
# Deleting model 'moviecountry'
db.delete_table('backend_moviecountry')
# Deleting model 'trivia'
db.delete_table('backend_trivia')
# Deleting model 'connection'
db.delete_table('backend_connection')
# Deleting model 'cast'
db.delete_table('backend_cast')
# Deleting model 'frame'
db.delete_table('backend_frame')
# Deleting model 'movielanguage'
db.delete_table('backend_movielanguage')
# Deleting model 'file'
db.delete_table('backend_file')
# Deleting model 'movieimdb'
db.delete_table('backend_movieimdb')
# Deleting model 'country'
db.delete_table('backend_country')
# Deleting model 'archivefile'
db.delete_table('backend_archivefile')
# Deleting model 'movieextra'
db.delete_table('backend_movieextra')
# Deleting model 'language'
db.delete_table('backend_language')
# Deleting model 'keyword'
db.delete_table('backend_keyword')
# Deleting model 'genre'
db.delete_table('backend_genre')
# Changing field 'Movie.imdb'
# (to signature: fields.DictField(default={}, editable=False))
db.alter_column('backend_movie', 'imdb', orm['backend.movie:imdb'])
def backwards(self, orm):
# Deleting model 'Facet'
db.delete_table('backend_facet')
# Deleting field 'Movie.metadata'
db.delete_column('backend_movie', 'metadata')
# Deleting field 'MovieSort.director_desc'
db.delete_column('backend_moviesort', 'director_desc')
# Deleting field 'MovieSort.writer_desc'
db.delete_column('backend_moviesort', 'writer_desc')
# Deleting field 'MovieSort.country_desc'
db.delete_column('backend_moviesort', 'country_desc')
# Deleting field 'MovieFind.location'
db.delete_column('backend_moviefind', 'location')
# Deleting field 'MovieFind.actor'
db.delete_column('backend_moviefind', 'actor')
# Deleting field 'MovieSort.producer_desc'
db.delete_column('backend_moviesort', 'producer_desc')
# Deleting field 'MovieSort.cinematographer_desc'
db.delete_column('backend_moviesort', 'cinematographer_desc')
# Deleting field 'MovieSort.title_desc'
db.delete_column('backend_moviesort', 'title_desc')
# Deleting field 'MovieSort.language_desc'
db.delete_column('backend_moviesort', 'language_desc')
# Deleting field 'MovieSort.year_desc'
db.delete_column('backend_moviesort', 'year_desc')
# Deleting field 'MovieFind.character'
db.delete_column('backend_moviefind', 'character')
# Deleting field 'MovieSort.editor_desc'
db.delete_column('backend_moviesort', 'editor_desc')
# Deleting field 'MovieFind.keyword'
db.delete_column('backend_moviefind', 'keyword')
# Adding field 'Movie.extra'
db.add_column('backend_movie', 'extra', orm['backend.movie:extra'])
# Adding field 'MovieFind.cast'
db.add_column('backend_moviefind', 'cast', orm['backend.moviefind:cast'])
# Adding ManyToManyField 'Person.movies'
db.create_table('backend_person_movies', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('person', models.ForeignKey(orm.Person, null=False)),
('movie', models.ForeignKey(orm.movie, null=False))
))
# Adding field 'Movie.oxdb'
db.add_column('backend_movie', 'oxdb', orm['backend.movie:oxdb'])
# Adding field 'MovieFind.keywords'
db.add_column('backend_moviefind', 'keywords', orm['backend.moviefind:keywords'])
# Adding field 'MovieFind.locations'
db.add_column('backend_moviefind', 'locations', orm['backend.moviefind:locations'])
# Adding model 'movieoxdb'
db.create_table('backend_movieoxdb', (
('series_title', orm['backend.moviefind:series_title']),
('gross', orm['backend.moviefind:gross']),
('votes', orm['backend.moviefind:votes']),
('episode', orm['backend.moviefind:episode']),
('created', orm['backend.moviefind:created']),
('profit', orm['backend.moviefind:profit']),
('season', orm['backend.moviefind:season']),
('plot', orm['backend.moviefind:plot']),
('rating', orm['backend.moviefind:rating']),
('year', orm['backend.moviefind:year']),
('budget', orm['backend.moviefind:budget']),
('modified', orm['backend.moviefind:modified']),
('episode_title', orm['backend.moviefind:episode_title']),
('series_imdb', orm['backend.moviefind:series_imdb']),
('tagline', orm['backend.moviefind:tagline']),
('title', orm['backend.moviefind:title']),
('runtime', orm['backend.moviefind:runtime']),
('release_date', orm['backend.moviefind:release_date']),
('id', orm['backend.moviefind:id']),
('plot_outline', orm['backend.moviefind:plot_outline']),
))
db.send_create_signal('backend', ['movieoxdb'])
# Adding model 'review'
db.create_table('backend_review', (
('title', orm['backend.moviefind:title']),
('url', orm['backend.moviefind:url']),
('movie', orm['backend.moviefind:movie']),
('manual', orm['backend.moviefind:manual']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['review'])
# Adding model 'archive'
db.create_table('backend_archive', (
('users', orm['backend.moviefind:users']),
('created', orm['backend.moviefind:created']),
('modified', orm['backend.moviefind:modified']),
('id', orm['backend.moviefind:id']),
('public', orm['backend.moviefind:public']),
('name', orm['backend.moviefind:name']),
))
db.send_create_signal('backend', ['archive'])
# Adding model 'alternativetitle'
db.create_table('backend_alternativetitle', (
('title', orm['backend.moviefind:title']),
('movie', orm['backend.moviefind:movie']),
('manual', orm['backend.moviefind:manual']),
('type', orm['backend.moviefind:type']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['alternativetitle'])
# Adding model 'moviecountry'
db.create_table('backend_moviecountry', (
('country', orm['backend.moviefind:country']),
('manual', orm['backend.moviefind:manual']),
('movie', orm['backend.moviefind:movie']),
('position', orm['backend.moviefind:position']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['moviecountry'])
# Adding model 'trivia'
db.create_table('backend_trivia', (
('movie', orm['backend.moviefind:movie']),
('manual', orm['backend.moviefind:manual']),
('position', orm['backend.moviefind:position']),
('trivia', orm['backend.moviefind:trivia']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['trivia'])
# Adding model 'connection'
db.create_table('backend_connection', (
('object', orm['backend.moviefind:object']),
('manual', orm['backend.moviefind:manual']),
('relation', orm['backend.moviefind:relation']),
('id', orm['backend.moviefind:id']),
('subject', orm['backend.moviefind:subject']),
))
db.send_create_signal('backend', ['connection'])
# Adding model 'cast'
db.create_table('backend_cast', (
('character', orm['backend.moviefind:character']),
('manual', orm['backend.moviefind:manual']),
('person', orm['backend.moviefind:person']),
('role', orm['backend.moviefind:role']),
('movie', orm['backend.moviefind:movie']),
('position', orm['backend.moviefind:position']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['cast'])
# Adding model 'frame'
db.create_table('backend_frame', (
('created', orm['backend.moviefind:created']),
('frame', orm['backend.moviefind:frame']),
('modified', orm['backend.moviefind:modified']),
('file', orm['backend.moviefind:file']),
('position', orm['backend.moviefind:position']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['frame'])
# Adding model 'movielanguage'
db.create_table('backend_movielanguage', (
('language', orm['backend.moviefind:language']),
('movie', orm['backend.moviefind:movie']),
('manual', orm['backend.moviefind:manual']),
('position', orm['backend.moviefind:position']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['movielanguage'])
# Adding model 'file'
db.create_table('backend_file', (
('available', orm['backend.moviefind:available']),
('needs_data', orm['backend.moviefind:needs_data']),
('pixel_aspect_ratio', orm['backend.moviefind:pixel_aspect_ratio']),
('stream_high', orm['backend.moviefind:stream_high']),
('pixel_format', orm['backend.moviefind:pixel_format']),
('oshash', orm['backend.moviefind:oshash']),
('stream_low', orm['backend.moviefind:stream_low']),
('height', orm['backend.moviefind:height']),
('channels', orm['backend.moviefind:channels']),
('part', orm['backend.moviefind:part']),
('display_aspect_ratio', orm['backend.moviefind:display_aspect_ratio']),
('audio_codec', orm['backend.moviefind:audio_codec']),
('duration', orm['backend.moviefind:duration']),
('path', orm['backend.moviefind:path']),
('samplerate', orm['backend.moviefind:samplerate']),
('id', orm['backend.moviefind:id']),
('md5', orm['backend.moviefind:md5']),
('info', orm['backend.moviefind:info']),
('sha1', orm['backend.moviefind:sha1']),
('verified', orm['backend.moviefind:verified']),
('created', orm['backend.moviefind:created']),
('movie', orm['backend.moviefind:movie']),
('framerate', orm['backend.moviefind:framerate']),
('modified', orm['backend.moviefind:modified']),
('pixels', orm['backend.moviefind:pixels']),
('bpp', orm['backend.moviefind:bpp']),
('stream_mid', orm['backend.moviefind:stream_mid']),
('published', orm['backend.moviefind:published']),
('video_codec', orm['backend.moviefind:video_codec']),
('size', orm['backend.moviefind:size']),
('type', orm['backend.moviefind:type']),
('width', orm['backend.moviefind:width']),
))
db.send_create_signal('backend', ['file'])
# Adding model 'movieimdb'
db.create_table('backend_movieimdb', (
('rating', orm['backend.moviefind:rating']),
('modified', orm['backend.moviefind:modified']),
('year', orm['backend.moviefind:year']),
('id', orm['backend.moviefind:id']),
('gross', orm['backend.moviefind:gross']),
('votes', orm['backend.moviefind:votes']),
('title', orm['backend.moviefind:title']),
('profit', orm['backend.moviefind:profit']),
('tagline', orm['backend.moviefind:tagline']),
('season', orm['backend.moviefind:season']),
('plot', orm['backend.moviefind:plot']),
('imdbId', orm['backend.moviefind:imdbId']),
('series_imdb', orm['backend.moviefind:series_imdb']),
('series_title', orm['backend.moviefind:series_title']),
('episode', orm['backend.moviefind:episode']),
('created', orm['backend.moviefind:created']),
('release_date', orm['backend.moviefind:release_date']),
('budget', orm['backend.moviefind:budget']),
('episode_title', orm['backend.moviefind:episode_title']),
('runtime', orm['backend.moviefind:runtime']),
('plot_outline', orm['backend.moviefind:plot_outline']),
))
db.send_create_signal('backend', ['movieimdb'])
# Adding model 'country'
db.create_table('backend_country', (
('movies', orm['backend.moviefind:movies']),
('id', orm['backend.moviefind:id']),
('name', orm['backend.moviefind:name']),
))
db.send_create_signal('backend', ['country'])
# Adding model 'archivefile'
db.create_table('backend_archivefile', (
('created', orm['backend.moviefind:created']),
('modified', orm['backend.moviefind:modified']),
('archive', orm['backend.moviefind:archive']),
('file', orm['backend.moviefind:file']),
('path', orm['backend.moviefind:path']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['archivefile'])
# Adding model 'movieextra'
db.create_table('backend_movieextra', (
('rights_level', orm['backend.moviefind:rights_level']),
('description', orm['backend.moviefind:description']),
('created', orm['backend.moviefind:created']),
('title', orm['backend.moviefind:title']),
('modified', orm['backend.moviefind:modified']),
('contributor', orm['backend.moviefind:contributor']),
('id', orm['backend.moviefind:id']),
))
db.send_create_signal('backend', ['movieextra'])
# Adding model 'language'
db.create_table('backend_language', (
('movies', orm['backend.moviefind:movies']),
('id', orm['backend.moviefind:id']),
('name', orm['backend.moviefind:name']),
))
db.send_create_signal('backend', ['language'])
# Adding model 'keyword'
db.create_table('backend_keyword', (
('movies', orm['backend.moviefind:movies']),
('manual', orm['backend.moviefind:manual']),
('id', orm['backend.moviefind:id']),
('name', orm['backend.moviefind:name']),
))
db.send_create_signal('backend', ['keyword'])
# Adding model 'genre'
db.create_table('backend_genre', (
('movies', orm['backend.moviefind:movies']),
('manual', orm['backend.moviefind:manual']),
('id', orm['backend.moviefind:id']),
('name', orm['backend.moviefind:name']),
))
db.send_create_signal('backend', ['genre'])
# Changing field 'Movie.imdb'
# (to signature: django.db.models.fields.related.OneToOneField(unique=True, null=True, to=orm['backend.MovieImdb']))
db.alter_column('backend_movie', 'imdb', orm['backend.movie:imdb'])
# Creating unique_together for [imdb] on movie.
db.create_unique('backend_movie', ['imdb_id'])
models = {
'auth.group': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'unique_together': "(('content_type', 'codename'),)"},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'backend.collection': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
'subdomain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '2048'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'})
},
'backend.facet': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_index': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'facets'", 'to': "orm['backend.Movie']"}),
'value': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'value_sort': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
'backend.layer': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'time_in': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'time_out': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'value': ('django.db.models.fields.TextField', [], {})
},
'backend.list': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']", 'symmetrical': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'backend.listitem': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.List']"}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"})
},
'backend.location': {
'area': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'lat_center': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lat_ne': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lat_sw': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lng_center': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lng_ne': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lng_sw': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']", 'symmetrical': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.movie': {
'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdb': ('fields.DictField', [], {'default': '{}', 'editable': 'False'}),
'json': ('fields.DictField', [], {'default': '{}', 'editable': 'False'}),
'metadata': ('fields.DictField', [], {'default': '{}', 'editable': 'False'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movieId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}),
'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'scene_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'stream_high': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'stream_low': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}),
'stream_mid': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'})
},
'backend.moviefind': {
'actor': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'all': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'character': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'cinematographer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'country': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'director': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'editor': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'filename': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'keyword': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'language': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'location': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'movie': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'find'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['backend.Movie']"}),
'producer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'trivia': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'writer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.moviesort': {
'aspectratio': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'bitrate': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'cast': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'cinematographer': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'cinematographer_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'connections': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'country': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'country_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'director': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'director_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {'default': '-1', 'db_index': 'True'}),
'editor': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'editor_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'filename': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'files': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'keywords': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'language': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'language_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'movie': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'sort'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['backend.Movie']"}),
'movieId': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'blank': 'True'}),
'pixels': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'producer': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'producer_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'rating': ('django.db.models.fields.FloatField', [], {'db_index': 'True', 'blank': 'True'}),
'resolution': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'risk': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'runtime': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'scenes': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'size': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'summary': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'db_index': 'True'}),
'title_desc': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'db_index': 'True'}),
'trivia': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'votes': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
'words': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'wpm': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
'writer': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'writer_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_index': 'True'}),
'year_desc': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_index': 'True'})
},
'backend.person': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdbId': ('django.db.models.fields.CharField', [], {'max_length': '7', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'name_sort': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
'backend.reviewwhitelist': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
'url': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
},
'contenttypes.contenttype': {
'Meta': {'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
}
}
complete_apps = ['backend']

File diff suppressed because it is too large Load diff

View file

@ -12,16 +12,17 @@ import models
def cronjob(**kwargs):
print "do some cleanup stuff once a day"
@task(ignore_resulsts=True)
def loadIMDb(imdbId):
load.loadIMDb(imdbId)
@task(ignore_resulsts=True, queue='default')
def updateImdb(imdbId):
movie = models.Movie.objects.get(movieId=imdbId)
movie.updateImdb()
@task(ignore_resulsts=True)
def findMovie(fileId):
f = models.File.objects.get(pk=fileId)
f.findMovie()
@task(ignore_resulsts=True, exchange="encoding")
@task(ignore_resulsts=True, queue="encoding")
def extractData(fileId):
'''
update file stuff
@ -30,7 +31,7 @@ def extractData(fileId):
f = models.File.objects.get(pk=fileId)
f.extract()
@task(ignore_resulsts=True, exchange="encoding")
@task(ignore_resulsts=True, queue="encoding")
def updateMovie(movidId):
'''
update movie

View file

@ -12,7 +12,8 @@ import ox
import ox.iso
from ox.normalize import normalizeName
def oxid(title, director, year='', seriesTitle='', episodeTitle='', season=0, episode=0):
def oxid(title, directors, year='', seriesTitle='', episodeTitle='', season=0, episode=0):
director = ', '.join(directors)
oxid_value = u"\n".join([title, director, year])
oxid = hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()
if seriesTitle:
@ -22,15 +23,19 @@ def oxid(title, director, year='', seriesTitle='', episodeTitle='', season=0, ep
oxid += hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()[:20]
return u"0x" + oxid
def oxdb_director(director):
def oxdb_directors(director):
director = os.path.basename(os.path.dirname(director))
if director.endswith('_'):
director = "%s." % director[:-1]
director = ", ".join([normalizeName(d) for d in director.split('; ')])
director = director.replace('Series', '')
director = director.replace('Unknown Director', '')
director = director.replace('Various Directors', '')
return director
directors = [normalizeName(d) for d in director.split('; ')]
def cleanup(director):
director = director.strip()
director = director.replace('Series', '')
director = director.replace('Unknown Director', '')
director = director.replace('Various Directors', '')
return director
directors = filter(None, [cleanup(d) for d in directors])
return directors
def oxdb_title(_title, searchTitle = False):
'''
@ -117,11 +122,15 @@ def parsePath(path):
search_title = oxdb_title(path, True)
r = {}
r['title'] = oxdb_title(path)
r['director'] = oxdb_director(path)
r['directors'] = oxdb_directors(path)
r['episode_title'] = oxdb_episode_title(path)
r['season'], r['episode'] = oxdb_season_episode(path)
r['series'] = oxdb_series_title(path)
r['series_title'] = oxdb_series_title(path)
r['part'] = oxdb_part(path)
r['imdbId'] = ox.web.imdb.guess(search_title, r['director'], timeout=-1)
r['imdbId'] = ox.web.imdb.guess(search_title, ', '.join(r['directors']), timeout=-1)
r['oxdbId'] = oxid(r['title'], r['directors'],
seriesTitle=r['series_title'],
episodeTitle=r['episode_title'],
season=r['season'], episode=r['episode'])
return r

View file

@ -33,8 +33,10 @@ import tasks
from oxuser.models import getUserJSON
from oxuser.views import api_login, api_logout, api_register, api_contact, api_recover, api_preferences
from archive.views import api_update, api_addArchive, api_editArchive, api_removeArchive
from archive.models import File
def api(request):
if request.META['REQUEST_METHOD'] == "OPTIONS":
response = HttpResponse('')
@ -78,10 +80,18 @@ def api_error(request):
def _order_query(qs, sort, prefix='sort__'):
order_by = []
if len(sort) == 1:
if sort[0]['key'] in ('title', 'director'):
sort.append({'operator': '-', 'key': 'year'})
if sort[0]['key'] in ('year', ):
sort.append({'operator': '+', 'key': 'director'})
for e in sort:
operator = e['operator']
if operator != '-': operator = ''
key = {'id': 'movieId'}.get(e['key'], e['key'])
#FIXME: this should be a property of models.MovieSort!!!
if operator=='-' and key in ('title', 'director', 'writer', 'producer', 'editor', 'cinematographer', 'language', 'country', 'year'):
key = '%s_desc' % key
order = '%s%s%s' % (operator, prefix, key)
order_by.append(order)
if order_by:
@ -180,29 +190,23 @@ Positions
query['sort'] = [{'key': 'name', 'operator':'+'}]
#FIXME: also filter lists here
response['data']['items'] = []
name = 'name'
items = 'movies'
movie_qs = query['qs']
if query['group'] == "director":
qs = models.Cast.objects.filter(role='directors').filter(movie__id__in=movie_qs).values('person__name').annotate(movies=Count('person__id')).order_by()
name = 'person__name'
elif query['group'] == "country":
qs = models.Country.objects.filter(movies__id__in=movie_qs).values('name').annotate(movies=Count('id'))
elif query['group'] == "genre":
qs = models.Genre.objects.filter(movies__id__in=movie_qs).values('name').annotate(movies=Count('id'))
elif query['group'] == "language":
qs = models.Language.objects.filter(movies__id__in=movie_qs).values('name').annotate(movies=Count('id'))
elif query['group'] == "year":
if query['group'] == "year":
qs = models.MovieSort.objects.filter(movie__id__in=movie_qs).values('year').annotate(movies=Count('year'))
name='year'
name_sort='year'
else:
qs = models.Facet.objects.filter(key=query['group']).filter(movie__id__in=movie_qs)
qs = qs.values('value').annotate(movies=Count('id')).order_by()
name = 'value'
name_sort = 'value_sort'
#replace normalized items/name sort with actual db value
for i in range(0, len(query['sort'])):
if query['sort'][i]['key'] == 'name':
if query['group'] in ('director', ):
query['sort'][i]['key'] = 'person__name_sort'
else:
query['sort'][i]['key'] = name
if query['sort'][i]['key'] == 'items':
query['sort'][i]['key'] = name_sort
elif query['sort'][i]['key'] == 'items':
query['sort'][i]['key'] = items
qs = _order_query(qs, query['sort'], prefix='')
if 'ids' in query:
@ -235,26 +239,25 @@ Positions
for p in _p:
r[p] = m.get(p, '')
return r
qs = qs[query['range'][0]:query['range'][1]]
response['data']['items'] = [only_p(m['json']) for m in qs.values('json')]
else: # otherwise stats
#movies = models.Movie.objects.filter(available=True)
movies = query['qs']
files = models.File.objects.all().filter(movie__in=movies)
files = File.objects.all().filter(movie__in=movies)
r = files.aggregate(
Count('duration'),
Count('pixels'),
Count('size')
Sum('duration'),
Sum('pixels'),
Sum('size')
)
response['data']['duration'] = r['duration__count']
response['data']['duration'] = r['duration__sum']
response['data']['files'] = files.count()
response['data']['items'] = movies.count()
response['data']['pixels'] = r['pixels__count']
response['data']['pixels'] = r['pixels__sum']
response['data']['runtime'] = movies.aggregate(Sum('sort__runtime'))['sort__runtime__sum']
if response['data']['runtime'] == None:
response['data']['runtime'] = 1337
response['data']['size'] = r['size__count']
response['data']['size'] = r['size__sum']
return render_to_json_response(response)
def api_getItem(request):
@ -401,106 +404,6 @@ def api_removeList(request):
response = json_response(status=501, text='not implemented')
return render_to_json_response(response)
@login_required_json
def api_addArchive(request):
'''
ARCHIVE API NEEDS CLEANUP
param data
{name: string}
return {'status': {'code': int, 'text': string},
'data': {}}
'''
data = json.loads(request.POST['data'])
try:
archive = models.Archive.objects.get(name=data['name'])
response = {'status': {'code': 401, 'text': 'archive with this name exists'}}
except models.Archive.DoesNotExist:
archive = models.Archive(name=data['name'])
archive.save()
archive.users.add(request.user)
response = json_response({})
response['status']['text'] = 'archive created'
return render_to_json_response(response)
@login_required_json
def api_editArchive(request):
'''
ARCHIVE API NEEDS CLEANUP
param data
{id: string, key: value,..}
return {'status': {'code': int, 'text': string},
'data': {}}
'''
data = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Archive, name=data['name'])
if item.editable(request.user):
response = json_response(status=501, text='not implemented')
item.edit(data)
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
@login_required_json
def api_removeArchive(request):
'''
ARCHIVE API NEEDS CLEANUP
param data
string id
return {'status': {'code': int, 'text': string}}
'''
response = json_response({})
itemId = json.loads(request.POST['data'])
item = get_object_or_404_json(models.Archive, movieId=itemId)
if item.editable(request.user):
response = json_response(status=501, text='not implemented')
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
#@login_required_json
def api_update(request):
'''
param data
{archive: string, files: json}
return {'status': {'code': int, 'text': string},
'data': {info: object, rename: object}}
'''
data = json.loads(request.POST['data'])
archive = data['archive']
files = data['files']
archive = get_object_or_404_json(models.Archive, name=archive)
if archive.editable(request.user):
needs_data = []
rename = {}
for oshash in files:
data = files[oshash]
q = models.ArchiveFile.objects.filter(archive=archive, file__oshash=oshash)
if q.count() == 0:
#print "adding file", oshash, data['path']
f = models.ArchiveFile.get_or_create(archive, oshash)
f.update(data)
if not f.file.movie:
task.findMovie(f.file.id)
#FIXME: only add if it was not in File
else:
f = q[0]
if data['path'] != f.path:
f.path = data['path']
f.save()
if f.file.needs_data:
needs_data.append(oshash)
if f.path != f.file.path:
rename[oshash] = f.file.path
#print "processed files for", archive.name
#remove all files not in files.keys() from ArchiveFile
response = json_response({'info': needs_data, 'rename': rename})
else:
response = json_response(status=403, text='permission denied')
return render_to_json_response(response)
def api_encodingSettings(request):
'''
returns Firefogg encoding settings as specified by site

View file

@ -112,6 +112,7 @@ INSTALLED_APPS = (
'app',
'backend',
'archive',
'oxuser',
'torrent',
)