diff --git a/.bzrignore b/.bzrignore
index b21790c05..03a40b211 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1,2 +1,6 @@
secret.txt
local_settings.py
+lib
+include
+src
+bin
diff --git a/README b/README
new file mode 100644
index 000000000..ee3287b47
--- /dev/null
+++ b/README
@@ -0,0 +1,36 @@
+
+To setup a local instance of 0xdb:
+
+ bzr branch http://code.0xdb.org/oxdb oxdb
+ cd oxdb
+ virtualenv .
+ pip -E . install -r requirements.txt
+
+
+you need python, bazaar, pip and virtualenv:
+
+ apt-get install python-setuptools bzr
+ east_install pip
+ pip install virtualenv
+
+also it uses system python moduels, so make sure you have
+ ipython, dbmodule(psycopg2, python-mysqldb,..)
+installed via apt-get/pip/easy_install in your system path.
+
+
+Install rabbitmq and carrot:
+ sudo apt-get install rabbitmq-server
+
+ sudo rabbitmqctl add_user oxdb password
+ sudo rabbitmqctl add_vhost /oxdb
+ sudo rabbitmqctl set_permissions -p /oxdb oxdb "^oxdb-.*" ".*" ".*"
+
+
+ update BROKER_* settings in local_settings.py:
+
+Development:
+ we are using django, http://docs.djangoproject.com/en/dev/
+ communication between webserver and background tasks is done via rabbitmq
+ http://github.com/ask/carrot/ for more info on the lib used to communicate
+
+
diff --git a/apache/vhost.conf.in b/apache/vhost.conf.in
new file mode 100644
index 000000000..b491e21b3
--- /dev/null
+++ b/apache/vhost.conf.in
@@ -0,0 +1,24 @@
+
+
+
+ Options -Indexes
+
+
+ Order deny,allow
+ Allow from all
+
+
+ Alias /.bzr /oxdb/.bzr
+ Alias /static __PREFIX__/oxdb/static
+ Alias /favicon.ico __PREFIX__/oxdb/static/favicon.ico
+ Alias /media __PREFIX__/oxdb/media
+ Alias /admin/media __PREFIX__/src/django/django/contrib/admin/media
+ WSGIScriptAlias / __PREFIX__/wsgi/django.wsgi
+
+ WSGIDaemonProcess oxdb user=oxdb group=oxdb threads=25 python-path=__PREFIX__/lib/python2.6/site-packages/
+ WSGIProcessGroup oxdb
+
+ ServerSignature Off
+
+
+
diff --git a/oxdb/backend/admin.py b/oxdb/backend/admin.py
new file mode 100644
index 000000000..2341c9c90
--- /dev/null
+++ b/oxdb/backend/admin.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# vi:si:et:sw=4:sts=4:ts=4
+# Written 2009 by j@mailb.org
+
+from django.contrib import admin
+
+from forms import FileAdminForm, MovieAdminForm, ArchiveFileAdminForm
+import models
+
+
+#class MovieImdbAdmin(admin.ModelAdmin):
+# search_fields = ['imdbId', 'title']
+#admin.site.register(models.MovieImdb, MovieImdbAdmin)
+
+class MovieImdbInline(admin.StackedInline):
+ model = models.MovieImdb
+
+class MovieOxdbInline(admin.StackedInline):
+ model = models.MovieOxdb
+
+class MovieAdmin(admin.ModelAdmin):
+ search_fields = ['movieId', 'imdb__title', 'oxdb__title']
+ form = MovieAdminForm
+ #inlines = [MovieImdbInline, MovieOxdbInline]
+
+admin.site.register(models.Movie, MovieAdmin)
+
+
+class FileAdmin(admin.ModelAdmin):
+ search_fields = ['path', 'video_codec']
+
+ form = FileAdminForm
+
+admin.site.register(models.File, FileAdmin)
+
+class ArchiveFileAdmin(admin.ModelAdmin):
+ search_fields = ['path', 'archive__name']
+ form = ArchiveFileAdminForm
+
+admin.site.register(models.ArchiveFile, ArchiveFileAdmin)
+
+
+class ArchiveAdmin(admin.ModelAdmin):
+ search_fields = ['name']
+admin.site.register(models.Archive, ArchiveAdmin)
+
diff --git a/oxdb/backend/fields.py b/oxdb/backend/fields.py
new file mode 100644
index 000000000..e556eccab
--- /dev/null
+++ b/oxdb/backend/fields.py
@@ -0,0 +1,47 @@
+from django.db import models
+from django.utils import simplejson as json
+
+
+class DictField(models.TextField):
+ """DictField is a textfield that contains JSON-serialized dictionaries."""
+
+ # Used so to_python() is called
+ __metaclass__ = models.SubfieldBase
+
+ def to_python(self, value):
+ """Convert our string value to python after we load it from the DB"""
+ if isinstance(value, dict):
+ return value
+
+ value = json.loads(value)
+ assert isinstance(value, dict)
+ return value
+
+ def get_db_prep_save(self, value):
+ """Convert our JSON object to a string before we save"""
+ assert isinstance(value, dict)
+ value = json.dumps(value)
+ return super(DictField, self).get_db_prep_save(value)
+
+
+class TupleField(models.TextField):
+ """TupleField is a textfield that contains JSON-serialized tuples."""
+
+ # Used so to_python() is called
+ __metaclass__ = models.SubfieldBase
+
+ def to_python(self, value):
+ """Convert our string value to JSON after we load it from the DB"""
+ if isinstance(value, tuple):
+ return value
+
+ value = json.loads(value)
+ assert isinstance(value, list)
+ return tuple(value)
+
+ def get_db_prep_save(self, value):
+ """Convert our JSON object to a string before we save"""
+ assert isinstance(value, tuple)
+ value = json.dumps(value)
+ return super(TupleField, self).get_db_prep_save(value)
+
diff --git a/oxdb/backend/forms.py b/oxdb/backend/forms.py
new file mode 100644
index 000000000..15cc3d208
--- /dev/null
+++ b/oxdb/backend/forms.py
@@ -0,0 +1,42 @@
+from ajax_filtered_fields.forms import AjaxManyToManyField, ForeignKeyByLetter
+from django.conf import settings
+from django import forms
+
+import models
+
+ajax_filtered_js = (
+ settings.ADMIN_MEDIA_PREFIX + "js/SelectBox.js",
+ settings.ADMIN_MEDIA_PREFIX + "js/SelectFilter2.js",
+ settings.STATIC_URL + 'js/jquery/jquery.js',
+ settings.STATIC_URL + 'js/ajax_filtered_fields.js',
+)
+
+class FileAdminForm(forms.ModelForm):
+ movie = ForeignKeyByLetter(models.Movie, field_name='imdb__title')
+
+ class Meta:
+ model = models.File
+
+ class Media:
+ js = ajax_filtered_js
+
+class ArchiveFileAdminForm(forms.ModelForm):
+ file = ForeignKeyByLetter(models.File, field_name='path')
+
+ class Meta:
+ model = models.ArchiveFile
+
+ class Media:
+ js = ajax_filtered_js
+
+
+class MovieAdminForm(forms.ModelForm):
+ imdb = ForeignKeyByLetter(models.MovieImdb, field_name='title')
+ oxdb = ForeignKeyByLetter(models.MovieOxdb, field_name='title')
+
+ class Meta:
+ model = models.Movie
+
+ class Media:
+ js = ajax_filtered_js
+
diff --git a/oxdb/backend/load.py b/oxdb/backend/load.py
index 0226a56e2..fd86bbda1 100644
--- a/oxdb/backend/load.py
+++ b/oxdb/backend/load.py
@@ -5,8 +5,8 @@ import os.path
from django.db import models
from django.contrib.auth.models import User
-import ox.web.imdb
-from ox import stripTags, findRe
+import oxweb.imdb
+from oxlib import stripTags, findRe
import models
@@ -37,14 +37,14 @@ def loadIMDb(imdbId):
movie = models.Movie()
movie.imdb = imdb
- info = ox.web.imdb.getMovieInfo(imdbId)
+ info = oxweb.imdb.getMovieInfo(imdbId)
for key in ('title',
'tagline',
'year',
'release_date',
'rating',
'votes',
- 'series_imdb'
+ 'series_imdb',
'season',
'episode'):
if key in info:
@@ -58,11 +58,11 @@ def loadIMDb(imdbId):
if key in info:
setattr(movie.imdb, _info_map.get(key, key), info[key])
- movie.imdb.plot = ox.web.imdb.getMoviePlot(imdbId)
+ movie.imdb.plot = oxweb.imdb.getMoviePlot(imdbId)
debug("plot", movie.imdb.plot)
- movie.imdb.runtime = ox.web.imdb.getMovieRuntimeSeconds(imdbId)
- business = ox.web.imdb.getMovieBusinessSum(imdbId)
+ movie.imdb.runtime = oxweb.imdb.getMovieRuntimeSeconds(imdbId)
+ business = oxweb.imdb.getMovieBusinessSum(imdbId)
for key in ('gross', 'profit', 'budget'):
setattr(movie.imdb, key, business[key])
@@ -70,7 +70,7 @@ def loadIMDb(imdbId):
movie.oxdbId = "__init__%s" % random.randint(0, 100000)
movie.save()
models.AlternativeTitle.objects.filter(movie=movie, manual=False).delete()
- for i in ox.web.imdb.getMovieAKATitles(imdbId):
+ for i in oxweb.imdb.getMovieAKATitles(imdbId):
t = models.AlternativeTitle()
t.movie = movie
t.title = i[0]
@@ -100,7 +100,7 @@ def loadIMDb(imdbId):
#Location
movie.locations_all.filter(manual=False).delete()
- locations = ox.web.imdb.getMovieLocations(imdbId)
+ locations = oxweb.imdb.getMovieLocations(imdbId)
for i in locations:
debug("add location", i)
location = models.Location.get_or_create(i)
@@ -116,7 +116,7 @@ def loadIMDb(imdbId):
#Keyword
movie.keywords_all.filter(manual=False).delete()
- keywords = ox.web.imdb.getMovieKeywords(imdbId)
+ keywords = oxweb.imdb.getMovieKeywords(imdbId)
for g in keywords:
debug("add keyword", g)
keyword = models.Keyword.get_or_create(g)
@@ -124,7 +124,7 @@ def loadIMDb(imdbId):
movie.trivia_all.filter(manual=False).delete()
position = 0
- trivia = ox.web.imdb.getMovieTrivia(imdbId)
+ trivia = oxweb.imdb.getMovieTrivia(imdbId)
for i in trivia:
debug("add trivia", i)
t = models.Trivia()
@@ -136,7 +136,7 @@ def loadIMDb(imdbId):
position = 0
models.Cast.objects.filter(movie=movie).filter(manual=False).delete()
- credits = ox.web.imdb.getMovieCredits(imdbId)
+ credits = oxweb.imdb.getMovieCredits(imdbId)
for role in credits:
for p in credits[role]:
name = stripTags(p[0])
@@ -149,7 +149,7 @@ def loadIMDb(imdbId):
position += 1
movie.connections_all.filter(manual=False).delete()
- connections = ox.web.imdb.getMovieConnections(imdbId)
+ connections = oxweb.imdb.getMovieConnections(imdbId)
for relation in connections:
for otherId in connections[relation]:
try:
@@ -159,7 +159,7 @@ def loadIMDb(imdbId):
except models.Movie.DoesNotExist:
pass
- reviews = ox.web.imdb.getMovieExternalReviews(imdbId)
+ reviews = oxweb.imdb.getMovieExternalReviews(imdbId)
movie.reviews_all.filter(manual=False).delete()
for r in reviews:
debug("add review", r)
diff --git a/oxdb/backend/managers.py b/oxdb/backend/managers.py
index 57b9e5852..eb32a9907 100644
--- a/oxdb/backend/managers.py
+++ b/oxdb/backend/managers.py
@@ -132,7 +132,7 @@ class FileManager(Manager):
def movie_files(self, movie):
q = self.get_query_set()
- return q.filter(is_video=True, movie=movie)
+ return q.filter(type=1, movie=movie)
class ArchiveFileManager(Manager):
def get_query_set(self):
@@ -144,9 +144,10 @@ class ArchiveFileManager(Manager):
def by_oshash(self, oshash):
q = self.get_query_set()
- q.filter(movie_file__oshash=oshash)
+ q = q.filter(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]
+ else:
+ return q[0]
diff --git a/oxdb/backend/migrations/0001_initial.py b/oxdb/backend/migrations/0001_initial.py
index 8ee506a62..d6ad0ee20 100644
--- a/oxdb/backend/migrations/0001_initial.py
+++ b/oxdb/backend/migrations/0001_initial.py
@@ -2,7 +2,7 @@
from south.db import db
from django.db import models
-from oxdb.backend.models import *
+from backend.models import *
class Migration:
@@ -12,8 +12,9 @@ class Migration:
db.create_table('backend_trivia', (
('id', orm['backend.Trivia:id']),
('trivia', orm['backend.Trivia:trivia']),
- ('movie', orm['backend.Trivia:movie']),
+ ('manual', orm['backend.Trivia:manual']),
('position', orm['backend.Trivia:position']),
+ ('movie', orm['backend.Trivia:movie']),
))
db.send_create_signal('backend', ['Trivia'])
@@ -23,6 +24,7 @@ class Migration:
('movie', orm['backend.AlternativeTitle:movie']),
('title', orm['backend.AlternativeTitle:title']),
('type', orm['backend.AlternativeTitle:type']),
+ ('manual', orm['backend.AlternativeTitle:manual']),
))
db.send_create_signal('backend', ['AlternativeTitle'])
@@ -32,6 +34,7 @@ class Migration:
('movie', orm['backend.MovieLanguage:movie']),
('language', orm['backend.MovieLanguage:language']),
('position', orm['backend.MovieLanguage:position']),
+ ('manual', orm['backend.MovieLanguage:manual']),
))
db.send_create_signal('backend', ['MovieLanguage'])
@@ -40,10 +43,12 @@ class Migration:
('id', orm['backend.Movie:id']),
('created', orm['backend.Movie:created']),
('modified', orm['backend.Movie:modified']),
- ('accessed', orm['backend.Movie:accessed']),
+ ('available', orm['backend.Movie:available']),
('movieId', orm['backend.Movie:movieId']),
- ('imdbId', orm['backend.Movie:imdbId']),
('oxdbId', orm['backend.Movie:oxdbId']),
+ ('imdb', orm['backend.Movie:imdb']),
+ ('oxdb', orm['backend.Movie:oxdb']),
+ ('rights_level', orm['backend.Movie:rights_level']),
('title', orm['backend.Movie:title']),
('year', orm['backend.Movie:year']),
('runtime', orm['backend.Movie:runtime']),
@@ -56,26 +61,29 @@ class Migration:
('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']),
+ ('directors', orm['backend.Movie:directors']),
+ ('writers', orm['backend.Movie:writers']),
+ ('editors', orm['backend.Movie:editors']),
+ ('producers', orm['backend.Movie:producers']),
+ ('cinematographers', orm['backend.Movie:cinematographers']),
+ ('cast', orm['backend.Movie:cast']),
+ ('alternative_titles', orm['backend.Movie:alternative_titles']),
+ ('genres', orm['backend.Movie:genres']),
+ ('keywords', orm['backend.Movie:keywords']),
+ ('countries', orm['backend.Movie:countries']),
+ ('languages', orm['backend.Movie:languages']),
+ ('trivia', orm['backend.Movie:trivia']),
+ ('locations', orm['backend.Movie:locations']),
+ ('connections', orm['backend.Movie:connections']),
+ ('reviews', orm['backend.Movie:reviews']),
+ ('stream128', orm['backend.Movie:stream128']),
+ ('stream320', orm['backend.Movie:stream320']),
+ ('stream640', orm['backend.Movie:stream640']),
('scene_height', orm['backend.Movie:scene_height']),
))
db.send_create_signal('backend', ['Movie'])
@@ -86,6 +94,7 @@ class Migration:
('created', orm['backend.Archive:created']),
('modified', orm['backend.Archive:modified']),
('name', orm['backend.Archive:name']),
+ ('public', orm['backend.Archive:public']),
))
db.send_create_signal('backend', ['Archive'])
@@ -95,11 +104,36 @@ class Migration:
('created', orm['backend.ArchiveFile:created']),
('modified', orm['backend.ArchiveFile:modified']),
('archive', orm['backend.ArchiveFile:archive']),
- ('movie_file', orm['backend.ArchiveFile:movie_file']),
+ ('file', orm['backend.ArchiveFile:file']),
('path', orm['backend.ArchiveFile:path']),
))
db.send_create_signal('backend', ['ArchiveFile'])
+ # Adding model 'MovieOxdb'
+ db.create_table('backend_movieoxdb', (
+ ('id', orm['backend.MovieOxdb:id']),
+ ('created', orm['backend.MovieOxdb:created']),
+ ('modified', orm['backend.MovieOxdb:modified']),
+ ('title', orm['backend.MovieOxdb:title']),
+ ('year', orm['backend.MovieOxdb:year']),
+ ('runtime', orm['backend.MovieOxdb:runtime']),
+ ('release_date', orm['backend.MovieOxdb:release_date']),
+ ('tagline', orm['backend.MovieOxdb:tagline']),
+ ('plot', orm['backend.MovieOxdb:plot']),
+ ('plot_outline', orm['backend.MovieOxdb:plot_outline']),
+ ('rating', orm['backend.MovieOxdb:rating']),
+ ('votes', orm['backend.MovieOxdb:votes']),
+ ('budget', orm['backend.MovieOxdb:budget']),
+ ('gross', orm['backend.MovieOxdb:gross']),
+ ('profit', orm['backend.MovieOxdb:profit']),
+ ('series_imdb', orm['backend.MovieOxdb:series_imdb']),
+ ('series_title', orm['backend.MovieOxdb:series_title']),
+ ('episode_title', orm['backend.MovieOxdb:episode_title']),
+ ('season', orm['backend.MovieOxdb:season']),
+ ('episode', orm['backend.MovieOxdb:episode']),
+ ))
+ db.send_create_signal('backend', ['MovieOxdb'])
+
# Adding model 'Language'
db.create_table('backend_language', (
('id', orm['backend.Language:id']),
@@ -115,9 +149,22 @@ class Migration:
))
db.send_create_signal('backend', ['ReviewWhitelist'])
+ # Adding model 'Layer'
+ db.create_table('backend_layer', (
+ ('id', orm['backend.Layer:id']),
+ ('created', orm['backend.Layer:created']),
+ ('modified', orm['backend.Layer:modified']),
+ ('user', orm['backend.Layer:user']),
+ ('movie', orm['backend.Layer:movie']),
+ ('time_in', orm['backend.Layer:time_in']),
+ ('time_out', orm['backend.Layer:time_out']),
+ ('type', orm['backend.Layer:type']),
+ ('value', orm['backend.Layer:value']),
+ ))
+ db.send_create_signal('backend', ['Layer'])
+
# 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']),
@@ -135,6 +182,8 @@ class Migration:
('summary', orm['backend.MovieSort:summary']),
('trivia', orm['backend.MovieSort:trivia']),
('connections', orm['backend.MovieSort:connections']),
+ ('rating', orm['backend.MovieSort:rating']),
+ ('votes', orm['backend.MovieSort:votes']),
('scenes', orm['backend.MovieSort:scenes']),
('words', orm['backend.MovieSort:words']),
('wpm', orm['backend.MovieSort:wpm']),
@@ -163,6 +212,7 @@ class Migration:
('computed_path', orm['backend.File:computed_path']),
('size', orm['backend.File:size']),
('duration', orm['backend.File:duration']),
+ ('is_video', orm['backend.File:is_video']),
('video_codec', orm['backend.File:video_codec']),
('pixel_format', orm['backend.File:pixel_format']),
('width', orm['backend.File:width']),
@@ -176,6 +226,10 @@ class Migration:
('bpp', orm['backend.File:bpp']),
('pixels', orm['backend.File:pixels']),
('part', orm['backend.File:part']),
+ ('available', orm['backend.File:available']),
+ ('stream128', orm['backend.File:stream128']),
+ ('stream320', orm['backend.File:stream320']),
+ ('stream640', orm['backend.File:stream640']),
))
db.send_create_signal('backend', ['File'])
@@ -190,6 +244,7 @@ class Migration:
db.create_table('backend_genre', (
('id', orm['backend.Genre:id']),
('name', orm['backend.Genre:name']),
+ ('manual', orm['backend.Genre:manual']),
))
db.send_create_signal('backend', ['Genre'])
@@ -199,6 +254,7 @@ class Migration:
('movie', orm['backend.MovieCountry:movie']),
('country', orm['backend.MovieCountry:country']),
('position', orm['backend.MovieCountry:position']),
+ ('manual', orm['backend.MovieCountry:manual']),
))
db.send_create_signal('backend', ['MovieCountry'])
@@ -208,6 +264,7 @@ class Migration:
('movie', orm['backend.Review:movie']),
('title', orm['backend.Review:title']),
('url', orm['backend.Review:url']),
+ ('manual', orm['backend.Review:manual']),
))
db.send_create_signal('backend', ['Review'])
@@ -217,7 +274,7 @@ class Migration:
('created', orm['backend.Subtitle:created']),
('modified', orm['backend.Subtitle:modified']),
('user', orm['backend.Subtitle:user']),
- ('movie_file', orm['backend.Subtitle:movie_file']),
+ ('file', orm['backend.Subtitle:file']),
('language', orm['backend.Subtitle:language']),
('srt', orm['backend.Subtitle:srt']),
))
@@ -231,6 +288,7 @@ class Migration:
('role', orm['backend.Cast:role']),
('character', orm['backend.Cast:character']),
('position', orm['backend.Cast:position']),
+ ('manual', orm['backend.Cast:manual']),
))
db.send_create_signal('backend', ['Cast'])
@@ -247,9 +305,36 @@ class Migration:
db.create_table('backend_keyword', (
('id', orm['backend.Keyword:id']),
('name', orm['backend.Keyword:name']),
+ ('manual', orm['backend.Keyword:manual']),
))
db.send_create_signal('backend', ['Keyword'])
+ # Adding model 'MovieImdb'
+ db.create_table('backend_movieimdb', (
+ ('id', orm['backend.MovieImdb:id']),
+ ('created', orm['backend.MovieImdb:created']),
+ ('modified', orm['backend.MovieImdb:modified']),
+ ('imdbId', orm['backend.MovieImdb:imdbId']),
+ ('title', orm['backend.MovieImdb:title']),
+ ('year', orm['backend.MovieImdb:year']),
+ ('runtime', orm['backend.MovieImdb:runtime']),
+ ('release_date', orm['backend.MovieImdb:release_date']),
+ ('tagline', orm['backend.MovieImdb:tagline']),
+ ('plot', orm['backend.MovieImdb:plot']),
+ ('plot_outline', orm['backend.MovieImdb:plot_outline']),
+ ('rating', orm['backend.MovieImdb:rating']),
+ ('votes', orm['backend.MovieImdb:votes']),
+ ('budget', orm['backend.MovieImdb:budget']),
+ ('gross', orm['backend.MovieImdb:gross']),
+ ('profit', orm['backend.MovieImdb:profit']),
+ ('series_imdb', orm['backend.MovieImdb:series_imdb']),
+ ('series_title', orm['backend.MovieImdb:series_title']),
+ ('episode_title', orm['backend.MovieImdb:episode_title']),
+ ('season', orm['backend.MovieImdb:season']),
+ ('episode', orm['backend.MovieImdb:episode']),
+ ))
+ db.send_create_signal('backend', ['MovieImdb'])
+
# Adding model 'List'
db.create_table('backend_list', (
('id', orm['backend.List:id']),
@@ -267,6 +352,7 @@ class Migration:
('subject', orm['backend.Connection:subject']),
('relation', orm['backend.Connection:relation']),
('object', orm['backend.Connection:object']),
+ ('manual', orm['backend.Connection:manual']),
))
db.send_create_signal('backend', ['Connection'])
@@ -274,6 +360,7 @@ class Migration:
db.create_table('backend_location', (
('id', orm['backend.Location:id']),
('name', orm['backend.Location:name']),
+ ('manual', orm['backend.Location:manual']),
('lat_sw', orm['backend.Location:lat_sw']),
('lng_sw', orm['backend.Location:lng_sw']),
('lat_ne', orm['backend.Location:lat_ne']),
@@ -286,7 +373,6 @@ class Migration:
# 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']),
@@ -368,12 +454,18 @@ class Migration:
# Deleting model 'ArchiveFile'
db.delete_table('backend_archivefile')
+ # Deleting model 'MovieOxdb'
+ db.delete_table('backend_movieoxdb')
+
# Deleting model 'Language'
db.delete_table('backend_language')
# Deleting model 'ReviewWhitelist'
db.delete_table('backend_reviewwhitelist')
+ # Deleting model 'Layer'
+ db.delete_table('backend_layer')
+
# Deleting model 'MovieSort'
db.delete_table('backend_moviesort')
@@ -404,6 +496,9 @@ class Migration:
# Deleting model 'Keyword'
db.delete_table('backend_keyword')
+ # Deleting model 'MovieImdb'
+ db.delete_table('backend_movieimdb')
+
# Deleting model 'List'
db.delete_table('backend_list')
@@ -463,7 +558,8 @@ class Migration:
},
'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']"}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'alternative_titles_all'", 'to': "orm['backend.Movie']"}),
'title': ('django.db.models.fields.TextField', [], {}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '1000'})
},
@@ -472,29 +568,32 @@ class Migration:
'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'}),
+ 'public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']"})
},
'backend.archivefile': {
- 'archive': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Archive']"}),
+ 'archive': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['backend.Archive']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.File']"}),
'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'}),
+ 'character': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cast_relation'", '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'}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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']"})
+ 'subject': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'connections_all'", 'to': "orm['backend.Movie']"})
},
'backend.country': {
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
@@ -503,6 +602,7 @@ class Migration:
},
'backend.file': {
'audio_codec': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', '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'}),
@@ -512,6 +612,7 @@ class Migration:
'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'}),
+ 'is_video': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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']"}),
@@ -523,16 +624,21 @@ class Migration:
'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'}),
+ 'stream128': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100'}),
+ 'stream320': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100'}),
+ 'stream640': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100'}),
'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'}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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'}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
@@ -541,6 +647,17 @@ class Migration:
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
+ 'backend.layer': {
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
+ 'time_in': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
+ 'time_out': ('django.db.models.fields.FloatField', [], {'default': '-1'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
'backend.list': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
@@ -566,84 +683,136 @@ class Migration:
'lng_center': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lng_ne': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'lng_sw': ('django.db.models.fields.FloatField', [], {'default': '0'}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'movies': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['backend.Movie']"}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
},
'backend.movie': {
- 'accessed': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'alternative_titles': ('fields.TupleField', [], {'default': '()'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True', 'blank': 'True'}),
'budget': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'cast': ('fields.TupleField', [], {'default': '()'}),
+ 'cinematographers': ('fields.TupleField', [], {'default': '()'}),
+ 'connections': ('fields.TupleField', [], {'default': '()'}),
+ 'countries': ('fields.TupleField', [], {'default': '()'}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
- 'duration': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
+ 'directors': ('fields.TupleField', [], {'default': '()'}),
+ 'editors': ('fields.TupleField', [], {'default': '()'}),
'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'}),
+ 'genres': ('fields.TupleField', [], {'default': '()'}),
'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'}),
+ 'imdb': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'movie'", 'unique': 'True', 'null': 'True', 'to': "orm['backend.MovieImdb']"}),
+ 'keywords': ('fields.TupleField', [], {'default': '()'}),
+ 'languages': ('fields.TupleField', [], {'default': '()'}),
+ 'locations': ('fields.TupleField', [], {'default': '()'}),
'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'}),
+ 'oxdb': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'movie'", 'unique': 'True', 'null': 'True', 'to': "orm['backend.MovieOxdb']"}),
'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'}),
+ 'producers': ('fields.TupleField', [], {'default': '()'}),
'profit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'rating': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
'release_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'reviews': ('fields.TupleField', [], {'default': '()'}),
'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'}),
+ 'stream128': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100'}),
+ 'stream320': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100'}),
+ 'stream640': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100'}),
'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'}),
+ 'trivia': ('fields.TupleField', [], {'default': '()'}),
'votes': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
- 'wikipedia_url': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'writers': ('fields.TupleField', [], {'default': '()'}),
'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'}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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'}),
+ 'cast': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'cinematographer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'country': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'director': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'editor': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'filename': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- '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'}),
+ 'language': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'locations': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'movie': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'find'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['backend.Movie']"}),
+ 'producer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
+ 'title': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'trivia': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
- 'writer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'writer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
+ },
+ 'backend.movieimdb': {
+ 'budget': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
+ 'episode_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1000', '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'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'plot': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'plot_outline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'profit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
+ 'release_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'runtime': ('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.CharField', [], {'default': "''", 'max_length': '1000', 'blank': 'True'}),
+ 'tagline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
+ 'votes': ('django.db.models.fields.IntegerField', [], {'null': 'True', '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']"}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
'movie': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {})
},
+ 'backend.movieoxdb': {
+ 'budget': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': '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'}),
+ 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'plot': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'plot_outline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'profit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'rating': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True'}),
+ 'release_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'runtime': ('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'}),
+ 'tagline': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
+ 'votes': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'year': ('django.db.models.fields.CharField', [], {'max_length': '4'})
+ },
'backend.moviesort': {
'aspectratio': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'bitrate': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
@@ -657,13 +826,13 @@ class Migration:
'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']"}),
+ 'movie': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'sort'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['backend.Movie']"}),
'movieId': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'pixels': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}),
'producer': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'rating': ('django.db.models.fields.FloatField', [], {'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'}),
@@ -672,6 +841,7 @@ class Migration:
'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'}),
+ 'votes': ('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'}),
@@ -686,7 +856,8 @@ class Migration:
},
'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']"}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reviews_all'", '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'})
},
@@ -697,16 +868,17 @@ class Migration:
},
'backend.subtitle': {
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subtitles'", 'to': "orm['backend.File']"}),
'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']"}),
+ 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'movie': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'trivia_all'", 'to': "orm['backend.Movie']"}),
'position': ('django.db.models.fields.IntegerField', [], {}),
'trivia': ('django.db.models.fields.TextField', [], {})
},
diff --git a/oxdb/backend/migrations/0002_extend_movies.py b/oxdb/backend/migrations/0002_extend_movies.py
deleted file mode 100644
index aa481eef5..000000000
--- a/oxdb/backend/migrations/0002_extend_movies.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# -*- 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']
diff --git a/oxdb/backend/models.py b/oxdb/backend/models.py
index 502e229a3..17a710d2a 100644
--- a/oxdb/backend/models.py
+++ b/oxdb/backend/models.py
@@ -7,13 +7,15 @@ import random
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
-import ox
-from ox import stripTags
-from ox.normalize import canonicalTitle, canonicalName
+from django.core.files.base import ContentFile
+import oxlib
+from oxlib import stripTags
+from oxlib.normalize import canonicalTitle, canonicalName
+from django.utils import simplejson as json
import utils
import managers
-
+import fields
class MovieImdb(models.Model):
created = models.DateTimeField(auto_now_add=True)
@@ -36,10 +38,13 @@ class MovieImdb(models.Model):
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='')
+ series_title = models.CharField(max_length=1000, blank=True, default='')
+ episode_title = models.CharField(max_length=1000, blank=True, default='')
season = models.IntegerField(default=-1)
episode = models.IntegerField(default=-1)
+
+ def __unicode__(self):
+ return u"%s (%s)" % (self.title, self.imdbId)
class MovieOxdb(models.Model):
created = models.DateTimeField(auto_now_add=True)
@@ -66,6 +71,9 @@ class MovieOxdb(models.Model):
season = models.IntegerField(default=-1)
episode = models.IntegerField(default=-1)
+ def __unicode__(self):
+ return u"%s (%s)" % (self.title, self.year)
+
def newMovie(title, director, year):
movie = Movie()
oxdb = MovieOxdb()
@@ -80,13 +88,18 @@ def newMovie(title, director, year):
movie.save()
return movie
+def movie_path(f, size):
+ name = "%s.%s" % (size, 'ogv')
+ url_hash = f.movieId
+ return os.path.join('movie', url_hash[:2], url_hash[2:4], url_hash[4:6], name)
+
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)
+ available = models.BooleanField(default=False, db_index=True)
movieId = models.CharField(max_length=128, unique=True, blank=True)
oxdbId = models.CharField(max_length=42, unique=True, blank=True)
@@ -139,9 +152,9 @@ class Movie(models.Model):
def keywords(self):
return self._manual(self.keywords_all)
def countries(self):
- return self._manual(self.countries_all, 'moviecountry__manual')
+ return self._manual(self.countries_all, 'moviecountry__manual').order_by('moviecountry__position')
def languages(self):
- return self._manual(self.languages_all, 'movielanguage__manual')
+ return self._manual(self.languages_all, 'movielanguage__manual').order_by('movielanguage__position')
def trivia(self):
return self._manual(self.trivia_all)
def locations(self):
@@ -169,12 +182,59 @@ class Movie(models.Model):
rights_level = models.IntegerField(default=-1)
+ '''
+ #these values get populated with imdb/oxdb values on save()
+ #edits will be overwritten
+ 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)
+ '''
+
+ json = fields.DictField(default={}, editable=False)
+
+ '''
+ directors = fields.TupleField(default=())
+ writers = fields.TupleField(default=())
+ editors = fields.TupleField(default=())
+ producers = fields.TupleField(default=())
+ cinematographers = fields.TupleField(default=())
+ cast = fields.TupleField(default=())
+ alternative_titles = fields.TupleField(default=())
+ genres = fields.TupleField(default=())
+ keywords = fields.TupleField(default=())
+ countries = fields.TupleField(default=())
+ languages = fields.TupleField(default=())
+ trivia = fields.TupleField(default=())
+ locations = fields.TupleField(default=())
+ connections = fields.DictField(default={})
+ reviews = fields.TupleField(default=())
+ '''
+
#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)
+ #FIXME: use data.0xdb.org/posters for that
#what of this is still required?
still_pos = models.IntegerField(null=True, blank=True)
poster = models.TextField(blank=True)
@@ -182,13 +242,20 @@ class Movie(models.Model):
posters_available = models.TextField(blank=True)
poster_height = models.IntegerField(null=True, blank=True)
poster_width = models.IntegerField(null=True, blank=True)
+ '''
+ #stream related fields
+ '''
+ '''
+ stream128 = models.FileField(default=None, blank=True, upload_to=lambda f, x: movie_path(f, '128'))
+ stream320 = models.FileField(default=None, blank=True, upload_to=lambda f, x: movie_path(f, '320'))
+ stream640 = models.FileField(default=None, blank=True, upload_to=lambda f, x: movie_path(f, '640'))
+ #FIXME: is this still required? should this not be aspect ratio? depends on stream???
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()
@@ -200,6 +267,26 @@ class Movie(models.Model):
mid = self.oxdbId
self.movieId = mid
+ if self.id:
+ self.json = self.get_json()
+ '''
+ #populate auto values for faster results
+ #FIXME: why is it not possible to use setattr to set List instead of db value?
+ common_fields = [f.name for f in MovieImdb._meta.fields]
+ only_relevant = lambda f: f not in ('id', 'created', 'modified', 'imdbId')
+ common_fields = filter(only_relevant, common_fields)
+ for f in common_fields:
+ setattr(self, f, self.get(f))
+ for f in ('directors', 'writers', 'editors', 'producers', 'cinematographers',
+ 'reviews', 'countries', 'languages',
+ 'keywords', 'genres', 'trivia', 'alternative_titles'):
+ value = getattr(self, 'get_' + f)
+ setattr(self, f, tuple([v.json() for v in value()]))
+ for f in ('cast', ):
+ value = getattr(self, 'get_' + f)
+ setattr(self, f, value())
+ self.connections = self.connections_json()
+ '''
super(Movie, self).save(*args, **kwargs)
self.updateFind()
self.updateSort()
@@ -229,7 +316,7 @@ class Movie(models.Model):
'alternative_titles': 'alternative_titles',
'connections_json': 'connections'
}
- def json(self, fields=None):
+ def get_json(self, fields=None):
movie = {}
for key in self._public_fields:
pub_key = self._public_fields.get(key, key)
@@ -238,8 +325,9 @@ class Movie(models.Model):
value = getattr(self, key)
else:
value = self.get(key)
- if key in ('directors', 'writers', 'reviews',
- 'countries', 'languages', 'keywords', 'genres', 'trivia', 'alternative_titles'):
+ if key in ('directors', 'writers', 'editors', 'cinematographers', 'producers',
+ '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()
@@ -392,7 +480,7 @@ class MovieFind(models.Model):
movie = models.OneToOneField('Movie', related_name='find', primary_key=True)
all = models.TextField(blank=True)
- title = models.CharField(max_length=1000)
+ title = models.TextField(blank=True)
director = models.TextField(blank=True, default='')
country = models.TextField(blank=True, default='')
year = models.CharField(max_length=4)
@@ -414,18 +502,17 @@ class MovieFind(models.Model):
filename = models.TextField(blank=True, default='')
_private_fields = ('id', 'movie')
- _public_names = {
- 'movieId': 'id'
- }
- def options(self):
- options = []
+ #return available find fields
+ #FIXME: should return mapping name -> verbose_name
+ def fields(self):
+ fields = []
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)
+ name = f.verbose_name
+ name = name[0].capitalize() + name[1:]
+ fields.append(name)
+ return tuple(fields)
+ fields = classmethod(fields)
class MovieSort(models.Model):
"""
@@ -457,14 +544,14 @@ class MovieSort(models.Model):
votes = models.IntegerField(blank=True)
scenes = models.IntegerField(blank=True)
words = models.IntegerField(null=True, blank=True)
- wpm = models.IntegerField(null=True, blank=True)
+ wpm = models.IntegerField('Words per Minute', null=True, blank=True)
risk = models.IntegerField(null=True, blank=True)
- movieId = models.CharField(max_length=128, blank=True)
+ movieId = models.CharField('ID', max_length=128, blank=True)
duration = models.FloatField(default=-1)
resolution = models.IntegerField(blank=True)
- aspectratio = models.IntegerField(blank=True)
+ aspectratio = models.IntegerField('Aspect Ratio', blank=True)
bitrate = models.IntegerField(blank=True)
pixels = models.IntegerField(blank=True)
filename = models.IntegerField(blank=True)
@@ -472,18 +559,17 @@ class MovieSort(models.Model):
size = models.IntegerField(blank=True)
_private_fields = ('id', 'movie')
- _public_names = {
- 'movieId': 'id'
- }
- def options(self):
- options = []
+ #return available sort fields
+ #FIXME: should return mapping name -> verbose_name
+ def fields(self):
+ fields = []
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)
+ name = f.verbose_name
+ name = name[0].capitalize() + name[1:]
+ fields.append(name)
+ return tuple(fields)
+ fields = classmethod(fields)
class AlternativeTitle(models.Model):
movie = models.ForeignKey(Movie, related_name='alternative_titles_all')
@@ -522,7 +608,7 @@ class Person(models.Model):
def save(self, *args, **kwargs):
if not self.name_sort:
- self.name_sort = ox.normalize.canonicalName(self.name)
+ self.name_sort = oxlib.normalize.canonicalName(self.name)
super(Person, self).save(*args, **kwargs)
def get_or_create(model, name, imdbId=None):
@@ -544,10 +630,10 @@ class Person(models.Model):
return self.name
class Cast(models.Model):
- movie = models.ForeignKey(Movie)
+ movie = models.ForeignKey(Movie, related_name='cast_relation')
person = models.ForeignKey(Person)
role = models.CharField(max_length=200)
- character = models.CharField(max_length=200, blank=True)
+ character = models.CharField(max_length=1000, blank=True)
position = models.IntegerField()
manual = models.BooleanField(default=False)
@@ -736,7 +822,8 @@ class Trivia(models.Model):
def json(self):
trivia = self.trivia
- trivia = ox.fixAmpersands(trivia)
+ trivia = oxlib.fixAmpersands(trivia)
+ trivia = re.sub(' ', '', trivia)
trivia = re.sub('(.*?)', '\\2', trivia)
trivia = re.sub('(.*?)', '\\2', trivia)
return trivia
@@ -764,6 +851,7 @@ class Connection(models.Model):
'Spin off from': 'Spin off',
'Spoofs': 'Spoofed in',
'Version of': 'Version of',
+ 'Alternate language version of': 'Alternate language version of',
}
if relation in _map.values():
for k in _map:
@@ -846,22 +934,37 @@ def stream_path(f, size):
url_hash = f.oshash
return os.path.join('stream', url_hash[:2], url_hash[2:4], url_hash[4:6], name)
+def still_path(f, still):
+ name = "%s.%s" % (still, 'png')
+ url_hash = f.oshash
+ return os.path.join('still', url_hash[:2], url_hash[2:4], url_hash[4:6], name)
+
+FILE_TYPES = (
+ (0, 'unknown'),
+ (1, 'video'),
+ (2, 'audio'),
+ (3, 'subtitle'),
+)
+
class File(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
+ verified = models.BooleanField(default=False)
oshash = models.CharField(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)
+ sha1 = models.CharField(blank=True, null=True, unique=True, max_length=40)
+ md5 = models.CharField(blank=True, null=True, unique=True, max_length=32)
- movie = models.ForeignKey(Movie, related_name="files", default=None)
+ movie = models.ForeignKey(Movie, related_name="files", default=None, null=True)
- computed_path = models.CharField(blank=True, max_length=2048)
- size = models.IntegerField(default=-1)
+ type = models.IntegerField(default=0, choices=FILE_TYPES)
+ info = fields.DictField(default={})
+ #FIMXE: why do i need those in the db? could jsut have them in info
+
+ path = models.CharField(blank=True, max_length=2048)
+ size = models.BigIntegerField(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)
@@ -876,16 +979,20 @@ class File(models.Model):
#computed values
bpp = models.FloatField(default=-1)
- pixels = models.IntegerField(default=0)
+ pixels = models.BigIntegerField(default=0)
part = models.IntegerField(default=0)
+ needs_data = models.BooleanField(default=True)
+
#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'))
+ timeline = models.ImageField(default=None, null=True, upload_to=lambda f, x: still_path(f, '0'))
+
def save_chunk(self, chunk, name='video.ogv'):
if not self.available:
#FIXME: this should use stream128 or stream640 depending on configuration
@@ -912,7 +1019,56 @@ class File(models.Model):
get_or_create = classmethod(get_or_create)
def __unicode__(self):
- return "%s (%s)" % (self.computed_path, self.oshash)
+ return "%s (%s)" % (self.path, self.oshash)
+
+ def update(self, data=None):
+ """
+ only add, do not overwrite keys in file
+ """
+ if data and not self.info:
+ self.info = data
+ _video_map = {
+ 'codec': 'video_codec',
+ }
+ if 'video' in self.info and self.info['video']:
+ for key in ('codec', 'pixel_format', 'width', 'height',
+ 'pixel_aspect_ratio', 'display_aspect_ratio', 'framerate'):
+ if key in self.info['video'][0]:
+ setattr(self, _video_map.get(key, key), self.info['video'][0][key])
+ _audio_map = {
+ 'codec': 'audio_codec',
+ }
+ if 'audio' in self.info and self.info['audio']:
+ for key in ('codec', 'samplerate', 'channels'):
+ if key in self.info['audio'][0]:
+ setattr(self, _audio_map.get(key, key), self.info['audio'][0][key])
+
+ for key in ('duration', 'size', 'sha1', 'md5'):
+ if key in self.info:
+ setattr(self, key, self.info[key])
+
+ #detect and assign type based on extension or detected video track
+ if os.path.splitext(self.info['path'])[-1] in ('.rar', '.sub', '.idx'):
+ self.type = 0
+ elif 'video' in self.info:
+ self.type = 1
+ elif os.path.splitext(self.info['path'])[-1] in ('.mp3', '.oga'):
+ self.type = 2
+ elif os.path.splitext(self.info['path'])[-1] in ('.srt', ):
+ self.type = 3
+ #FIXME: this should be computed and not submitted path
+ self.path = self.info['path']
+ self.save()
+
+class Still(models.Model):
+ created = models.DateTimeField(auto_now_add=True)
+ modified = models.DateTimeField(auto_now=True)
+ file = models.ForeignKey(File, related_name="stills")
+ position = models.FloatField()
+ still = models.ImageField(default=None, null=True, upload_to=lambda f, x: still_path(f, '0'))
+
+ def __unicode__(self):
+ return '%s at %s' % (self.file, self.position)
class Subtitle(models.Model):
created = models.DateTimeField(auto_now_add=True)
@@ -935,7 +1091,7 @@ class Subtitle(models.Model):
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)
+ return '%s.%s.srt' % (os.path.splitext(self.movie_file.path)[0], self.language)
class Layer(models.Model):
created = models.DateTimeField(auto_now_add=True)
@@ -958,6 +1114,9 @@ class Archive(models.Model):
name = models.CharField(max_length=255, unique=True)
public = models.BooleanField(default=False)
users = models.ManyToManyField(User, related_name='archives')
+
+ def __unicode__(self):
+ return '%s' % (self.name)
class ArchiveFile(models.Model):
created = models.DateTimeField(auto_now_add=True)
@@ -967,32 +1126,27 @@ class ArchiveFile(models.Model):
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.file.update(data)
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
+ file = File.get_or_create(oshash)
+ file.save()
+ f = model.objects.create(archive=archive, file=file)
f.save()
return f
get_or_create = classmethod(get_or_create)
def __unicode__(self):
- return '%s (%s)' % (self.path, unicode(self.user))
+ return '%s (%s)' % (self.path, unicode(self.archive))
diff --git a/oxdb/backend/urls.py b/oxdb/backend/urls.py
index f738b46bf..ea0b31e6a 100644
--- a/oxdb/backend/urls.py
+++ b/oxdb/backend/urls.py
@@ -20,12 +20,11 @@ subtitles/add?oshash&language
subtitles/remove?oshash&language
'''
-urlpatterns = patterns("oxdb.backend.views",
+urlpatterns = patterns("backend.views",
(r'^find', 'find'),
(r'^files/find', 'find_files'),
(r'^files/info', 'file_info'),
- (r'^archive/(?P.+)/add', 'add_file'),
- (r'^archive/(?P.+)/remove', 'remove_file'),
+ (r'^archive/(?P.+)/update', 'update_archive'),
(r'^file/parse', 'file_parse'),
(r'^subtitle/get', 'subtitles'),
diff --git a/oxdb/backend/utils.py b/oxdb/backend/utils.py
index 0602d6564..25f2a9c4c 100644
--- a/oxdb/backend/utils.py
+++ b/oxdb/backend/utils.py
@@ -8,9 +8,9 @@ import sys
import re
import hashlib
-import ox
-import ox.iso
-from ox.normalize import normalizeName
+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])
@@ -62,7 +62,7 @@ def oxdb_title(_title, searchTitle = False):
return title
def oxdb_year(data):
- return ox.findRe(data, '\.(\d{4})\.')
+ return oxlib.findRe(data, '\.(\d{4})\.')
def oxdb_series_title(path):
seriesTitle = u''
diff --git a/oxdb/backend/views.py b/oxdb/backend/views.py
index 618db48d3..a9c3e9646 100644
--- a/oxdb/backend/views.py
+++ b/oxdb/backend/views.py
@@ -4,16 +4,22 @@ import os.path
import re
from datetime import datetime
from urllib2 import unquote
+import json
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.http import HttpResponse
from django.contrib.auth.decorators import login_required
-from django.utils import simplejson as json
-from ox.django.shortcuts import render_to_json_response
-from ox.django.decorators import login_required_json
+try:
+ import simplejson as json
+except ImportError:
+ from django.utils import simplejson as json
+from oxdjango.shortcuts import render_to_json_response
+from oxdjango.decorators import login_required_json
+
import models
import utils
@@ -168,13 +174,18 @@ def find(request):
if 'n' in query:
response = {'items': qs.count()}
else:
+ _p = query['p']
+ def only_p(m):
+ r = {}
+ if m:
+ m = json.loads(m)
+ for p in _p:
+ r[p] = m[p]
+ return r
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']))
+
+ response['items'] = [only_p(m['json']) for m in qs.values('json')]
+
elif 'g' in query:
if query['s'].split(':')[0] not in ('name', 'items'):
query['s'] = 'name'
@@ -207,9 +218,9 @@ def find(request):
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)
+
+ response['items'] = [{'title': i[name], 'items': i[items]} for i in qs]
+
else:
#FIXME: also filter lists here
movies = models.Movie.objects.filter(available=True)
@@ -225,23 +236,15 @@ def find(request):
'''
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
+ "movie_id": 0123456, ??
"oshash": "a41cde31c581e11d",
"sha1":..,
"md5":..
+ "duration": 5.266667,
+ "video": [],
+ "audio": [],
+ "path": "E/Example, The/An Example.avi",
+ "size": 1646274
}
'''
def file_info(request):
@@ -264,7 +267,7 @@ srt =
def subtitles(request):
oshash = request.GET['oshash']
language = request.GET.get('language', None)
- if requeset.method == 'POST':
+ if request.method == 'POST':
user = request.user
sub = models.Subtitles.get_or_create(user, oshash, language)
sub.srt = request.POST['srt']
@@ -289,6 +292,7 @@ GET list
'''
@login_required_json
def list_files(request):
+ response = {}
response['files'] = {}
qs = models.UserFile.filter(user=request.user)
p = Paginator(qs, 1000)
@@ -299,9 +303,10 @@ def list_files(request):
return render_to_json_response(response)
def find_files(request):
+ response = {}
query = parse_query(request)
response['files'] = {}
- qs = models.UserFile.filter(user=request.user).filter(movie_file__movie__id__in=quert['q'])
+ qs = models.UserFile.filter(user=request.user).filter(movie_file__movie__id__in=query['q'])
p = Paginator(qs, 1000)
for i in p.page_range:
page = p.page(i)
@@ -310,7 +315,7 @@ def find_files(request):
return render_to_json_response(response)
'''
-POST add
+POST metadata
> file: {
"duration": 5.266667,
"video_codec": "mpeg1",
@@ -331,8 +336,7 @@ POST add
}
'''
#@login_required_json
-def add_file(request, archive):
- print request.POST
+def add_metadata(request, archive):
info = json.loads(request.POST['file'])
oshash = info['oshash']
archive = models.Archive.objects.get(name=archive)
@@ -344,15 +348,99 @@ def add_file(request, archive):
response = {'status': 404}
return render_to_json_response(response)
+class StillForm(forms.Form):
+ still = forms.FileField()
+ position = forms.FloatField()
+
+#@login_required_json
+def add_still(request, oshash):
+ response = {'status': 500}
+ f = get_object_or_404(models.File, oshash=oshash)
+
+ form = TimelineForm(request.POST, request.FILES)
+ if form.is_valid():
+ ff = form.cleaned_data['still']
+ position = form.cleaned_data['position']
+
+ still = models.Still(file=f, position=position)
+ still.save()
+ still.still.save(ff, ff.name)
+ response = {'status': 200}
+ response['url'] = still.url()
+ return render_to_json_response(response)
+
+class TimelineForm(forms.Form):
+ timeline = forms.FileField()
+
+#FIXME: should everybody be able to overwrite timelines?
+#@login_required_json
+def add_timeline(request, oshash):
+ response = {'status': 500}
+ f = get_object_or_404(models.File, oshash=oshash)
+
+ form = TimelineForm(request.POST, request.FILES)
+ if form.is_valid():
+ ff = form.cleaned_data['timeline']
+ f.timeline.save(ff.name, ff)
+ response = {'status': 200}
+ response['url'] = f.timeline.url()
+ return render_to_json_response(response)
+
+
+class VideoForm(forms.Form):
+ video = forms.FileField()
+
+#@login_required_json
+def add_video(request, oshash):
+ response = {'status': 500}
+ f = get_object_or_404(models.File, oshash=oshash)
+
+ form = VideoForm(request.POST, request.FILES)
+ if form.is_valid():
+ ff = form.cleaned_data['video']
+ f.stream128.save(ff.name, ff)
+ response = {'status': 200}
+ response['url'] = f.stream128.url()
+ return render_to_json_response(response)
+
'''
-POST remove?oshash=
+POST update
+ > files: {
+ oshash: { 'path': .., ..},
+ oshash: { 'path': .., ..},
+ }
'''
-@login_required_json
-def remove_file(request, archive):
- oshash = request.POST['oshash']
+#@login_required_json
+def update_archive(request, archive):
+ print "update request"
archive = models.Archive.objects.get(name=archive)
- models.UserFiles.objects.filter(movie_file__oshash=oshash, user=request.user).delete()
- response = {'status': 200}
+ files = json.loads(request.POST['files'])
+ print "update request for", archive.name
+ needs_data = []
+ rename = {}
+ for oshash in files:
+ print 'checking', oshash
+ data = files[oshash]
+ q = models.ArchiveFile.objects.filter(archive=archive, file__oshash=oshash)
+ if q.count() == 0:
+ print "adding file", oshash, data['path']
+ f = models.ArchiveFile.get_or_create(archive, oshash)
+ f.update(data)
+ #FIXME: only add if it was not in File
+ else:
+ f = q[0]
+ if data['path'] != f.path:
+ f.path = data['path']
+ f.save()
+ if f.file.needs_data:
+ needs_data.append(oshash)
+ if f.path != f.file.path:
+ rename[oshash] = f.file.path
+ print "processed files for", archive.name
+ #remove all files not in files.keys() from ArchiveFile
+ response = {}
+ response['info'] = needs_data
+ response['rename'] = rename
return render_to_json_response(response)
def file_parse(request):
diff --git a/oxdb/settings.py b/oxdb/settings.py
index 9d7249bb3..a4ca7bec6 100644
--- a/oxdb/settings.py
+++ b/oxdb/settings.py
@@ -52,6 +52,8 @@ TESTS_ROOT = join(PROJECT_ROOT, 'tests')
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''
+STATIC_URL = '/static/'
+
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
@@ -61,7 +63,7 @@ ADMIN_MEDIA_PREFIX = '/admin/media/'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
-# 'django.template.loaders.eggs.load_template_source',
+ 'django.template.loaders.eggs.load_template_source',
)
MIDDLEWARE_CLASSES = (
@@ -88,6 +90,14 @@ INSTALLED_APPS = (
'backend',
)
+#rabbitmq connection settings
+BROKER_HOST = "127.0.0.1"
+BROKER_PORT = 5672
+BROKER_USER = "oxdb"
+BROKER_PASSWORD = "0xdb"
+BROKER_VHOST = "/oxdb"
+
+
#overwrite default settings with local settings
try:
from local_settings import *
diff --git a/oxdb/static/js/ajax_filtered_fields.js b/oxdb/static/js/ajax_filtered_fields.js
new file mode 100644
index 000000000..887348daf
--- /dev/null
+++ b/oxdb/static/js/ajax_filtered_fields.js
@@ -0,0 +1,91 @@
+ajax_filtered_fields = {
+
+ request_url: "/ajax_filtered_fields/json_index/",
+ data_loaded: "data_loaded",
+
+ _appendOption: function(obj, selector) {
+ // append a json data row as an option to the selector
+ var option = $('');
+ option.attr({value: obj[0]});
+ option.appendTo(selector);
+ return option;
+ },
+
+ _removeOptions: function(selector) {
+ // remove all options from selector
+ selector.children("option").each(function(i) {
+ $(this).remove();
+ });
+ },
+
+ getManyToManyJSON: function(element_id, app_label, object_name,
+ lookup_string, select_related) {
+ // manage the ManyToMany ajax request
+ var selector_from = $("#" + element_id + "_from");
+ var selector_to = $("#" + element_id + "_to");
+
+ $("#" + element_id + "_input").val("");
+ selector_from.attr("disabled", true);
+ selector_to.attr("disabled", true);
+
+ this._removeOptions(selector_from);
+
+ $.getJSON(this.request_url, {
+ app_label: app_label,
+ object_name: object_name,
+ lookup_string: lookup_string,
+ select_related: select_related},
+ function(data){
+ $.each(data, function(i, obj){
+ var option_is_selected = selector_to.children("option[value='" + obj[0] + "']").length;
+ if (!option_is_selected) {
+ ajax_filtered_fields._appendOption(obj, selector_from);
+ };
+ });
+ SelectBox.init(element_id + "_from");
+ selector_from.attr("disabled", false);
+ selector_to.attr("disabled", false);
+ selector_from.trigger(ajax_filtered_fields.data_loaded);
+ });
+ },
+
+ getForeignKeyJSON: function(element_id, app_label, object_name,
+ lookup_string, select_related) {
+ // manage the ForeignKey ajax request
+ var selector = $("#" + element_id);
+ var hidden = $("#hidden-" + element_id);
+
+ $("#" + element_id + "_input").val("");
+ selector.attr("disabled", true);
+
+ this._removeOptions(selector);
+
+ $.getJSON(this.request_url, {
+ app_label: app_label,
+ object_name: object_name,
+ lookup_string: lookup_string,
+ select_related: select_related},
+ function(data){
+ var selection = hidden.val();
+ ajax_filtered_fields._appendOption(new Array("", "---------"), selector);
+ $.each(data, function(i, obj){
+ ajax_filtered_fields._appendOption(obj, selector);
+ });
+ selector.children("option[value='" + selection + "']").attr("selected", "selected");
+ selector.attr("disabled", false);
+ SelectBox.init(element_id);
+ ajax_filtered_fields.bindForeignKeyOptions(element_id);
+ selector.trigger(ajax_filtered_fields.data_loaded);
+ });
+ },
+
+ bindForeignKeyOptions: function(element_id) {
+ // bind the dummy options to the hidden field that do the work
+ var selector = $("#" + element_id);
+ var hidden = $("#hidden-" + element_id);
+ selector.change(function(e) {
+ hidden.val($(this).val());
+ });
+ }
+
+};
diff --git a/oxdb/static/js/ui.js b/oxdb/static/js/ui.js
index e782515d9..1990a669c 100644
--- a/oxdb/static/js/ui.js
+++ b/oxdb/static/js/ui.js
@@ -568,7 +568,7 @@ $(function() {
items.push({
size: 64,
id: code,
- icon: "http://oil21.org/tmp/flags/" + flag + ".png",
+ icon: "http://localhost/oxdbstatic/flags/" + flag + ".png",
title: strings[0] + (strings.length > 1 ? "
" + strings[1] : ""),
info: Ox.formatNumber(v.items) + " Movie" + (v.items > 1 ? "s" : "")
});
diff --git a/oxdb/urls.py b/oxdb/urls.py
index 810f5c2dc..d9685075e 100644
--- a/oxdb/urls.py
+++ b/oxdb/urls.py
@@ -9,6 +9,7 @@ admin.autodiscover()
urlpatterns = patterns('',
# Example:
+ (r'^ajax_filtered_fields/', include('ajax_filtered_fields.urls')),
(r'^json/', include('backend.urls')),
(r'^$', 'app.views.index'),
diff --git a/oxdb/user_management/views.py b/oxdb/user_management/views.py
index 689363a98..c3da9bf86 100644
--- a/oxdb/user_management/views.py
+++ b/oxdb/user_management/views.py
@@ -6,8 +6,8 @@ from django.shortcuts import render_to_response, get_object_or_404, get_list_or_
from django.template import RequestContext
from django.utils import simplejson as json
-from ox.django.shortcuts import render_to_json_response
-from ox.django.decorators import login_required_json
+from oxdjango.shortcuts import render_to_json_response
+from oxdjango.decorators import login_required_json
import models
@@ -51,7 +51,7 @@ def recover(request):
if q.count() > 0:
user = q[0]
if user:
- user.sendmail(...) #FIXME: send recovery mail
+ #user.sendmail(...) #FIXME: send recovery mail
response = {'status': 200, 'message': 'recovert email sent.'}
else:
response = {'status': 500, 'message': 'user or email not found.'}
@@ -80,7 +80,7 @@ def preferences(request):
if key == 'password':
user.set_password(value)
user.save()
- elsif key == 'email':
+ elif key == 'email':
user.email = vaule
user.save()
else: