move in preparation for virtualenv setup

This commit is contained in:
j 2009-10-09 16:02:20 +02:00
commit 973b3600af
33 changed files with 0 additions and 0 deletions

0
oxdb/backend/__init__.py Normal file
View file

173
oxdb/backend/load.py Normal file
View file

@ -0,0 +1,173 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import random
import os.path
from django.db import models
from django.contrib.auth.models import User
import oxweb.imdb
from oxlib import stripTags, findRe
import models
def debug(*msgs):
for m in msgs:
print m,
print
'''Import data from imdb into database,
param: impdb id
return: Movie Object, None if failed
'''
def loadIMDb(imdbId):
if len(imdbId) != 7:
debug("IMDb ID not valid")
return None
try:
movie = models.Movie.byImdbId(imdbId)
except models.Movie.DoesNotExist:
#this shound not happen, just in case previous imports failed
try:
imdb = models.MovieImdb.objects.get(imdbId=imdbId)
except models.MovieImdb.DoesNotExist:
imdb = models.MovieImdb()
imdb.imdbId = imdbId
imdb.save()
movie = models.Movie()
movie.imdb = imdb
info = oxweb.imdb.getMovieInfo(imdbId)
for key in ('title',
'tagline',
'year',
'release_date',
'rating',
'votes',
'series_imdb'
'season',
'episode'):
if key in info:
setattr(movie.imdb, key, info[key])
debug(key, info[key])
_info_map = {
'episode title': 'episode_title',
'series title': 'series_title',
}
for key in _info_map.keys():
if key in info:
setattr(movie.imdb, _info_map.get(key, key), info[key])
movie.imdb.plot = oxweb.imdb.getMoviePlot(imdbId)
debug("plot", movie.imdb.plot)
movie.imdb.runtime = oxweb.imdb.getMovieRuntimeSeconds(imdbId)
business = oxweb.imdb.getMovieBusinessSum(imdbId)
for key in ('gross', 'profit', 'budget'):
setattr(movie.imdb, key, business[key])
movie.imdb.save()
movie.oxdbId = "__init__%s" % random.randint(0, 100000)
movie.save()
models.AlternativeTitle.objects.filter(movie=movie, manual=False).delete()
for i in oxweb.imdb.getMovieAKATitles(imdbId):
t = models.AlternativeTitle()
t.movie = movie
t.title = i[0]
t.type = i[1]
t.save()
#FIXME: related tables should be cleaned to not accumulate cruft
#Country
models.MovieCountry.objects.filter(movie=movie, manual=False).delete()
position = 0
if 'country' in info:
for i in info['country']:
debug("add country", i)
country = models.Country.get_or_create(i)
models.MovieCountry.link(movie, country, position)
position += 1
#Language
models.MovieLanguage.objects.filter(movie=movie, manual=False).delete()
position = 0
if 'language' in info:
for i in info['language']:
debug("add language", i)
language = models.Language.get_or_create(i)
models.MovieLanguage.link(movie, language, position)
position += 1
#Location
movie.locations_all.filter(manual=False).delete()
locations = oxweb.imdb.getMovieLocations(imdbId)
for i in locations:
debug("add location", i)
location = models.Location.get_or_create(i)
location.movies.add(movie)
#Genre
movie.genres_all.filter(manual=False).delete()
if 'genre' in info:
for i in info['genre']:
debug("add genre", i)
genre = models.Genre.get_or_create(i)
genre.movies.add(movie)
#Keyword
movie.keywords_all.filter(manual=False).delete()
keywords = oxweb.imdb.getMovieKeywords(imdbId)
for g in keywords:
debug("add keyword", g)
keyword = models.Keyword.get_or_create(g)
keyword.movies.add(movie)
movie.trivia_all.filter(manual=False).delete()
position = 0
trivia = oxweb.imdb.getMovieTrivia(imdbId)
for i in trivia:
debug("add trivia", i)
t = models.Trivia()
t.movie = movie
t.trivia = i
t.position = position
t.save()
position += 1
position = 0
models.Cast.objects.filter(movie=movie).filter(manual=False).delete()
credits = oxweb.imdb.getMovieCredits(imdbId)
for role in credits:
for p in credits[role]:
name = stripTags(p[0])
imdb_id = findRe(p[0], 'nm(\d{7})')
debug("add cast", name)
#FIXME: we could save character information here
character = stripTags(p[1])
person = models.Person.get_or_create(name, imdb_id)
models.Cast.link(movie, person, role, character, position)
position += 1
movie.connections_all.filter(manual=False).delete()
connections = oxweb.imdb.getMovieConnections(imdbId)
for relation in connections:
for otherId in connections[relation]:
try:
object = models.Movie.objects.get(imdb__imdbId=otherId)
debug("add connection", relation, object)
models.Connection.get_or_create(movie, relation, object)
except models.Movie.DoesNotExist:
pass
reviews = oxweb.imdb.getMovieExternalReviews(imdbId)
movie.reviews_all.filter(manual=False).delete()
for r in reviews:
debug("add review", r)
review = models.Review.get_or_create(movie, r)
review.title = reviews[r]
review.save()
movie.oxdbId = movie.oxid()
movie.save()
return movie

152
oxdb/backend/managers.py Normal file
View file

@ -0,0 +1,152 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import re
from datetime import datetime
from urllib2 import unquote
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q, Manager
import models
def keyType(key):
if key in ('released'):
return "date"
if key in ('year', 'cast.length'):
return "int"
if key in ('rating', 'votes'):
return "float"
return "string"
class MovieManager(Manager):
def get_query_set(self):
return super(MovieManager, self).get_query_set()
def find(self, request):
'''
construct query set from q value in request,
also checks for lists.
range and order must be applied later
'''
q = ''
for i in request.META['QUERY_STRING'].split('&'):
if i.startswith('q='):
q = i[2:]
op = ','
if '|' in q:
op = '|'
conditions = []
for e in q.split(op):
e = e.split(':')
if len(e) == 1: e = ['all'] + e
k, v = e
exclude = False
if v.startswith('!'):
v = v[1:]
exclude = True
if keyType(k) == "string":
startswith = v.startswith('^')
endswith = v.endswith('$')
if startswith and endswith:
v = v[1:-1]
k = '%s__iexact' % k
elif startswith:
v = v[1:]
k = '%s__istartswith' % k
elif v.endswith('$'):
v = v[:-1]
k = '%s__iendswith' % k
else:
k = '%s__icontains' % k
k = 'find__%s' % k
v = unquote(v)
if exclude:
conditions.append(~Q(**{k:v}))
else:
conditions.append(Q(**{k:v}))
else:
def parseDate(d):
while len(d) < 3:
d.append(1)
return datetime(*[int(i) for i in d])
#1960-1970
match = re.compile("(-?[\d\.]+?)-(-?[\d\.]+$)").findall(v)
if match:
v1 = match[0][0]
v2 = match[0][1]
if keyType(k) == "date":
v1 = parseDate(v1.split('.'))
v2 = parseDate(v2.split('.'))
if exclude: #!1960-1970
k1 = str('%s__lt' % k)
k2 = str('%s__gte' % k)
conditions.append(Q(**{k1:v1})|Q(**{k2:v2}))
else: #1960-1970
k1 = str('%s__gte' % k)
k2 = str('%s__lt' % k)
conditions.append(Q(**{k1:v1})&Q(**{k2:v2}))
else:
if keyType(k) == "date":
v = parseDate(v.split('.'))
k = str('%s' % k)
if exclude: #!1960
conditions.append(~Q(**{k:v}))
else: #1960
conditions.append(Q(**{k:v}))
#join query with operator
qs = self.get_query_set()
#only include movies that have hard metadata
qs = qs.filter(available=True)
if conditions:
q = conditions[0]
for c in conditions[1:]:
if op == '|':
q = q | c
else:
q = q & c
qs = qs.filter(q)
# filter list, works for own or public lists
l = request.GET.get('l', 'all')
if l != "all":
l = l.split(":")
only_public = True
if not request.user.is_anonymous():
if len(l) == 1: l = [request.user.username] + l
if request.user.username == l[0]:
only_public = False
if len(l) == 2:
lqs = models.List.objects.filter(name=l[1], user__username=l[0])
if only_public:
lqs = qls.filter(public=True)
if lqs.count() == 1:
qs = qs.filter(listitem__list__id=lqs[0].id)
return qs
class FileManager(Manager):
def get_query_set(self):
return super(FileManager, self).get_query_set()
def movie_files(self, movie):
q = self.get_query_set()
return q.filter(is_video=True, movie=movie)
class ArchiveFileManager(Manager):
def get_query_set(self):
return super(ArchiveFileManager, self).get_query_set()
def movie_files(self, movie):
q = self.get_query_set()
return q.filter(file__is_video=True, file__movie=movie)
def by_oshash(self, oshash):
q = self.get_query_set()
q.filter(movie_file__oshash=oshash)
if q.count() == 0:
raise models.ArchiveFile.DoesNotExist("%s matching oshash %s does not exist." %
(models.ArchiveFile._meta.object_name, oshash))
return q[0]

View file

@ -0,0 +1,722 @@
# -*- coding: utf-8 -*-
from south.db import db
from django.db import models
from oxdb.backend.models import *
class Migration:
def forwards(self, orm):
# Adding model 'Trivia'
db.create_table('backend_trivia', (
('id', orm['backend.Trivia:id']),
('trivia', orm['backend.Trivia:trivia']),
('movie', orm['backend.Trivia:movie']),
('position', orm['backend.Trivia:position']),
))
db.send_create_signal('backend', ['Trivia'])
# Adding model 'AlternativeTitle'
db.create_table('backend_alternativetitle', (
('id', orm['backend.AlternativeTitle:id']),
('movie', orm['backend.AlternativeTitle:movie']),
('title', orm['backend.AlternativeTitle:title']),
('type', orm['backend.AlternativeTitle:type']),
))
db.send_create_signal('backend', ['AlternativeTitle'])
# Adding model 'MovieLanguage'
db.create_table('backend_movielanguage', (
('id', orm['backend.MovieLanguage:id']),
('movie', orm['backend.MovieLanguage:movie']),
('language', orm['backend.MovieLanguage:language']),
('position', orm['backend.MovieLanguage:position']),
))
db.send_create_signal('backend', ['MovieLanguage'])
# Adding model 'Movie'
db.create_table('backend_movie', (
('id', orm['backend.Movie:id']),
('created', orm['backend.Movie:created']),
('modified', orm['backend.Movie:modified']),
('accessed', orm['backend.Movie:accessed']),
('movieId', orm['backend.Movie:movieId']),
('imdbId', orm['backend.Movie:imdbId']),
('oxdbId', orm['backend.Movie:oxdbId']),
('title', orm['backend.Movie:title']),
('year', orm['backend.Movie:year']),
('runtime', orm['backend.Movie:runtime']),
('release_date', orm['backend.Movie:release_date']),
('tagline', orm['backend.Movie:tagline']),
('plot', orm['backend.Movie:plot']),
('plot_outline', orm['backend.Movie:plot_outline']),
('rating', orm['backend.Movie:rating']),
('votes', orm['backend.Movie:votes']),
('budget', orm['backend.Movie:budget']),
('gross', orm['backend.Movie:gross']),
('profit', orm['backend.Movie:profit']),
('files_modified', orm['backend.Movie:files_modified']),
('filename', orm['backend.Movie:filename']),
('extracted', orm['backend.Movie:extracted']),
('duration', orm['backend.Movie:duration']),
('rights_level', orm['backend.Movie:rights_level']),
('tpb_id', orm['backend.Movie:tpb_id']),
('kg_id', orm['backend.Movie:kg_id']),
('open_subtitle_id', orm['backend.Movie:open_subtitle_id']),
('wikipedia_url', orm['backend.Movie:wikipedia_url']),
('series_imdb', orm['backend.Movie:series_imdb']),
('series_title', orm['backend.Movie:series_title']),
('episode_title', orm['backend.Movie:episode_title']),
('season', orm['backend.Movie:season']),
('episode', orm['backend.Movie:episode']),
('still_pos', orm['backend.Movie:still_pos']),
('poster', orm['backend.Movie:poster']),
('posters_disabled', orm['backend.Movie:posters_disabled']),
('posters_available', orm['backend.Movie:posters_available']),
('poster_height', orm['backend.Movie:poster_height']),
('poster_width', orm['backend.Movie:poster_width']),
('scene_height', orm['backend.Movie:scene_height']),
))
db.send_create_signal('backend', ['Movie'])
# Adding model 'Archive'
db.create_table('backend_archive', (
('id', orm['backend.Archive:id']),
('created', orm['backend.Archive:created']),
('modified', orm['backend.Archive:modified']),
('name', orm['backend.Archive:name']),
))
db.send_create_signal('backend', ['Archive'])
# Adding model 'ArchiveFile'
db.create_table('backend_archivefile', (
('id', orm['backend.ArchiveFile:id']),
('created', orm['backend.ArchiveFile:created']),
('modified', orm['backend.ArchiveFile:modified']),
('archive', orm['backend.ArchiveFile:archive']),
('movie_file', orm['backend.ArchiveFile:movie_file']),
('path', orm['backend.ArchiveFile:path']),
))
db.send_create_signal('backend', ['ArchiveFile'])
# Adding model 'Language'
db.create_table('backend_language', (
('id', orm['backend.Language:id']),
('name', orm['backend.Language:name']),
))
db.send_create_signal('backend', ['Language'])
# Adding model 'ReviewWhitelist'
db.create_table('backend_reviewwhitelist', (
('id', orm['backend.ReviewWhitelist:id']),
('name', orm['backend.ReviewWhitelist:name']),
('url', orm['backend.ReviewWhitelist:url']),
))
db.send_create_signal('backend', ['ReviewWhitelist'])
# Adding model 'MovieSort'
db.create_table('backend_moviesort', (
('id', orm['backend.MovieSort:id']),
('movie', orm['backend.MovieSort:movie']),
('title', orm['backend.MovieSort:title']),
('director', orm['backend.MovieSort:director']),
('country', orm['backend.MovieSort:country']),
('year', orm['backend.MovieSort:year']),
('producer', orm['backend.MovieSort:producer']),
('writer', orm['backend.MovieSort:writer']),
('editor', orm['backend.MovieSort:editor']),
('cinematographer', orm['backend.MovieSort:cinematographer']),
('language', orm['backend.MovieSort:language']),
('runtime', orm['backend.MovieSort:runtime']),
('keywords', orm['backend.MovieSort:keywords']),
('genre', orm['backend.MovieSort:genre']),
('cast', orm['backend.MovieSort:cast']),
('summary', orm['backend.MovieSort:summary']),
('trivia', orm['backend.MovieSort:trivia']),
('connections', orm['backend.MovieSort:connections']),
('scenes', orm['backend.MovieSort:scenes']),
('words', orm['backend.MovieSort:words']),
('wpm', orm['backend.MovieSort:wpm']),
('risk', orm['backend.MovieSort:risk']),
('movieId', orm['backend.MovieSort:movieId']),
('duration', orm['backend.MovieSort:duration']),
('resolution', orm['backend.MovieSort:resolution']),
('aspectratio', orm['backend.MovieSort:aspectratio']),
('bitrate', orm['backend.MovieSort:bitrate']),
('pixels', orm['backend.MovieSort:pixels']),
('filename', orm['backend.MovieSort:filename']),
('files', orm['backend.MovieSort:files']),
('size', orm['backend.MovieSort:size']),
))
db.send_create_signal('backend', ['MovieSort'])
# Adding model 'File'
db.create_table('backend_file', (
('id', orm['backend.File:id']),
('created', orm['backend.File:created']),
('modified', orm['backend.File:modified']),
('oshash', orm['backend.File:oshash']),
('sha1', orm['backend.File:sha1']),
('md5', orm['backend.File:md5']),
('movie', orm['backend.File:movie']),
('computed_path', orm['backend.File:computed_path']),
('size', orm['backend.File:size']),
('duration', orm['backend.File:duration']),
('video_codec', orm['backend.File:video_codec']),
('pixel_format', orm['backend.File:pixel_format']),
('width', orm['backend.File:width']),
('height', orm['backend.File:height']),
('pixel_aspect_ratio', orm['backend.File:pixel_aspect_ratio']),
('display_aspect_ratio', orm['backend.File:display_aspect_ratio']),
('framerate', orm['backend.File:framerate']),
('audio_codec', orm['backend.File:audio_codec']),
('samplerate', orm['backend.File:samplerate']),
('channels', orm['backend.File:channels']),
('bpp', orm['backend.File:bpp']),
('pixels', orm['backend.File:pixels']),
('part', orm['backend.File:part']),
))
db.send_create_signal('backend', ['File'])
# Adding model 'Country'
db.create_table('backend_country', (
('id', orm['backend.Country:id']),
('name', orm['backend.Country:name']),
))
db.send_create_signal('backend', ['Country'])
# Adding model 'Genre'
db.create_table('backend_genre', (
('id', orm['backend.Genre:id']),
('name', orm['backend.Genre:name']),
))
db.send_create_signal('backend', ['Genre'])
# Adding model 'MovieCountry'
db.create_table('backend_moviecountry', (
('id', orm['backend.MovieCountry:id']),
('movie', orm['backend.MovieCountry:movie']),
('country', orm['backend.MovieCountry:country']),
('position', orm['backend.MovieCountry:position']),
))
db.send_create_signal('backend', ['MovieCountry'])
# Adding model 'Review'
db.create_table('backend_review', (
('id', orm['backend.Review:id']),
('movie', orm['backend.Review:movie']),
('title', orm['backend.Review:title']),
('url', orm['backend.Review:url']),
))
db.send_create_signal('backend', ['Review'])
# Adding model 'Subtitle'
db.create_table('backend_subtitle', (
('id', orm['backend.Subtitle:id']),
('created', orm['backend.Subtitle:created']),
('modified', orm['backend.Subtitle:modified']),
('user', orm['backend.Subtitle:user']),
('movie_file', orm['backend.Subtitle:movie_file']),
('language', orm['backend.Subtitle:language']),
('srt', orm['backend.Subtitle:srt']),
))
db.send_create_signal('backend', ['Subtitle'])
# Adding model 'Cast'
db.create_table('backend_cast', (
('id', orm['backend.Cast:id']),
('movie', orm['backend.Cast:movie']),
('person', orm['backend.Cast:person']),
('role', orm['backend.Cast:role']),
('character', orm['backend.Cast:character']),
('position', orm['backend.Cast:position']),
))
db.send_create_signal('backend', ['Cast'])
# Adding model 'Person'
db.create_table('backend_person', (
('id', orm['backend.Person:id']),
('name', orm['backend.Person:name']),
('imdbId', orm['backend.Person:imdbId']),
('name_sort', orm['backend.Person:name_sort']),
))
db.send_create_signal('backend', ['Person'])
# Adding model 'Keyword'
db.create_table('backend_keyword', (
('id', orm['backend.Keyword:id']),
('name', orm['backend.Keyword:name']),
))
db.send_create_signal('backend', ['Keyword'])
# Adding model 'List'
db.create_table('backend_list', (
('id', orm['backend.List:id']),
('created', orm['backend.List:created']),
('modified', orm['backend.List:modified']),
('user', orm['backend.List:user']),
('name', orm['backend.List:name']),
('public', orm['backend.List:public']),
))
db.send_create_signal('backend', ['List'])
# Adding model 'Connection'
db.create_table('backend_connection', (
('id', orm['backend.Connection:id']),
('subject', orm['backend.Connection:subject']),
('relation', orm['backend.Connection:relation']),
('object', orm['backend.Connection:object']),
))
db.send_create_signal('backend', ['Connection'])
# Adding model 'Location'
db.create_table('backend_location', (
('id', orm['backend.Location:id']),
('name', orm['backend.Location:name']),
('lat_sw', orm['backend.Location:lat_sw']),
('lng_sw', orm['backend.Location:lng_sw']),
('lat_ne', orm['backend.Location:lat_ne']),
('lng_ne', orm['backend.Location:lng_ne']),
('lat_center', orm['backend.Location:lat_center']),
('lng_center', orm['backend.Location:lng_center']),
('area', orm['backend.Location:area']),
))
db.send_create_signal('backend', ['Location'])
# Adding model 'MovieFind'
db.create_table('backend_moviefind', (
('id', orm['backend.MovieFind:id']),
('movie', orm['backend.MovieFind:movie']),
('all', orm['backend.MovieFind:all']),
('title', orm['backend.MovieFind:title']),
('director', orm['backend.MovieFind:director']),
('country', orm['backend.MovieFind:country']),
('year', orm['backend.MovieFind:year']),
('language', orm['backend.MovieFind:language']),
('writer', orm['backend.MovieFind:writer']),
('producer', orm['backend.MovieFind:producer']),
('editor', orm['backend.MovieFind:editor']),
('cinematographer', orm['backend.MovieFind:cinematographer']),
('cast', orm['backend.MovieFind:cast']),
('genre', orm['backend.MovieFind:genre']),
('keywords', orm['backend.MovieFind:keywords']),
('summary', orm['backend.MovieFind:summary']),
('trivia', orm['backend.MovieFind:trivia']),
('locations', orm['backend.MovieFind:locations']),
('filename', orm['backend.MovieFind:filename']),
))
db.send_create_signal('backend', ['MovieFind'])
# Adding model 'ListItem'
db.create_table('backend_listitem', (
('id', orm['backend.ListItem:id']),
('created', orm['backend.ListItem:created']),
('modified', orm['backend.ListItem:modified']),
('list', orm['backend.ListItem:list']),
('movie', orm['backend.ListItem:movie']),
))
db.send_create_signal('backend', ['ListItem'])
# Adding ManyToManyField 'Location.movies'
db.create_table('backend_location_movies', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('location', models.ForeignKey(orm.Location, null=False)),
('movie', models.ForeignKey(orm.Movie, null=False))
))
# Adding ManyToManyField 'Archive.users'
db.create_table('backend_archive_users', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('archive', models.ForeignKey(orm.Archive, null=False)),
('user', models.ForeignKey(orm['auth.User'], null=False))
))
# Adding ManyToManyField 'Keyword.movies'
db.create_table('backend_keyword_movies', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('keyword', models.ForeignKey(orm.Keyword, null=False)),
('movie', models.ForeignKey(orm.Movie, null=False))
))
# Adding ManyToManyField 'Genre.movies'
db.create_table('backend_genre_movies', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('genre', models.ForeignKey(orm.Genre, null=False)),
('movie', models.ForeignKey(orm.Movie, null=False))
))
def backwards(self, orm):
# Deleting model 'Trivia'
db.delete_table('backend_trivia')
# Deleting model 'AlternativeTitle'
db.delete_table('backend_alternativetitle')
# Deleting model 'MovieLanguage'
db.delete_table('backend_movielanguage')
# Deleting model 'Movie'
db.delete_table('backend_movie')
# Deleting model 'Archive'
db.delete_table('backend_archive')
# Deleting model 'ArchiveFile'
db.delete_table('backend_archivefile')
# Deleting model 'Language'
db.delete_table('backend_language')
# Deleting model 'ReviewWhitelist'
db.delete_table('backend_reviewwhitelist')
# Deleting model 'MovieSort'
db.delete_table('backend_moviesort')
# Deleting model 'File'
db.delete_table('backend_file')
# Deleting model 'Country'
db.delete_table('backend_country')
# Deleting model 'Genre'
db.delete_table('backend_genre')
# Deleting model 'MovieCountry'
db.delete_table('backend_moviecountry')
# Deleting model 'Review'
db.delete_table('backend_review')
# Deleting model 'Subtitle'
db.delete_table('backend_subtitle')
# Deleting model 'Cast'
db.delete_table('backend_cast')
# Deleting model 'Person'
db.delete_table('backend_person')
# Deleting model 'Keyword'
db.delete_table('backend_keyword')
# Deleting model 'List'
db.delete_table('backend_list')
# Deleting model 'Connection'
db.delete_table('backend_connection')
# Deleting model 'Location'
db.delete_table('backend_location')
# Deleting model 'MovieFind'
db.delete_table('backend_moviefind')
# Deleting model 'ListItem'
db.delete_table('backend_listitem')
# Dropping ManyToManyField 'Location.movies'
db.delete_table('backend_location_movies')
# Dropping ManyToManyField 'Archive.users'
db.delete_table('backend_archive_users')
# Dropping ManyToManyField 'Keyword.movies'
db.delete_table('backend_keyword_movies')
# Dropping ManyToManyField 'Genre.movies'
db.delete_table('backend_genre_movies')
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']", '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']", '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']", 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'backend.alternativetitle': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'alternative_titles'", 'to': "orm['backend.Movie']"}),
'title': ('django.db.models.fields.TextField', [], {}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
},
'backend.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', [], {'unique': 'True', 'max_length': '255'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']"})
},
'backend.archivefile': {
'archive': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.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'}),
'movie_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.File']"}),
'path': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'})
},
'backend.cast': {
'character': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Person']"}),
'position': ('django.db.models.fields.IntegerField', [], {}),
'role': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
'backend.connection': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'object': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'relation': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
'subject': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'connections'", 'to': "orm['backend.Movie']"})
},
'backend.country': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.file': {
'audio_codec': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'bpp': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'channels': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'computed_path': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'display_aspect_ratio': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'framerate': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'height': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'md5': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'files'", 'to': "orm['backend.Movie']"}),
'oshash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '16', 'blank': 'True'}),
'part': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'pixel_aspect_ratio': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'pixel_format': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'pixels': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'samplerate': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'sha1': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'blank': 'True'}),
'size': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'video_codec': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'width': ('django.db.models.fields.IntegerField', [], {'default': '-1'})
},
'backend.genre': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.keyword': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.language': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'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']"}),
'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'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.movie': {
'accessed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'budget': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'episode_title': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'extracted': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'filename': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'files_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'gross': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '7', 'blank': 'True'}),
'kg_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movieId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
'open_subtitle_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}),
'plot': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'plot_outline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'poster': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'poster_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'poster_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'posters_available': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'posters_disabled': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'profit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rating': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'release_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'rights_level': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'runtime': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'scene_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'series_imdb': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '7'}),
'series_title': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'still_pos': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'tagline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'tpb_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'votes': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'wikipedia_url': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.moviecountry': {
'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Country']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {})
},
'backend.moviefind': {
'all': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'cast': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'cinematographer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'country': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'director': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'editor': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'filename': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'language': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'locations': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'find'", 'unique': 'True', 'to': "orm['backend.Movie']"}),
'producer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'trivia': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'writer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.movielanguage': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Language']"}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {})
},
'backend.moviesort': {
'aspectratio': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'bitrate': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'cast': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'cinematographer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'connections': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'country': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'director': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'editor': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'filename': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'files': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'keywords': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'language': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sort'", 'unique': 'True', 'to': "orm['backend.Movie']"}),
'movieId': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'pixels': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'producer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'resolution': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'risk': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'runtime': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'scenes': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'size': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'summary': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'trivia': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'words': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'wpm': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'writer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.person': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdbId': ('django.db.models.fields.CharField', [], {'max_length': '7', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'name_sort': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
'backend.review': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reviews'", 'to': "orm['backend.Movie']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'})
},
'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'})
},
'backend.subtitle': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movie_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.File']"}),
'srt': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'backend.trivia': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'trivia'", 'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {}),
'trivia': ('django.db.models.fields.TextField', [], {})
},
'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']

View file

@ -0,0 +1,349 @@
# -*- coding: utf-8 -*-
from south.db import db
from django.db import models
from oxdb.backend.models import *
class Migration:
def forwards(self, orm):
# Adding field 'Movie.available'
db.add_column('backend_movie', 'available', orm['backend.movie:available'])
# Deleting field 'Movie.filename'
db.delete_column('backend_movie', 'filename')
# Deleting field 'Movie.extracted'
db.delete_column('backend_movie', 'extracted')
# Deleting field 'Movie.files_modified'
db.delete_column('backend_movie', 'files_modified')
# Deleting model 'file'
db.delete_table('backend_file')
# Deleting model 'archivefile'
db.delete_table('backend_archivefile')
# Deleting model 'subtitle'
db.delete_table('backend_subtitle')
# Deleting model 'archive'
db.delete_table('backend_archive')
def backwards(self, orm):
# Deleting field 'Movie.available'
db.delete_column('backend_movie', 'available')
# Adding field 'Movie.filename'
db.add_column('backend_movie', 'filename', orm['backend.movie:filename'])
# Adding field 'Movie.extracted'
db.add_column('backend_movie', 'extracted', orm['backend.movie:extracted'])
# Adding field 'Movie.files_modified'
db.add_column('backend_movie', 'files_modified', orm['backend.movie:files_modified'])
# Adding model 'file'
db.create_table('backend_file', (
('computed_path', orm['backend.movie:computed_path']),
('pixel_format', orm['backend.movie:pixel_format']),
('height', orm['backend.movie:height']),
('channels', orm['backend.movie:channels']),
('audio_codec', orm['backend.movie:audio_codec']),
('duration', orm['backend.movie:duration']),
('samplerate', orm['backend.movie:samplerate']),
('id', orm['backend.movie:id']),
('size', orm['backend.movie:size']),
('width', orm['backend.movie:width']),
('movie', orm['backend.movie:movie']),
('pixel_aspect_ratio', orm['backend.movie:pixel_aspect_ratio']),
('oshash', orm['backend.movie:oshash']),
('part', orm['backend.movie:part']),
('display_aspect_ratio', orm['backend.movie:display_aspect_ratio']),
('pixels', orm['backend.movie:pixels']),
('md5', orm['backend.movie:md5']),
('sha1', orm['backend.movie:sha1']),
('created', orm['backend.movie:created']),
('framerate', orm['backend.movie:framerate']),
('modified', orm['backend.movie:modified']),
('bpp', orm['backend.movie:bpp']),
('video_codec', orm['backend.movie:video_codec']),
))
db.send_create_signal('backend', ['file'])
# Adding model 'archivefile'
db.create_table('backend_archivefile', (
('created', orm['backend.movie:created']),
('modified', orm['backend.movie:modified']),
('archive', orm['backend.movie:archive']),
('movie_file', orm['backend.movie:movie_file']),
('path', orm['backend.movie:path']),
('id', orm['backend.movie:id']),
))
db.send_create_signal('backend', ['archivefile'])
# Adding model 'subtitle'
db.create_table('backend_subtitle', (
('language', orm['backend.movie:language']),
('created', orm['backend.movie:created']),
('modified', orm['backend.movie:modified']),
('user', orm['backend.movie:user']),
('srt', orm['backend.movie:srt']),
('movie_file', orm['backend.movie:movie_file']),
('id', orm['backend.movie:id']),
))
db.send_create_signal('backend', ['subtitle'])
# Adding model 'archive'
db.create_table('backend_archive', (
('name', orm['backend.movie:name']),
('created', orm['backend.movie:created']),
('modified', orm['backend.movie:modified']),
('id', orm['backend.movie:id']),
('users', orm['backend.movie:users']),
))
db.send_create_signal('backend', ['archive'])
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']", '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']", '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']", 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'backend.alternativetitle': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'alternative_titles'", 'to': "orm['backend.Movie']"}),
'title': ('django.db.models.fields.TextField', [], {}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
},
'backend.cast': {
'character': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'person': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Person']"}),
'position': ('django.db.models.fields.IntegerField', [], {}),
'role': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
'backend.connection': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'object': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'relation': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
'subject': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'connections'", 'to': "orm['backend.Movie']"})
},
'backend.country': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.genre': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.keyword': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.language': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'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']"}),
'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'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.movie': {
'accessed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'budget': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'episode_title': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'gross': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '7', 'blank': 'True'}),
'kg_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'movieId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}),
'open_subtitle_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}),
'plot': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'plot_outline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'poster': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'poster_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'poster_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'posters_available': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'posters_disabled': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'profit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'rating': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'release_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
'rights_level': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'runtime': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'scene_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
'series_imdb': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '7'}),
'series_title': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'still_pos': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'tagline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'tpb_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'votes': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'wikipedia_url': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.moviecountry': {
'country': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Country']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {})
},
'backend.moviefind': {
'all': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'cast': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'cinematographer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'country': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'director': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'editor': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'filename': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'language': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'locations': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'find'", 'unique': 'True', 'to': "orm['backend.Movie']"}),
'producer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'trivia': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'writer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.movielanguage': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Language']"}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {})
},
'backend.moviesort': {
'aspectratio': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'bitrate': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'cast': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'cinematographer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'connections': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'country': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'director': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'duration': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
'editor': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'filename': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'files': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'keywords': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'language': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sort'", 'unique': 'True', 'to': "orm['backend.Movie']"}),
'movieId': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'pixels': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'producer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'resolution': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'risk': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'runtime': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'scenes': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'size': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'summary': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
'trivia': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'words': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'wpm': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'writer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
},
'backend.person': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'imdbId': ('django.db.models.fields.CharField', [], {'max_length': '7', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'name_sort': ('django.db.models.fields.CharField', [], {'max_length': '200'})
},
'backend.review': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reviews'", 'to': "orm['backend.Movie']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}),
'url': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'})
},
'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'})
},
'backend.trivia': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'trivia'", 'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {}),
'trivia': ('django.db.models.fields.TextField', [], {})
},
'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']

View file

998
oxdb/backend/models.py Normal file
View file

@ -0,0 +1,998 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import re
import os.path
import random
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
import oxlib
from oxlib import stripTags
from oxlib.normalize import canonicalTitle, canonicalName
import utils
import managers
class MovieImdb(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
imdbId = models.CharField(max_length=7, unique=True)
title = models.CharField(max_length=1000)
year = models.CharField(max_length=4)
runtime = models.IntegerField(null=True, blank=True)
release_date = models.DateField(null=True, blank=True)
tagline = models.TextField(blank=True)
plot = models.TextField(blank=True)
plot_outline = models.TextField(blank=True)
rating = models.FloatField(null=True, blank=True)
votes = models.IntegerField(null=True, blank=True)
budget = models.IntegerField(null=True, blank=True)
gross = models.IntegerField(null=True, blank=True)
profit = models.IntegerField(null=True, blank=True)
series_imdb = models.CharField(max_length=7, default='')
series_title = models.TextField(blank=True, default='')
episode_title = models.TextField(blank=True, default='')
season = models.IntegerField(default=-1)
episode = models.IntegerField(default=-1)
class MovieOxdb(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
title = models.CharField(max_length=1000)
year = models.CharField(max_length=4)
runtime = models.IntegerField(null=True, blank=True)
release_date = models.DateField(null=True, blank=True)
tagline = models.TextField(blank=True)
plot = models.TextField(blank=True)
plot_outline = models.TextField(blank=True)
rating = models.FloatField(null=True, blank=True)
votes = models.IntegerField(null=True, blank=True)
budget = models.IntegerField(null=True, blank=True)
gross = models.IntegerField(null=True, blank=True)
profit = models.IntegerField(null=True, blank=True)
series_imdb = models.CharField(max_length=7, default='')
series_title = models.TextField(blank=True, default='')
episode_title = models.TextField(blank=True, default='')
season = models.IntegerField(default=-1)
episode = models.IntegerField(default=-1)
def newMovie(title, director, year):
movie = Movie()
oxdb = MovieOxdb()
oxdb.save()
movie.oxdb = oxdb
movie.oxdb.title = title
movie.oxdb.year = str(year)
movie.oxdb.save()
movie.oxdbId = "__init__%s" % random.randint(0, 100000)
movie.save()
movie.oxdbId = movie.oxid()
movie.save()
return movie
class Movie(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
#only movies that have metadata from files are available,
#this is indicated by setting available to True
available = models.BooleanField(default=False)
movieId = models.CharField(max_length=128, unique=True, blank=True)
oxdbId = models.CharField(max_length=42, unique=True, blank=True)
imdb = models.OneToOneField('MovieImdb', null=True, related_name='movie')
oxdb = models.OneToOneField('MovieOxdb', null=True, related_name='movie')
objects = managers.MovieManager()
def get(self, key, default=None):
if self.oxdb and getattr(self.oxdb, key):
return getattr(self.oxdb, key)
if self.imdb:
return getattr(self.imdb, key)
return default
def _manual(self, qs, f='manual'):
if qs.filter(**{f:True}).count() > 0:
return qs.exclude(**{f:False})
return qs.exclude(**{f:True})
def directors(self):
qs = self.people.filter(cast__role='directors').order_by('cast__position')
return self._manual(qs, 'cast__manual')
def writers(self):
qs = self.people.filter(cast__role='writers').order_by('cast__position')
return self._manual(qs, 'cast__manual')
def editors(self):
qs = self.people.filter(cast__role='editors').order_by('cast__position')
return self._manual(qs, 'cast__manual')
def producers(self):
qs = self.people.filter(cast__role='producers').order_by('cast__position')
return self._manual(qs, 'cast__manual')
def cinematographers(self):
qs = self.people.filter(cast__role='cinematographers').order_by('cast__position')
return self._manual(qs, 'cast__manual')
def cast(self):
cast = []
qs = Cast.objects.filter(movie=self, role='cast').order_by('position')
qs = self._manual(qs)
for c in qs:
cast.append((c.person.name, c.character))
return tuple(cast)
def alternative_titles(self):
return self._manual(self.alternative_titles_all)
def genres(self):
return self._manual(self.genres_all)
def keywords(self):
return self._manual(self.keywords_all)
def countries(self):
return self._manual(self.countries_all, 'moviecountry__manual')
def languages(self):
return self._manual(self.languages_all, 'movielanguage__manual')
def trivia(self):
return self._manual(self.trivia_all)
def locations(self):
return self._manual(self.locations_all)
def connections(self):
return self._manual(self.connections_all)
def connections_json(self):
connections = {}
for connection in self.connections():
if connection.relation not in connections:
connections[connection.relation] = []
connections[connection.relation].append(connection.object.movieId)
return connections
def reviews(self):
q = self.reviews_all.filter(manual=True)
if q.count() > 0:
return q
whitelist = ReviewWhitelist.objects.all()
q = Q(id=-1)
for w in whitelist:
q = q | Q(url__contains=w.url)
return self.reviews_all.filter(q).filter(manual=False)
rights_level = models.IntegerField(default=-1)
#FIXME: use data.0xdb.org
tpb_id = models.CharField(max_length=128, blank=True)
kg_id = models.CharField(max_length=128, blank=True)
open_subtitle_id = models.IntegerField(null=True, blank=True)
wikipedia_url = models.TextField(blank=True)
#what of this is still required?
still_pos = models.IntegerField(null=True, blank=True)
poster = models.TextField(blank=True)
posters_disabled = models.TextField(blank=True)
posters_available = models.TextField(blank=True)
poster_height = models.IntegerField(null=True, blank=True)
poster_width = models.IntegerField(null=True, blank=True)
scene_height = models.IntegerField(null=True, blank=True)
def __unicode__(self):
return u'%s (%s)' % (self.get('title'), self.get('year'))
def save(self, *args, **kwargs):
if not self.oxdb:
oxdb = MovieOxdb()
oxdb.save()
self.oxdb = oxdb
if self.imdb:
mid = self.imdb.imdbId
else:
mid = self.oxdbId
self.movieId = mid
super(Movie, self).save(*args, **kwargs)
self.updateFind()
self.updateSort()
_public_fields = {
'movieId': 'id',
'title': 'title',
'year': 'year',
'runtime': 'runtime',
'release_date': 'release_date',
'countries': 'country',
'directors': 'director',
'languages': 'language',
'genres': 'genre',
'keywords': 'keyword',
'cast': 'cast',
'series_title': 'series_title',
'episode_title': 'episode_title',
'season': 'season',
'episode': 'episode',
'reviews': 'reviews',
'trivia': 'trivia',
'rating': 'rating',
'votes': 'votes',
'alternative_titles': 'alternative_titles',
'connections_json': 'connections'
}
def json(self, fields=None):
movie = {}
for key in self._public_fields:
pub_key = self._public_fields.get(key, key)
if not fields or pub_key in fields:
if hasattr(self, key):
value = getattr(self, key)
else:
value = self.get(key)
if key in ('directors', 'writers', 'reviews',
'countries', 'languages', 'keywords', 'genres', 'trivia', 'alternative_titles'):
movie[pub_key] = tuple([v.json() for v in value()])
elif callable(value):
movie[pub_key] = value()
else:
movie[pub_key] = value
if fields:
for f in fields:
if f.endswith('.length') and f[:-7] in ('cast', 'genre', 'trivia'):
movie[f] = getattr(self.sort.all()[0], f[:-7])
return movie
def fields(self):
fields = {}
for f in self._meta.fields:
if f.name in self._public_fields:
fields[f.name] = {}
fields[f.name]['order'] = 'desc'
fields[f.name]['type'] = type(f)
return fields
fields = classmethod(fields)
#Class functions to get Movies by ID, right now movieId, imdbId and oxdbId
#FIXME: this should go into a manager
def byMovieId(self, movieId):
if len(movieId) == 7:
return self.byImdbId(movieId)
return self.byOxdbId(movieId)
byMovieId = classmethod(byMovieId)
def byImdbId(self, imdbId):
return self.objects.get(imdb__imdbId=imdbId)
byImdbId = classmethod(byImdbId)
def byOxdbId(self, oxdbId):
return self.objects.get(oxdbId=oxdbId)
byOxdbId = classmethod(byOxdbId)
def oxid(self):
directors = ','.join([d.name for d in self.directors()])
return utils.oxid(self.get('title', ''), directors, self.get('year', ''),
self.get('series_title', ''), self.get('episode_title', ''),
self.get('season', ''), self.get('episode', ''))
def updateFind(self):
try:
f = self.find
except MovieFind.DoesNotExist:
f = MovieFind(movie=self)
f.title = self.get('title') + ' '.join([t.title for t in self.alternative_titles()])
f.director = ' '.join([i.name for i in self.directors()])
f.country = ' '.join([i.name for i in self.countries()])
f.year = self.get('year', '')
f.language = ' '.join([i.name for i in self.languages()])
f.writer = ' '.join([i.name for i in self.writers()])
f.producer = ' '.join([i.name for i in self.producers()])
f.editor = ' '.join([i.name for i in self.editors()])
f.cinematographer = ' '.join([i.name for i in self.cinematographers()])
f.cast = ' '.join(['%s %s' % i for i in self.cast()])
f.genre = ' '.join([i.name for i in self.genres()])
f.keywords = ' '.join([i.name for i in self.keywords()])
f.summary = self.get('plot', '') + self.get('plot_outline', '')
f.trivia = ' '.join([i.trivia for i in self.trivia()])
f.location = ' '.join([i.name for i in self.locations()])
#FIXME: collate filenames
#f.filename = self.filename
f.all = ' '.join(filter(None, [f.title, f.director, f.country, f.year, f.language,
f.writer, f.producer, f.editor, f.cinematographer,
f.cast, f.genre, f.keywords, f.summary, f.trivia,
f.location, f.filename]))
f.save()
def updateSort(self):
try:
s = self.sort
except MovieSort.DoesNotExist:
s = MovieSort(movie=self)
def sortName(value):
sort_value = '~'
if value:
sort_value = stripTags(value).split(',')
sort_value = '; '.join([canonicalName(name.strip()) for name in sort_value])
sort_value = sort_value.replace(u'\xc5k', 'A')
if not sort_value:
sort_value = '~'
return sort_value
#title
title = canonicalTitle(self.get('title'))
title = re.sub(u'[\'!¿¡,\.;\-"\:\*\[\]]', '', title)
title = title.replace(u'Æ', 'Ae')
#pad numbered titles
numbers = re.compile('^(\d+)').findall(title)
if numbers:
padded = '%010d' % int(numbers[0])
title = re.sub('^(\d+)', padded, title)
s.title = title.strip()
directors = ','.join([i.name for i in self.directors()])
s.director = sortName(directors)
s.country = ','.join([i.name for i in self.countries()])
s.year = self.get('year', '')
names = ','.join([i.name for i in self.producers()])
s.producer = sortName(names)
names = ','.join([i.name for i in self.writers()])
s.writer = sortName(names)
names = ','.join([i.name for i in self.editors()])
s.editor = sortName(names)
names = ','.join([i.name for i in self.cinematographers()])
s.cinematographer = sortName(names)
s.language = ','.join([i.name for i in self.languages()])
s.country = ','.join([i.name for i in self.countries()])
s.runtime = self.get('runtime', 0)
s.keywords = self.keywords().count()
s.genre = self.genres().count()
s.cast = len(self.cast())
s.summary = len(self.get('plot', '').split())
s.trivia = self.trivia().count()
s.connections = self.connections().count()
s.movieId = self.movieId
s.rating = self.get('rating', -1)
s.votes = self.get('votes', -1)
# data from related subtitles
s.scenes = 0 #FIXME
s.words = 0 #FIXME
s.wpm = 0 #FIXME
s.risk = 0 #FIXME
# data from related files
s.duration = 0 #FIXME
s.resolution = 0 #FIXME
s.aspectratio = 0 #FIXME
s.bitrate = 0 #FIXME
s.pixels = 0 #FIXME
s.filename = 0 #FIXME
s.files = 0 #FIXME
s.size = 0 #FIXME
s.save()
class MovieFind(models.Model):
"""
used to search movies, all search values are in here
"""
movie = models.OneToOneField('Movie', related_name='find', primary_key=True)
all = models.TextField(blank=True)
title = models.CharField(max_length=1000)
director = models.TextField(blank=True, default='')
country = models.TextField(blank=True, default='')
year = models.CharField(max_length=4)
language = models.TextField(blank=True, default='')
writer = models.TextField(blank=True, default='')
producer = models.TextField(blank=True, default='')
editor = models.TextField(blank=True, default='')
cinematographer = models.TextField(blank=True, default='')
cast = models.TextField(blank=True, default='')
#person
genre = models.TextField(blank=True)
keywords = models.TextField(blank=True)
summary = models.TextField(blank=True)
trivia = models.TextField(blank=True)
locations = models.TextField(blank=True, default='')
#only for own files or as admin?
filename = models.TextField(blank=True, default='')
_private_fields = ('id', 'movie')
_public_names = {
'movieId': 'id'
}
def options(self):
options = []
for f in self._meta.fields:
if f.name not in self._private_fields:
name = f.name
name = self._public_names.get(name, name)
options.append((name, 'Find: %s' % name.capitalize()))
return tuple(options)
options = classmethod(options)
class MovieSort(models.Model):
"""
used to sort movies, all sort values are in here
"""
movie = models.OneToOneField('Movie', related_name='sort', primary_key=True)
title = models.CharField(max_length=1000)
director = models.TextField(blank=True)
country = models.TextField(blank=True)
year = models.CharField(max_length=4)
producer = models.TextField(blank=True)
writer = models.TextField(blank=True)
editor = models.TextField(blank=True)
cinematographer = models.TextField(blank=True)
language = models.TextField(blank=True)
runtime = models.IntegerField(blank=True, null=True)
keywords = models.IntegerField(blank=True)
genre = models.TextField(blank=True)
cast = models.IntegerField(blank=True)
summary = models.IntegerField(blank=True)
trivia = models.IntegerField(blank=True)
connections = models.IntegerField(blank=True)
rating = models.FloatField(blank=True)
votes = models.IntegerField(blank=True)
scenes = models.IntegerField(blank=True)
words = models.IntegerField(null=True, blank=True)
wpm = models.IntegerField(null=True, blank=True)
risk = models.IntegerField(null=True, blank=True)
movieId = models.CharField(max_length=128, blank=True)
duration = models.FloatField(default=-1)
resolution = models.IntegerField(blank=True)
aspectratio = models.IntegerField(blank=True)
bitrate = models.IntegerField(blank=True)
pixels = models.IntegerField(blank=True)
filename = models.IntegerField(blank=True)
files = models.IntegerField(blank=True)
size = models.IntegerField(blank=True)
_private_fields = ('id', 'movie')
_public_names = {
'movieId': 'id'
}
def options(self):
options = []
for f in self._meta.fields:
if f.name not in self._private_fields:
name = f.name
name = self._public_names.get(name, name)
options.append((name, 'Sort: %s' % name.capitalize()))
return tuple(options)
options = classmethod(options)
class AlternativeTitle(models.Model):
movie = models.ForeignKey(Movie, related_name='alternative_titles_all')
title = models.TextField()
type = models.CharField(max_length=1000)
manual = models.BooleanField(default=False)
class Meta:
ordering = ('title', )
def __unicode__(self):
return self.title
def json(self):
return (self.title, self.type)
def get_or_create(model, name):
try:
o = model.objects.get(name=name)
except model.DoesNotExist:
o = model.objects.create(name=name)
o.save()
return o
class Person(models.Model):
name = models.CharField(max_length=200)
imdbId = models.CharField(max_length=7, blank=True)
name_sort = models.CharField(max_length=200)
movies = models.ManyToManyField(Movie, related_name='people', through='Cast')
class Meta:
ordering = ('name_sort', )
def __unicode__(self):
return self.name
def save(self, *args, **kwargs):
if not self.name_sort:
self.name_sort = oxlib.normalize.canonicalName(self.name)
super(Person, self).save(*args, **kwargs)
def get_or_create(model, name, imdbId=None):
if imdbId:
q = model.objects.filter(name=name, imdbId=imdbId)
else:
q = model.objects.all().filter(name=name)
if q.count() > 0:
o = q[0]
else:
o = model.objects.create(name=name)
if imdbId:
o.imdbId = imdbId
o.save()
return o
get_or_create = classmethod(get_or_create)
def json(self):
return self.name
class Cast(models.Model):
movie = models.ForeignKey(Movie)
person = models.ForeignKey(Person)
role = models.CharField(max_length=200)
character = models.CharField(max_length=200, blank=True)
position = models.IntegerField()
manual = models.BooleanField(default=False)
class Meta:
ordering = ('position', 'person__name_sort')
def __unicode__(self):
return "%s <> %s" % (self.person, self.movie)
def link(self, movie, person, role, character, position, manual=False):
q = self.objects.filter(movie=movie, person=person, role=role, character=character)
if q.count() > 0:
link = q[0]
link.position = position
link.manual = manual
link.save()
else:
link = self()
link.movie=movie
link.person=person
link.role=role
link.character=character
link.position = position
link.manual = manual
link.save()
return link
link = classmethod(link)
def json(self):
return (self.person.json(), self.character)
class Country(models.Model):
name = models.CharField(max_length=200, unique=True)
movies = models.ManyToManyField(Movie, related_name='countries_all', through='MovieCountry')
class Meta:
#!! adding this to ordering, breaks:
# models.Country.objects.values("name").annotate(movies=Count('movies'))
#'moviecountry__position',
ordering = ('name', )
def __unicode__(self):
return self.name
get_or_create = classmethod(get_or_create)
def json(self):
return self.name
class MovieCountry(models.Model):
movie = models.ForeignKey(Movie)
country = models.ForeignKey(Country)
position = models.IntegerField()
manual = models.BooleanField(default=False)
class Meta:
ordering = ('position', 'country')
def __unicode__(self):
return "%s <> %s" % (self.country, self.movie)
def link(self, movie, country, position):
q = self.objects.filter(movie=movie, country=country)
if q.count() > 0:
link = q[0]
link.position = position
link.save()
else:
link = self()
link.movie=movie
link.country=country
link.position=position
link.save()
return link
link = classmethod(link)
class Language(models.Model):
name = models.CharField(max_length=200, unique=True)
movies = models.ManyToManyField(Movie, related_name='languages_all', through="MovieLanguage")
class Meta:
ordering = ('name', )
def __unicode__(self):
return self.name
get_or_create = classmethod(get_or_create)
def json(self):
return self.name
class MovieLanguage(models.Model):
movie = models.ForeignKey(Movie)
language = models.ForeignKey(Language)
position = models.IntegerField()
manual = models.BooleanField(default=False)
class Meta:
ordering = ('position', 'language')
def __unicode__(self):
return self.language.name
def link(self, movie, language, position):
q = self.objects.filter(movie=movie, language=language)
if q.count() > 0:
link = q[0]
link.position = position
link.save()
else:
link = self()
link.movie=movie
link.language=language
link.position=position
link.save()
return link
link = classmethod(link)
class Keyword(models.Model):
name = models.CharField(max_length=200, unique=True)
manual = models.BooleanField(default=False)
movies = models.ManyToManyField(Movie, related_name='keywords_all')
class Meta:
ordering = ('name', )
def __unicode__(self):
return self.name
get_or_create = classmethod(get_or_create)
def json(self):
return self.name
class Genre(models.Model):
name = models.CharField(max_length=200, unique=True)
manual = models.BooleanField(default=False)
movies = models.ManyToManyField(Movie, related_name='genres_all')
class Meta:
ordering = ('name', )
def __unicode__(self):
return self.name
get_or_create = classmethod(get_or_create)
def json(self):
return self.name
class Location(models.Model):
name = models.CharField(max_length=200, unique=True)
manual = models.BooleanField(default=False)
movies = models.ManyToManyField(Movie, related_name='locations_all')
#fixme: geo data
lat_sw = models.FloatField(default=0)
lng_sw = models.FloatField(default=0)
lat_ne = models.FloatField(default=0)
lng_ne = models.FloatField(default=0)
lat_center = models.FloatField(default=0)
lng_center = models.FloatField(default=0)
area = models.FloatField(default=-1)
class Meta:
ordering = ('name', )
def __unicode__(self):
return self.name
get_or_create = classmethod(get_or_create)
def json(self):
return self.name
class Trivia(models.Model):
trivia = models.TextField()
manual = models.BooleanField(default=False)
position = models.IntegerField()
movie = models.ForeignKey(Movie, related_name='trivia_all')
class Meta:
ordering = ('position', )
def __unicode__(self):
return self.trivia
def json(self):
trivia = self.trivia
trivia = oxlib.fixAmpersands(trivia)
trivia = re.sub('<a href="(/name/nm.*?)">(.*?)</a>', '<a href="/?f=name&amp;q=\\2">\\2</a>', trivia)
trivia = re.sub('<a href="/title/tt(.*?)/">(.*?)</a>', '<a href="/\\1">\\2</a>', trivia)
return trivia
class Connection(models.Model):
subject = models.ForeignKey(Movie, related_name='connections_all')
relation = models.CharField(max_length=512)
object = models.ForeignKey(Movie)
manual = models.BooleanField(default=False)
def get_or_create(model, subject, relation, object, reverse=True, manual=False):
q = model.objects.filter(subject=subject, relation=relation, object=object)
if q.count() > 0:
o = q[0]
else:
o = model.objects.create(subject=subject, relation=relation, object=object, manual=manual)
o.save()
if reverse:
_map = {
'Edited into': 'Edited from',
'Features': 'Featured in',
'Follows': 'Followed by',
'References': 'Referenced in',
'Remake of': 'Remade as',
'Spin off from': 'Spin off',
'Spoofs': 'Spoofed in',
'Version of': 'Version of',
}
if relation in _map.values():
for k in _map:
if _map[k] == relation:
reverse_relation = k
else:
reverse_relation = _map[relation]
o2 = model.get_or_create(object, reverse_relation, subject, reverse=False)
return o
get_or_create = classmethod(get_or_create)
def __unicode__(self):
return '%s %s %s' % (self.subject, self.relation, self.object)
class Review(models.Model):
movie = models.ForeignKey('Movie', related_name='reviews_all')
title = models.CharField(blank=True, max_length=2048)
url = models.CharField(blank=True, max_length=2048)
manual = models.BooleanField(default=False)
def __unicode__(self):
return self.title
def get_or_create(self, movie, url):
q = self.objects.filter(movie=movie, url=url)
if q.count() > 0:
o = q[0]
else:
o = self.objects.create(movie=movie, url=url)
o.save()
return o
get_or_create = classmethod(get_or_create)
def name(self):
for w in ReviewWhitelist.objects.all():
if w.url in self.url:
return w.name
return self.title
def json(self):
return (self.name(), self.url)
class ReviewWhitelist(models.Model):
name = models.CharField(max_length=255, unique=True)
url = models.CharField(max_length=255, unique=True)
class List(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User)
name = models.CharField(max_length=255, unique=True)
public = models.BooleanField(default=False)
movies = models.ManyToManyField(Movie, related_name='lists', through='ListItem')
def add(self, movie):
q = self.movies.filter(id=movie.id)
if q.count() == 0:
l = ListItem()
l.list = self
l.movie = movie
l.save()
def remove(self, movie):
self.ListItem.objects.all().filter(movie=movie, list=self).delete()
def __unicode__(self):
return u'%s (%s)' % (self.title, unicode(self.user))
class ListItem(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
list = models.ForeignKey(List)
movie = models.ForeignKey(Movie)
def __unicode__(self):
return u'%s in %s' % (unicode(self.movie), unicode(self.list))
def stream_path(f, size):
name = "%s.%s" % (size, 'ogv')
url_hash = f.oshash
return os.path.join('stream', url_hash[:2], url_hash[2:4], url_hash[4:6], name)
class File(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
oshash = models.CharField(blank=True, unique=True, max_length=16)
sha1 = models.CharField(blank=True, unique=True, max_length=40)
md5 = models.CharField(blank=True, unique=True, max_length=32)
movie = models.ForeignKey(Movie, related_name="files", default=None)
computed_path = models.CharField(blank=True, max_length=2048)
size = models.IntegerField(default=-1)
duration = models.FloatField(default=-1)
is_video = models.BooleanField(default=False)
video_codec = models.CharField(blank=True, max_length=256)
pixel_format = models.CharField(blank=True, max_length=256)
width = models.IntegerField(default=-1)
height = models.IntegerField(default=-1)
pixel_aspect_ratio = models.CharField(blank=True, max_length=256)
display_aspect_ratio = models.CharField(blank=True, max_length=256)
framerate = models.CharField(blank=True, max_length=256)
audio_codec = models.CharField(blank=True, max_length=256)
samplerate = models.IntegerField(default=-1)
channels = models.IntegerField(default=-1)
#computed values
bpp = models.FloatField(default=-1)
pixels = models.IntegerField(default=0)
part = models.IntegerField(default=0)
#stream related fields
available = models.BooleanField(default=False)
stream128 = models.FileField(default=None, upload_to=lambda f, x: stream_path(f, '128'))
stream320 = models.FileField(default=None, upload_to=lambda f, x: stream_path(f, '320'))
stream640 = models.FileField(default=None, upload_to=lambda f, x: stream_path(f, '640'))
def save_chunk(self, chunk, name='video.ogv'):
if not self.available:
#FIXME: this should use stream128 or stream640 depending on configuration
video = getattr(self, 'stream128')
if not video:
video.save(name, ContentFile(chunk))
self.save()
else:
f = open(video.path, 'a')
f.write(chunk)
f.close()
return True
return False
objects = managers.FileManager()
def get_or_create(model, oshash):
try:
f = model.objects.get(oshash=oshash)
except model.DoesNotExist:
f = model.objects.create(oshash=oshash)
f.save()
return f
get_or_create = classmethod(get_or_create)
def __unicode__(self):
return "%s (%s)" % (self.computed_path, self.oshash)
class Subtitle(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User)
file = models.ForeignKey(File, related_name="subtitles")
language = models.CharField(max_length=16)
srt = models.TextField(blank=True)
def get_or_create(model, user, oshash, language):
q = model.objects.filter(file__oshash=oshash, language=language, user=user)
if q.count() > 0:
s = q[0]
else:
f = models.File.get_or_create(oshash=oshash)
s = model.objects.create(user=user, language=language, file=f)
s.save()
return s
get_or_create = classmethod(get_or_create)
def __unicode__(self):
return '%s.%s.srt' % (os.path.splitext(self.movie_file.computed_path)[0], self.language)
class Layer(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
user = models.ForeignKey(User)
movie = models.ForeignKey(Movie)
#seconds
time_in = models.FloatField(default=-1)
time_out = models.FloatField(default=-1)
type = models.CharField(blank=True, max_length=255)
value = models.TextField()
#location = models.ForeignKey('Location', default=None)
class Archive(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
name = models.CharField(max_length=255, unique=True)
public = models.BooleanField(default=False)
users = models.ManyToManyField(User, related_name='archives')
class ArchiveFile(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
archive = models.ForeignKey(Archive, related_name='files')
file = models.ForeignKey(File)
path = models.CharField(blank=True, max_length=2048)
objects = managers.ArchiveFileManager()
def update(self, data):
"""
only add, do not overwrite keys in file
"""
for key in ('duration', 'video_codec', 'pixel_format', 'width', 'height',
'pixel_aspect_ratio', 'display_aspect_ratio', 'framerate',
'audio_codec', 'samplerate', 'channels', 'size', 'sha1', 'md5'):
if key in data and not getattr(self.file, key):
setattr(self.file, key, data[key])
self.path = data.get('path', '')
self.file.save()
self.save()
def get_or_create(model, archive, oshash):
try:
f = model.objects.by_oshash(oshash=oshash)
except model.DoesNotExist:
f = model.objects.create()
f.file = File.get_or_create(oshash)
f.archive = archive
f.save()
return f
get_or_create = classmethod(get_or_create)
def __unicode__(self):
return '%s (%s)' % (self.path, unicode(self.user))

46
oxdb/backend/urls.py Normal file
View file

@ -0,0 +1,46 @@
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()
'''
files/find
files/info
files/add
files/remove
movies/find
movies/get
movies/edit?movie_id...
subtitles/list?oshash
subtitles/get?oshash&language
subtitles/add?oshash&language
subtitles/remove?oshash&language
'''
urlpatterns = patterns("oxdb.backend.views",
(r'^find', 'find'),
(r'^files/find', 'find_files'),
(r'^files/info', 'file_info'),
(r'^archive/(?P<archive>.+)/add', 'add_file'),
(r'^archive/(?P<archive>.+)/remove', 'remove_file'),
(r'^file/parse', 'file_parse'),
(r'^subtitle/get', 'subtitles'),
# Example:
# (r'^oxdata/', include('oxdata.foo.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
# (r'^admin/(.*)', admin.site.root),
)
#add user urls. login, logout, preferences etc
import user_management.urls
urlpatterns += user_management.urls.urlpatterns

127
oxdb/backend/utils.py Normal file
View file

@ -0,0 +1,127 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
#
import errno
import os
import sys
import re
import hashlib
import oxlib
import oxlib.iso
from oxlib.normalize import normalizeName
def oxid(title, director, year='', seriesTitle='', episodeTitle='', season=0, episode=0):
oxid_value = u"\n".join([title, director, year])
oxid = hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()
if seriesTitle:
oxid_value = u"\n".join([seriesTitle, "%02d" % season])
oxid = hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()[:20]
oxid_value = u"\n".join(["%02d" % episode, episodeTitle, director, year])
oxid += hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()[:20]
return u"0x" + oxid
def oxdb_director(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
def oxdb_title(_title, searchTitle = False):
'''
normalize filename to get movie title
'''
_title = os.path.basename(_title)
_title = _title.replace('... ', '_dot_dot_dot_')
_title = _title.replace('. ', '_dot__space_')
_title = _title.replace(' .', '_space__dot_')
title = _title.split('.')[0]
title = re.sub('([a-z0-9])_ ', '\\1: ', title)
se = re.compile('Season (\d+).Episode (\d+)').findall(_title)
if se:
se = "S%02dE%02d" % (int(se[0][0]), int(se[0][1]))
if 'Part' in _title.split('.')[-2] and 'Episode' not in _title.split('.')[-3]:
stitle = _title.split('.')[-3]
else:
stitle = _title.split('.')[-2]
if stitle.startswith('Episode '):
stitle = ''
if searchTitle:
title = '"%s" %s' % (title, stitle)
else:
title = '%s (%s) %s' % (title, se, stitle)
title = title.strip()
title = title.replace('_dot_dot_dot_', '... ')
title = title.replace('_dot__space_', '. ')
title = title.replace('_space__dot_', ' .')
return title
def oxdb_year(data):
return oxlib.findRe(data, '\.(\d{4})\.')
def oxdb_series_title(path):
seriesTitle = u''
if path.startswith('Series'):
seriesTitle = os.path.basename(os.path.dirname(path))
else:
t = oxdb_title(path)
if " (S" in t:
seriesTitle = t.split(" (S")[0]
return seriesTitle
def oxdb_episode_title(path):
episodeTitle = u''
ep = re.compile('.Episode \d+?\.(.*?)\.[a-zA-Z]').findall(path)
if ep:
episodeTitle = ep[0][0]
return episodeTitle
def oxdb_season_episode(path):
season = 0
episode = 0
path = os.path.basename(path)
se = re.compile('Season (\d+).Episode (\d+)').findall(path)
if se:
season = int(se[0][0])
episode = int(se[0][1])
else:
ep = re.compile('.Episode (\d+?)').findall(path)
if ep:
episode = int(ep[0][0])
if season == 0 and episode == 0:
se = re.compile('S(\d\d)E(\d\d)').findall(path)
if se:
season = int(se[0][0])
episode = int(se[0][1])
return (season, episode)
def oxdb_part(path):
part = 1
path = path.lower()
p = re.compile('part\s*?(\d+)\.').findall(path)
if p:
part = p[0]
else:
p = re.compile('cd\s*?(\d+)\.').findall(path)
if p:
part = p[0]
return part
def parsePath(path):
import oxweb.imdb
search_title = oxdb_title(path, True)
r = {}
r['title'] = oxdb_title(path)
r['director'] = oxdb_director(path)
r['episode_title'] = oxdb_episode_title(path)
r['season'], r['episode'] = oxdb_season_episode(path)
r['series'] = oxdb_series_title(path)
r['part'] = oxdb_part(path)
r['imdbId'] = oxweb.imdb.guess(search_title, r['director'])
return r

362
oxdb/backend/views.py Normal file
View file

@ -0,0 +1,362 @@
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import os.path
import re
from datetime import datetime
from urllib2 import unquote
from django.db.models import Q, Avg, Count
from django.contrib.auth.models import User
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from django.template import RequestContext
from django.core.paginator import Paginator
from django.contrib.auth.decorators import login_required
from django.utils import simplejson as json
from oxdb.utils.shortcuts import render_to_json_response
from oxdb.utils.decorators import login_required_json
import models
import utils
'''
field.length -> movie.sort.all()[0].field
o=0&n=100
a & b | c & d
query
l=user:name or l=name
q=year:1980,hello,country:usa
q=year:1980,hello,country:!usa
q=title:^the$
q=title:^100%24$
q=year:<1970,year:>1960
q=year:<1960,year:>1950,title:sex
!1960-1970
2009.08.02.22.26.35-2009.08.02.22.26.35
!^the
(dddd.dd.dd)-(dddd.dd.dd)
5-8
10000-20000
<2009-08-02-22-26-35
>2009-08-02-22-26-35
2009-08-02-22-26-35<
^the the*
*foo foo$
*foo* foo
s=director:asc,year:desc default: director:asc,year:desc
r=0:100 or r=100 or r=100: default: 0:100
p=id,title,director,date,cast.length default: title,director,year,country
q
List data backend spec:
url = //url for request
params = [] //additional params passed to url, i.e. query, or group
the url must understand the following requests:
number of items:
url?params&n=1
> {items: N}
items sorted by key range X to Y:
url?params&s=key:asc|desc&r=X:Y
> {items: [{k0:v0, k1:v1...}, {k0:v0, k1:v1...}]}
Examples:
/json/find?l=all&s=title&f=all&q=&a=desc&p=id,title,director,date,cast.length
/json/find?r=0:100&l=all&s=title&f=all&q=&a=desc&p=id,title,director,date,cast.length
{
movies=[
{
"id":
"title": "fsdf",
"director":
},
]
}
#get sort order for all ids
/json/find?r=0:1000&l=all&s=title&f=all&q=&a=desc&p=id
{
movies=[
{
"id": id
},
]
}
/json/find?l=all&s=title&f=all&q=&a=desc
{
movies: 1234,
files: 2345,
pixels: 1242345345,
size: 1235,
duration: 1235,
}
/json/find?r=0:100&l=all&s=[name, items]&f=all&q=&a=desc&g=country
{
groups = [ {name:"USA", movies: 123}, {name:"UK", movies: 1234} ]
}
#find as you type: in table, by sort string
#auto compleat in find box
'''
def order_query(qs, s, prefix='sort__'):
order_by = []
for e in s.split(','):
o = e.split(':')
if len(o) == 1: o.append('asc')
order = {'id': 'movieId'}.get(o[0], o[0])
order = '%s%s' % (prefix, order)
if o[1] == 'desc':
order = '-%s' % order
order_by.append(order)
if order_by:
qs = qs.order_by(*order_by)
return qs
def parse_query(request):
get = request.GET
query = {}
query['i'] = 0
query['o'] = 100
query['s'] = 'title:asc'
def parse_dict(s):
d = s.split(",")
return [i.strip() for i in d]
_dicts = ['p', ]
_ints = ['n', ]
for key in ('s', 'p', 'g', 'l', 'n'):
if key in get:
if key in _ints:
query[key] = int(get[key])
elif key in _dicts:
query[key] = parse_dict(get[key])
else:
query[key] = get[key]
query['q'] = models.Movie.objects.find(request)
if 'r' in get:
r = get['r'].split(':')
if len(r) == 1: r.append(0)
if r[0] == '': r[0] = 0
if r[1] == '': r[0] = -1
query['i'] = int(r[0])
query['o'] = int(r[1])
#group by only allows sorting by name or number of itmes
return query
def find(request):
query = parse_query(request)
response = {}
if 'p' in query:
response['items'] = []
qs = order_query(query['q'], query['s'])
if 'n' in query:
response = {'items': qs.count()}
else:
qs = qs[query['i']:query['o']]
print qs.query.as_sql()
p = Paginator(qs, 100)
for i in p.page_range:
page = p.page(i)
for m in page.object_list:
response['items'].append(m.json(query['p']))
elif 'g' in query:
if query['s'].split(':')[0] not in ('name', 'items'):
query['s'] = 'name'
#FIXME: also filter lists here
response['items'] = []
name = 'name'
items = 'movies'
movie_qs = query['q']
_objects = {
'country': models.Country.objects,
'genre': models.Genre.objects,
'language': models.Language.objects,
'director': models.Person.objects.filter(cast__role='directors'),
}
if query['g'] in _objects:
qs = _objects[query['g']].filter(movies__id__in=movie_qs).values('name').annotate(movies=Count('movies'))
elif query['g'] == "year":
qs = movie_qs.values('imdb__year').annotate(movies=Count('id'))
name='imdb__year'
if 'n' in query:
response['items'] = qs.count()
else:
#replace normalized items/name sort with actual db value
order_by = query['s'].split(":")
if len(order_by) == 1:
order_by.append('desc')
if order_by[0] == 'name':
order_by = "%s:%s" % (name, order_by[1])
else:
order_by = "%s:%s" % (items, order_by[1])
qs = order_query(qs, order_by, '')
qs = qs[query['i']:query['o']]
for i in qs:
group = {'title': i[name], 'items': i[items]}
response['items'].append(group)
else:
#FIXME: also filter lists here
movies = models.Movie.objects.filter(available=True)
files = models.File.objects.all()
response['items'] = movies.count()
response['files'] = files.count()
r = files.aggregate(Count('size'), Count('pixels'), Count('duration'))
response['pixels'] = r['pixels__count']
response['size'] = r['size__count']
response['duration'] = r['duration__count']
return render_to_json_response(response)
'''
GET info?oshash=a41cde31c581e11d
> {
"movie_id": 0123456,
"duration": 5.266667,
"video_codec": "mpeg1",
"pixel_format": "yuv420p",
"width": 352,
"height": 240,
"pixel_aspect_ratio": "1:1",
"display_aspect_ratio": "22:15",
"framerate": "30:1",
"audio_codec": "mp2",
"samplerate": 44100,
"channels": 1,
"path": "E/Example, The/An Example.avi",
"size": 1646274
"oshash": "a41cde31c581e11d",
"sha1":..,
"md5":..
}
'''
def file_info(request):
oshash = request.GET['oshash']
f = models.MovieFile.objects.get(oshash=oshash)
response = f.json()
return render_to_json_response(response)
'''
GET subtitles?oshash=a41cde31c581e11d
> {
"languages": ['en', 'fr', 'de']
}
GET subtitles?oshash=a41cde31c581e11d&language=en
> srt file
POST subtitle?oshash=a41cde31c581e11d&language=en
srt =
'''
def subtitles(request):
oshash = request.GET['oshash']
language = request.GET.get('language', None)
if requeset.method == 'POST':
user = request.user
sub = models.Subtitles.get_or_create(user, oshash, language)
sub.srt = request.POST['srt']
sub.save()
else:
if language:
q = models.Subtitles.objects.filter(movie_file__oshash=oshash, language=language)
if q.count() > 0:
return HttpResponse(q[0].srt, content_type='text/x-srt')
response = {}
l = models.Subtitles.objects.filter(movie_file__oshash=oshash).values('language')
response['languages'] = [f['language'] for f in l]
return render_to_json_response(response)
'''
GET list
> {
"files": {
"a41cde31c581e11d": {"path": "E/Example, The/An Example.avi", "size":1646274},
}
}
'''
@login_required_json
def list_files(request):
response['files'] = {}
qs = models.UserFile.filter(user=request.user)
p = Paginator(qs, 1000)
for i in p.page_range:
page = p.page(i)
for f in page.object_list:
response['files'][f.movie_file.oshash] = {'path': f.path, 'size': f.movie_file.size}
return render_to_json_response(response)
def find_files(request):
query = parse_query(request)
response['files'] = {}
qs = models.UserFile.filter(user=request.user).filter(movie_file__movie__id__in=quert['q'])
p = Paginator(qs, 1000)
for i in p.page_range:
page = p.page(i)
for f in page.object_list:
response['files'][f.movie_file.oshash] = {'path': f.path, 'size': f.movie_file.size}
return render_to_json_response(response)
'''
POST add
> file: {
"duration": 5.266667,
"video_codec": "mpeg1",
"pixel_format": "yuv420p",
"width": 352,
"height": 240,
"pixel_aspect_ratio": "1:1",
"display_aspect_ratio": "22:15",
"framerate": "30:1",
"audio_codec": "mp2",
"samplerate": 44100,
"channels": 1,
"path": "E/Example, The/An Example.avi",
"size": 1646274
"oshash": "a41cde31c581e11d",
"sha1":..,
"md5":..
}
'''
#@login_required_json
def add_file(request, archive):
print request.POST
info = json.loads(request.POST['file'])
oshash = info['oshash']
archive = models.Archive.objects.get(name=archive)
if archive.users.filter(user=request.user).count() == 1:
user_file = models.ArchiveFile.get_or_create(archive, oshash)
user_file.update(request.POST)
response = {'status': 200}
else:
response = {'status': 404}
return render_to_json_response(response)
'''
POST remove?oshash=
'''
@login_required_json
def remove_file(request, archive):
oshash = request.POST['oshash']
archive = models.Archive.objects.get(name=archive)
models.UserFiles.objects.filter(movie_file__oshash=oshash, user=request.user).delete()
response = {'status': 200}
return render_to_json_response(response)
def file_parse(request):
response = utils.parsePath(request.POST['path'])
return render_to_json_response(response)