diff --git a/pandora/archive/admin.py b/pandora/archive/admin.py index 66cd6979..8526e00a 100644 --- a/pandora/archive/admin.py +++ b/pandora/archive/admin.py @@ -3,7 +3,7 @@ from django.contrib import admin -#from forms import FileAdminForm, MovieAdminForm, ArchiveFileAdminForm +#from forms import FileAdminForm, ItemAdminForm, ArchiveFileAdminForm import models class FileAdmin(admin.ModelAdmin): diff --git a/pandora/archive/extract.py b/pandora/archive/extract.py index 5006ae62..43703b86 100644 --- a/pandora/archive/extract.py +++ b/pandora/archive/extract.py @@ -326,7 +326,7 @@ def divide(num, by): arr.append(div + (i > by - 1 - mod)) return arr -def timeline_strip(movie, cuts, info, prefix): +def timeline_strip(item, cuts, info, prefix): _debug = False duration = info['duration'] video_height = info['video'][0]['height'] @@ -353,29 +353,29 @@ def timeline_strip(movie, cuts, info, prefix): c = cuts.index(frame) if c +1 < len(cuts): duration = cuts[c + 1] - cuts[c] - stills = math.ceil(duration / (video_width * timeline_height / video_height)) - widths = divide(duration, stills) - still = frame + frames = math.ceil(duration / (video_width * timeline_height / video_height)) + widths = divide(duration, frames) + frame = frame if _debug: - print widths, duration, stills, cuts[c], cuts[c + 1] - for s in range(int(stills)): - still_ratio = widths[s] / timeline_height - if video_ratio > still_ratio: - width = int(round(video_height * still_ratio)) + print widths, duration, frames, cuts[c], cuts[c + 1] + for s in range(int(frames)): + frame_ratio = widths[s] / timeline_height + if video_ratio > frame_ratio: + width = int(round(video_height * frame_ratio)) left = int((video_width - width) / 2) box = (left, 0, left + width, video_height) else: - height = int(round(video_width / still_ratio)) + height = int(round(video_width / frame_ratio)) top = int((video_height - height) / 2) box = (0, top, video_width, top + height) if _debug: - print frame, 'cut', c, 'still', s, still, 'width', widths[s], box - #FIXME: why does this have to be still+1? - frame_image = Image.open(movie.frame((still+1)/fps)) + print frame, 'cut', c, 'frame', s, frame, 'width', widths[s], box + #FIXME: why does this have to be frame+1? + frame_image = Image.open(item.frame((frame+1)/fps)) frame_image = frame_image.crop(box).resize((widths[s], timeline_height), Image.ANTIALIAS) for x_ in range(widths[s]): line_image.append(frame_image.crop((x_, 0, x_ + 1, timeline_height))) - still += widths[s] + frame += widths[s] if len(line_image) > frame: timeline_image.paste(line_image[frame], (x, 0)) if x == timeline_width - 1: diff --git a/pandora/archive/migrations/0009_rename_movie.py b/pandora/archive/migrations/0009_rename_movie.py new file mode 100644 index 00000000..f0222ffe --- /dev/null +++ b/pandora/archive/migrations/0009_rename_movie.py @@ -0,0 +1,146 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + db.rename_column('archive_file', 'movie_id', 'item_id') + + + def backwards(self, orm): + + db.rename_column('archive_file', 'item_id', 'movie_id') + + + models = { + 'archive.file': { + 'Meta': {'object_name': 'File'}, + 'audio_codec': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'bits_per_pixel': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'channels': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'data': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'display_aspect_ratio': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'duration': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'episode': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'framerate': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'info': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'is_audio': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_extra': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_main': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_subtitle': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_version': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_video': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['backend.Item']"}), + 'language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '8'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}), + 'oshash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '16'}), + 'part': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'pixel_format': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'pixels': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'samplerate': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'season': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'sort_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}), + 'verified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'version': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}), + 'video': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'video_codec': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'width': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + 'archive.fileinstance': { + 'Meta': {'unique_together': "(('name', 'folder', 'volume'),)", 'object_name': 'FileInstance'}, + 'atime': ('django.db.models.fields.IntegerField', [], {'default': '1285254686'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'ctime': ('django.db.models.fields.IntegerField', [], {'default': '1285254686'}), + 'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'instances'", 'to': "orm['archive.File']"}), + 'folder': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'mtime': ('django.db.models.fields.IntegerField', [], {'default': '1285254686'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '2048'}), + 'volume': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'files'", 'to': "orm['archive.Volume']"}) + }, + 'archive.frame': { + 'Meta': {'unique_together': "(('file', 'position'),)", 'object_name': 'Frame'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'file': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'frames'", 'to': "orm['archive.File']"}), + 'frame': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'position': ('django.db.models.fields.FloatField', [], {}) + }, + 'archive.volume': { + 'Meta': {'unique_together': "(('user', 'name'),)", 'object_name': 'Volume'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'volumes'", 'to': "orm['auth.User']"}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + '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': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'backend.item': { + 'Meta': {'object_name': 'Item'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'imdb': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'itemId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}), + 'json': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'metadata': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}), + 'poster': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}), + 'poster_frame': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'poster_url': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'stream_aspect': ('django.db.models.fields.FloatField', [], {'default': '1.3333333333333333'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['archive'] diff --git a/pandora/archive/models.py b/pandora/archive/models.py index 7633e089..abe142ed 100644 --- a/pandora/archive/models.py +++ b/pandora/archive/models.py @@ -23,7 +23,7 @@ from firefogg import Firefogg import chardet from backend import utils -from pandora.backend.models import Movie +from pandora.backend.models import Item import extract @@ -46,7 +46,7 @@ class File(models.Model): verified = models.BooleanField(default=False) oshash = models.CharField(max_length=16, unique=True) - movie = models.ForeignKey(Movie, related_name='files') + item = models.ForeignKey(Item, related_name='files') name = models.CharField(max_length=2048, default="") # canoncial path/file sort_name = models.CharField(max_length=2048, default="") # sort path/file name @@ -260,8 +260,8 @@ class FileInstance(models.Model): return u"%s's %s <%s>"% (self.volume.user, self.name, self.file.oshash) @property - def movieId(self): - return File.objects.get(oshash=self.oshash).movieId + def itemId(self): + return File.objects.get(oshash=self.oshash).itemId def frame_path(frame, name): ext = os.path.splitext(name)[-1] diff --git a/pandora/archive/views.py b/pandora/archive/views.py index 3d9c16f4..88126020 100644 --- a/pandora/archive/views.py +++ b/pandora/archive/views.py @@ -56,7 +56,7 @@ def api_update(request): param data volume: '', files: [ - {oshash:, path:, ctime:, atime:, mtime:, } + {oshash:, path:, mtime:, } ] info: {oshash: object} @@ -88,9 +88,9 @@ def api_update(request): same_folder = models.FileInstance.objects.filter(folder=folder, volume=volume) if same_folder.count() > 0: - movie = same_folder[0].file.movie + item = same_folder[0].file.item else: - movie = None + item = None path = os.path.join(folder, name) @@ -98,7 +98,7 @@ def api_update(request): if instance.count()>0: instance = instance[0] updated = False - for key in ('atime', 'mtime', 'ctime', 'name', 'folder'): + for key in ('mtime', 'name', 'folder'): if f[key] != getattr(instance, key): setattr(instance, key, f[key]) updated=True @@ -111,24 +111,24 @@ def api_update(request): file_object = file_objects[0] #new oshash, add to database else: - if not movie: - movie_info = parse_path(folder) - movie = backend.models.getMovie(movie_info) + if not item: + item_info = parse_path(folder) + item = backend.models.getItem(item_info) file_object = models.File() file_object.oshash = oshash file_object.name = name - file_object.movie = movie + file_object.item = item file_object.save() response['data']['info'].append(oshash) instance = models.FileInstance() instance.volume = volume instance.file = file_object - for key in ('atime', 'mtime', 'ctime', 'name', 'folder'): + for key in ('mtime', 'name', 'folder'): setattr(instance, key, f[key]) instance.save() #remove deleted files - #FIXME: can this have any bad consequences? i.e. on the selction of used movie files. + #FIXME: can this have any bad consequences? i.e. on the selction of used item files. models.FileInstance.objects.filter(volume=volume).exclude(file__oshash__in=all_files).delete() user_profile = user.get_profile() @@ -255,7 +255,7 @@ def api_editFile(request): #FIXME: should this be file.files. or part of update def lookup_file(request, oshash): f = get_object_or_404(models.File, oshash=oshash) - return redirect(f.movie.get_absolute_url()) + return redirect(f.item.get_absolute_url()) """ @@ -270,7 +270,7 @@ def api_fileInfo(request): oshash = json.loads(request.POST['data']) elif 'oshash' in request.GET: oshash = request.GET['oshash'] - f = models.MovieFile.objects.get(oshash=oshash) + f = models.ItemFile.objects.get(oshash=oshash) response = {'data': f.json()} return render_to_json_response(response) @@ -301,11 +301,11 @@ def api_subtitles(request): else: response = json_response({}) if language: - q = models.Subtitles.objects.filter(movie_file__oshash=oshash, language=language) + q = models.Subtitles.objects.filter(item_file__oshash=oshash, language=language) if q.count() > 0: response['data']['subtitle'] = q[0].srt return render_to_json_response(response) - l = models.Subtitles.objects.filter(movie_file__oshash=oshash).values('language') + l = models.Subtitles.objects.filter(item_file__oshash=oshash).values('language') response['data']['languages'] = [f['language'] for f in l] return render_to_json_response(response) """ diff --git a/pandora/backend/admin.py b/pandora/backend/admin.py index e9193531..6dda3a08 100644 --- a/pandora/backend/admin.py +++ b/pandora/backend/admin.py @@ -3,27 +3,27 @@ from django.contrib import admin -#from forms import FileAdminForm, MovieAdminForm, ArchiveFileAdminForm +#from forms import FileAdminForm, ItemAdminForm, ArchiveFileAdminForm import models ''' -#class MovieImdbAdmin(admin.ModelAdmin): +#class ItemImdbAdmin(admin.ModelAdmin): # search_fields = ['imdbId', 'title'] -#admin.site.register(models.MovieImdb, MovieImdbAdmin) -class MovieImdbInline(admin.StackedInline): - model = models.MovieImdb +#admin.site.register(models.ItemImdb, ItemImdbAdmin) +class ItemImdbInline(admin.StackedInline): + model = models.ItemImdb -class MovieOxdbInline(admin.StackedInline): - model = models.MovieOxdb +class ItemOxdbInline(admin.StackedInline): + model = models.ItemOxdb ''' -class MovieAdmin(admin.ModelAdmin): - search_fields = ['movieId', 'imdb__title', 'oxdb__title'] - #form = MovieAdminForm - #inlines = [MovieImdbInline, MovieOxdbInline] +class ItemAdmin(admin.ModelAdmin): + search_fields = ['itemId', 'imdb__title', 'oxdb__title'] + #form = ItemAdminForm + #inlines = [ItemImdbInline, ItemOxdbInline] -admin.site.register(models.Movie, MovieAdmin) +admin.site.register(models.Item, ItemAdmin) diff --git a/pandora/backend/forms.py b/pandora/backend/forms.py index dd2c5509..8ebefe94 100644 --- a/pandora/backend/forms.py +++ b/pandora/backend/forms.py @@ -12,7 +12,7 @@ ajax_filtered_js = ( ) """ class FileAdminForm(forms.ModelForm): - movie = ForeignKeyByLetter(models.Movie, field_name='imdb__title') + item = ForeignKeyByLetter(models.Item, field_name='imdb__title') class Meta: model = models.File @@ -30,12 +30,12 @@ class ArchiveFileAdminForm(forms.ModelForm): js = ajax_filtered_js -class MovieAdminForm(forms.ModelForm): - imdb = ForeignKeyByLetter(models.MovieImdb, field_name='title') - oxdb = ForeignKeyByLetter(models.MovieOxdb, field_name='title') +class ItemAdminForm(forms.ModelForm): + imdb = ForeignKeyByLetter(models.ItemImdb, field_name='title') + oxdb = ForeignKeyByLetter(models.ItemOxdb, field_name='title') class Meta: - model = models.Movie + model = models.Item class Media: js = ajax_filtered_js diff --git a/pandora/backend/load.py b/pandora/backend/load.py index 0154d2f3..4715a0bc 100644 --- a/pandora/backend/load.py +++ b/pandora/backend/load.py @@ -19,7 +19,7 @@ def debug(*msgs): '''Import data from imdb into database, param: impdb id - return: Movie Object, None if failed + return: Item Object, None if failed ''' def loadIMDb(imdbId): @@ -27,17 +27,17 @@ def loadIMDb(imdbId): debug("IMDb ID not valid") return None try: - movie = models.Movie.byImdbId(imdbId) - except models.Movie.DoesNotExist: + item = models.Item.byImdbId(imdbId) + except models.Item.DoesNotExist: #this shound not happen, just in case previous imports failed try: - imdb = models.MovieImdb.objects.get(imdbId=imdbId) - except models.MovieImdb.DoesNotExist: - imdb = models.MovieImdb() + imdb = models.ItemImdb.objects.get(imdbId=imdbId) + except models.ItemImdb.DoesNotExist: + imdb = models.ItemImdb() imdb.imdbId = imdbId imdb.save() - movie = models.Movie() - movie.imdb = imdb + item = models.Item() + item.imdb = imdb info = ox.web.imdb.getMovieInfo(imdbId) for key in ('title', @@ -50,7 +50,7 @@ def loadIMDb(imdbId): 'season', 'episode'): if key in info: - setattr(movie.imdb, key, info[key]) + setattr(item.imdb, key, info[key]) debug(key, info[key]) _info_map = { 'episode title': 'episode_title', @@ -58,86 +58,86 @@ def loadIMDb(imdbId): } for key in _info_map.keys(): if key in info: - setattr(movie.imdb, _info_map.get(key, key), info[key]) + setattr(item.imdb, _info_map.get(key, key), info[key]) - movie.imdb.plot = ox.web.imdb.getMoviePlot(imdbId) - debug("plot", movie.imdb.plot) + item.imdb.plot = ox.web.imdb.getMoviePlot(imdbId) + debug("plot", item.imdb.plot) - movie.imdb.runtime = ox.web.imdb.getMovieRuntimeSeconds(imdbId) + item.imdb.runtime = ox.web.imdb.getMovieRuntimeSeconds(imdbId) business = ox.web.imdb.getMovieBusinessSum(imdbId) for key in ('gross', 'profit', 'budget'): - setattr(movie.imdb, key, business[key]) + setattr(item.imdb, key, business[key]) - movie.imdb.save() - movie.oxdbId = "__init__%s" % random.randint(0, 100000) - movie.save() - models.AlternativeTitle.objects.filter(movie=movie, manual=False).delete() + item.imdb.save() + item.oxdbId = "__init__%s" % random.randint(0, 100000) + item.save() + models.AlternativeTitle.objects.filter(item=item, manual=False).delete() for i in ox.web.imdb.getMovieAKATitles(imdbId): t = models.AlternativeTitle() - t.movie = movie + t.item = item t.title = i[0] t.type = i[1] t.save() #FIXME: related tables should be cleaned to not accumulate cruft #Country - models.MovieCountry.objects.filter(movie=movie, manual=False).delete() + models.ItemCountry.objects.filter(item=item, manual=False).delete() position = 0 if 'country' in info: for i in info['country']: debug("add country", i) country, created = models.Country.objects.get_or_create(name=i) - models.MovieCountry.link(movie, country, position) + models.ItemCountry.link(item, country, position) position += 1 #Language - models.MovieLanguage.objects.filter(movie=movie, manual=False).delete() + models.ItemLanguage.objects.filter(item=item, manual=False).delete() position = 0 if 'language' in info: for i in info['language']: debug("add language", i) language, created = models.Language.objects.get_or_create(name=i) - models.MovieLanguage.link(movie, language, position) + models.ItemLanguage.link(item, language, position) position += 1 #Location - movie.locations_all.filter(manual=False).delete() + item.locations_all.filter(manual=False).delete() locations = ox.web.imdb.getMovieLocations(imdbId) for i in locations: debug("add location", i) location, created = models.Location.objects.get_or_create(name=i) - location.movies.add(movie) + location.items.add(item) #Genre - movie.genres_all.filter(manual=False).delete() + item.genres_all.filter(manual=False).delete() if 'genre' in info: for i in info['genre']: debug("add genre", i) genre, created = models.Genre.objects.get_or_create(name=i) - genre.movies.add(movie) + genre.items.add(item) #Keyword - movie.keywords_all.filter(manual=False).delete() + item.keywords_all.filter(manual=False).delete() keywords = ox.web.imdb.getMovieKeywords(imdbId) for g in keywords: debug("add keyword", g) keyword, created = models.Keyword.objects.get_or_create(name=g) - keyword.movies.add(movie) + keyword.items.add(item) - movie.trivia_all.filter(manual=False).delete() + item.trivia_all.filter(manual=False).delete() position = 0 trivia = ox.web.imdb.getMovieTrivia(imdbId) for i in trivia: debug("add trivia", i) t = models.Trivia() - t.movie = movie + t.item = item t.trivia = i t.position = position t.save() position += 1 position = 0 - models.Cast.objects.filter(movie=movie).filter(manual=False).delete() + models.Cast.objects.filter(item=item).filter(manual=False).delete() credits = ox.web.imdb.getMovieCredits(imdbId) for role in credits: for p in credits[role]: @@ -147,29 +147,29 @@ def loadIMDb(imdbId): #FIXME: we could save character information here character = stripTags(p[1]) person = models.Person.get_or_create(name, imdb_id) - models.Cast.link(movie, person, role, character, position) + models.Cast.link(item, person, role, character, position) position += 1 - movie.connections_all.filter(manual=False).delete() + item.connections_all.filter(manual=False).delete() connections = ox.web.imdb.getMovieConnections(imdbId) for relation in connections: for otherId in connections[relation]: try: - object = models.Movie.objects.get(imdb__imdbId=otherId) + object = models.Item.objects.get(imdb__imdbId=otherId) debug("add connection", relation, object) - models.Connection.get_or_create(movie, relation, object) - except models.Movie.DoesNotExist: + models.Connection.get_or_create(item, relation, object) + except models.Item.DoesNotExist: pass reviews = ox.web.imdb.getMovieExternalReviews(imdbId) - movie.reviews_all.filter(manual=False).delete() + item.reviews_all.filter(manual=False).delete() for r in reviews: debug("add review", r) - review = models.Review.get_or_create(movie, r) + review = models.Review.get_or_create(item, r) review.title = reviews[r] review.save() - movie.oxdbId = movie.oxid() - movie.save() - return movie + item.oxdbId = item.oxid() + item.save() + return item diff --git a/pandora/backend/managers.py b/pandora/backend/managers.py index 9f999a66..9ca5afb9 100644 --- a/pandora/backend/managers.py +++ b/pandora/backend/managers.py @@ -36,7 +36,7 @@ def parseCondition(condition): ''' k = condition.get('key', 'all') - k = {'id': 'movieId'}.get(k, k) + k = {'id': 'itemId'}.get(k, k) if not k: k = 'all' v = condition['value'] op = condition.get('operator', None) @@ -49,9 +49,9 @@ def parseCondition(condition): if keyType(k) == "string": in_find=True if op == '=': - if k in models.Movie.facet_keys: + if k in models.Item.facet_keys: in_find=False - v = models.Movie.objects.filter(facets__key=k, facets__value=v) + v = models.Item.objects.filter(facets__key=k, facets__value=v) k = 'id__in' else: k = '%s__iexact' % k @@ -63,7 +63,7 @@ def parseCondition(condition): k = '%s__iendswith' % k else: # elif op == '~': k = '%s__icontains' % k - if in_find and not k.startswith('movieId'): + if in_find and not k.startswith('itemId'): k = 'find__%s' % k k = str(k) if exclude: @@ -151,9 +151,9 @@ def parseConditions(conditions, operator): return q return None -class MovieManager(Manager): +class ItemManager(Manager): def get_query_set(self): - return super(MovieManager, self).get_query_set() + return super(ItemManager, self).get_query_set() def filter_list(self, qs, l, user): if l != "all": @@ -195,7 +195,7 @@ class MovieManager(Manager): #join query with operator qs = self.get_query_set() - #only include movies that have hard metadata + #only include items that have hard metadata qs = qs.filter(available=True) conditions = parseConditions(data['query']['conditions'], data['query'].get('operator', '&')) @@ -212,17 +212,17 @@ class FileManager(Manager): def get_query_set(self): return super(FileManager, self).get_query_set() - def movie_files(self, movie): + def item_files(self, item): q = self.get_query_set() - return q.filter(type=1, movie=movie) + return q.filter(type=1, item=item) class ArchiveFileManager(Manager): def get_query_set(self): return super(ArchiveFileManager, self).get_query_set() - def movie_files(self, movie): + def item_files(self, item): q = self.get_query_set() - return q.filter(file__is_video=True, file__movie=movie) + return q.filter(file__is_video=True, file__item=item) def by_oshash(self, oshash): q = self.get_query_set() diff --git a/pandora/backend/migrations/0011_rename_movie.py b/pandora/backend/migrations/0011_rename_movie.py new file mode 100644 index 00000000..bec903c3 --- /dev/null +++ b/pandora/backend/migrations/0011_rename_movie.py @@ -0,0 +1,261 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.rename_table('backend_moviesort', 'backend_itemsort') + db.rename_table('backend_moviefind', 'backend_itemfind') + db.rename_table('backend_movie', 'backend_item') + db.rename_column('backend_item', 'movieId', 'itemId') + db.rename_column('backend_itemsort', 'movieId', 'itemId') + db.rename_column('backend_itemsort', 'movie_id', 'item_id') + db.rename_column('backend_itemfind', 'movie_id', 'item_id') + db.rename_column('backend_posterurl', 'movie_id', 'item_id') + db.rename_column('backend_stream', 'movie_id', 'item_id') + db.rename_column('backend_facet', 'movie_id', 'item_id') + db.rename_column('backend_layer', 'movie_id', 'item_id') + db.rename_column('backend_listitem', 'movie_id', 'item_id') + db.create_unique('backend_posterurl', ['url', 'item_id', 'service']) + + db.execute("UPDATE backend_item SET poster=REPLACE(poster,'movies/','items/') WHERE poster LIKE 'movies/%'") + db.execute("UPDATE backend_stream SET video=REPLACE(video,'movies/','items/') WHERE video LIKE 'movies/%'") + + def backwards(self, orm): + db.rename_table('backend_itemsort', 'backend_moviesort') + db.rename_table('backend_itemfind', 'backend_moviefind') + db.rename_table('backend_item', 'backend_movie') + db.rename_column('backend_item', 'itemId', 'movieId') + db.rename_column('backend_itemsort', 'itemId', 'movieId') + db.rename_column('backend_itemsort', 'item_id', 'movie') + db.rename_column('backend_itemfind', 'item_id', 'movie') + db.rename_column('backend_posterurl', 'item_id', 'movie') + db.rename_column('backend_stream', 'item_id', 'movie') + db.rename_column('backend_facet', 'item_id', 'movie_id') + db.rename_column('backend_layer', 'item_id', 'movie_id') + db.rename_column('backend_listitem', 'item_id', 'movie_id') + db.create_unique('backend_posterurl', ['url', 'movie_id', 'service']) + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + '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': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'backend.collection': { + 'Meta': {'object_name': 'Collection'}, + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'items': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Item']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'blank': 'True'}), + 'subdomain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '2048'}), + 'users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'collections'", 'symmetrical': 'False', 'to': "orm['auth.User']"}) + }, + 'backend.facet': { + 'Meta': {'object_name': 'Facet'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_index': 'True'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'facets'", 'to': "orm['backend.Item']"}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'value_sort': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'backend.layer': { + 'Meta': {'object_name': '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'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Item']"}), + 'start': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'stop': ('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': { + 'Meta': {'object_name': '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'}), + 'lists': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'lists'", 'symmetrical': 'False', 'through': "orm['backend.ListItem']", 'to': "orm['backend.Item']"}), + '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': { + 'Meta': {'object_name': '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'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['backend.Item']"}) + }, + 'backend.location': { + 'Meta': {'object_name': 'Location'}, + 'area': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lat_center': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'lat_ne': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'lat_sw': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'lng_center': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'lng_ne': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'lng_sw': ('django.db.models.fields.FloatField', [], {'default': '0'}), + 'manual': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'items': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'locations_all'", 'symmetrical': 'False', 'to': "orm['backend.Item']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'}) + }, + 'backend.item': { + 'Meta': {'object_name': 'Item'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'imdb': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'json': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'metadata': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'itemId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128', 'blank': 'True'}), + 'oxdbId': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '42', 'blank': 'True'}), + 'poster': ('django.db.models.fields.files.ImageField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}), + 'poster_frame': ('django.db.models.fields.FloatField', [], {'default': '-1'}), + 'poster_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'poster_url': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'poster_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'published': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'stream_aspect': ('django.db.models.fields.FloatField', [], {'default': '1.3333333333333333'}) + }, + 'backend.itemfind': { + 'Meta': {'object_name': 'ItemFind'}, + 'actor': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'all': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'character': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'cinematographer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'country': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'dialog': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'director': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'editor': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'filename': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'genre': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'keyword': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'language': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'location': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'item': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'find'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['backend.Item']"}), + 'producer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'title': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'trivia': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'writer': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'year': ('django.db.models.fields.CharField', [], {'max_length': '4'}) + }, + 'backend.itemsort': { + 'Meta': {'object_name': 'ItemSort'}, + 'aspectratio': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'bitrate': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'cast': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'cinematographer': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'cinematographer_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'connections': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'country': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'country_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'dialog': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'director': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'director_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'duration': ('django.db.models.fields.FloatField', [], {'default': '-1', 'db_index': 'True'}), + 'editor': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'editor_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'filename': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'files': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'genre': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'keywords': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'language': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'language_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'item': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'sort'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['backend.Item']"}), + 'itemId': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '128', 'blank': 'True'}), + 'pixels': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'producer': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'producer_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'rating': ('django.db.models.fields.FloatField', [], {'db_index': 'True', 'blank': 'True'}), + 'resolution': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'risk': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'runtime': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'scenes': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'summary': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'db_index': 'True'}), + 'title_desc': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'db_index': 'True'}), + 'trivia': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'votes': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}), + 'words': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'wpm': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'writer': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'writer_desc': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'blank': 'True'}), + 'year': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_index': 'True'}), + 'year_desc': ('django.db.models.fields.CharField', [], {'max_length': '4', 'db_index': 'True'}) + }, + 'backend.person': { + 'Meta': {'object_name': 'Person'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'imdbId': ('django.db.models.fields.CharField', [], {'max_length': '7', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'name_sort': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'backend.posterurl': { + 'Meta': {'object_name': 'PosterUrl'}, + 'height': ('django.db.models.fields.IntegerField', [], {'default': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'poster_urls'", 'to': "orm['backend.Item']"}), + 'service': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'width': ('django.db.models.fields.IntegerField', [], {'default': '80'}) + }, + 'backend.reviewwhitelist': { + 'Meta': {'object_name': '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.stream': { + 'Meta': {'unique_together': "(('item', 'profile'),)", 'object_name': 'Stream'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'info': ('oxdjango.fields.DictField', [], {'default': '{}'}), + 'item': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'streams'", 'to': "orm['backend.Item']"}), + 'profile': ('django.db.models.fields.CharField', [], {'default': "'96p.webm'", 'max_length': '255'}), + 'source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'derivatives'", 'null': 'True', 'to': "orm['backend.Stream']"}), + 'video': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'blank': 'True'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', '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/pandora/backend/models.py b/pandora/backend/models.py index 4b62ea12..1545be17 100644 --- a/pandora/backend/models.py +++ b/pandora/backend/models.py @@ -29,50 +29,50 @@ import utils from archive import extract -def getMovie(info): +def getItem(info): ''' info dict with: imdbId, title, director, episode_title, season, series ''' if 'imdbId' in info and info['imdbId']: try: - movie = Movie.objects.get(movieId=info['imdbId']) - except Movie.DoesNotExist: - movie = Movie(movieId=info['imdbId']) + item = Item.objects.get(itemId=info['imdbId']) + except Item.DoesNotExist: + item = Item(itemId=info['imdbId']) if 'title' in info and 'directors' in info: - movie.imdb = { + item.imdb = { 'title': info['title'], 'directors': info['directors'], 'year': info.get('year', '') } #FIXME: this should be done async - #movie.save() - #tasks.updateImdb.delay(movie.movieId) - movie.updateImdb() + #item.save() + #tasks.updateImdb.delay(item.itemId) + item.updateImdb() else: - q = Movie.objects.filter(find__title=info['title']) + q = Item.objects.filter(find__title=info['title']) if q.count() > 1: print "FIXME: check more than title here!!?" - movie = q[0] + item = q[0] else: try: - movie = Movie.objects.get(movieId=info['oxdbId']) - except Movie.DoesNotExist: - movie = Movie() - movie.metadata = { + item = Item.objects.get(itemId=info['oxdbId']) + except Item.DoesNotExist: + item = Item() + item.metadata = { 'title': info['title'], 'directors': info['directors'], 'year': info.get('year', '') } - movie.movieId = info['oxdbId'] + item.itemId = info['oxdbId'] for key in ('episode_title', 'series_title', 'season', 'episode'): if key in info and info[key]: - movie.metadata[key] = info[key] - movie.save() - return movie + item.metadata[key] = info[key] + item.save() + return item -class Movie(models.Model): +class Item(models.Model): person_keys = ('director', 'writer', 'producer', 'editor', 'cinematographer', 'actor', 'character') facet_keys = person_keys + ('country', 'language', 'genre', 'keyword') @@ -80,14 +80,14 @@ class Movie(models.Model): modified = models.DateTimeField(auto_now=True) published = models.DateTimeField(default=datetime.now, editable=False) - #only movies that have metadata from files are available, + #only items that have metadata from files are available, #this is indicated by setting available to True available = models.BooleanField(default=False, db_index=True) - movieId = models.CharField(max_length=128, unique=True, blank=True) + itemId = models.CharField(max_length=128, unique=True, blank=True) oxdbId = models.CharField(max_length=42, unique=True, blank=True) - objects = managers.MovieManager() + objects = managers.ItemManager() def get(self, key, default=None): if self.metadata and key in self.metadata: @@ -124,11 +124,11 @@ class Movie(models.Model): json = fields.DictField(default={}, editable=False) def updateImdb(self): - if len(self.movieId) == 7: - self.imdb = ox.web.imdb.Imdb(self.movieId) + if len(self.itemId) == 7: + self.imdb = ox.web.imdb.Imdb(self.itemId) self.save() - poster = models.ImageField(default=None, blank=True, upload_to=lambda m, x: os.path.join(movieid_path(m.movieId), "poster.jpg")) + poster = models.ImageField(default=None, blank=True, upload_to=lambda m, x: os.path.join(itemid_path(m.itemId), "poster.jpg")) poster_url = models.TextField(blank=True) poster_height = models.IntegerField(default=0) poster_width = models.IntegerField(default=0) @@ -145,7 +145,7 @@ class Movie(models.Model): return self.get('title') def get_absolute_url(self): - return '/timeline#%s' % self.movieId + return '/timeline#%s' % self.itemId def save(self, *args, **kwargs): self.json = self.get_json() @@ -158,7 +158,7 @@ class Movie(models.Model): else: self.poster_height = 128 self.poster_width = 80 - super(Movie, self).save(*args, **kwargs) + super(Item, self).save(*args, **kwargs) self.updateFind() self.updateSort() self.updateFacets() @@ -169,27 +169,27 @@ class Movie(models.Model): os.unlink(f) for f in glob("%sstrip*"%self.timeline_prefix[:-8]): os.unlink(f) - super(Movie, self).delete(*args, **kwargs) + super(Item, self).delete(*args, **kwargs) def mergeWith(self, other): ''' move all related tables to other and delete self ''' for stream in self.streams.all(): - stream.movie = other + stream.item = other stream.save() for l in self.lists.all(): - l.movies.remove(self) - if l.movies.filter(id=other.id) == 0: - l.movies.add(other) + l.items.remove(self) + if l.items.filter(id=other.id) == 0: + l.items.add(other) #FIXME: should this really happen for layers? for l in self.layer.all(): - l.movies.remove(self) - if l.movies.filter(id=other.id) == 0: - l.movies.add(other) + l.items.remove(self) + if l.items.filter(id=other.id) == 0: + l.items.add(other) if hasattr(self, 'files'): for f in self.files.all(): - f.movie = other + f.item = other f.save() self.delete() other.save() @@ -198,7 +198,7 @@ class Movie(models.Model): JSON cache related functions ''' _public_fields = { - 'movieId': 'id', + 'itemId': 'id', 'title': 'title', 'year': 'year', @@ -230,7 +230,7 @@ class Movie(models.Model): poster = {} poster['width'] = self.poster_width poster['height'] = self.poster_height - poster['url'] = '/%s/poster.jpg' % self.movieId + poster['url'] = '/%s/poster.jpg' % self.itemId ''' if self.poster: poster['url'] = self.poster.url @@ -264,7 +264,7 @@ class Movie(models.Model): if 'video' in s.info and s.info['video']: stream['aspectRatio'] = s.info['video'][0]['width'] / s.info['video'][0]['height'] if settings.XSENDFILE or settings.XACCELREDIRECT: - stream['baseUrl'] = '/%s' % self.movieId + stream['baseUrl'] = '/%s' % self.itemId else: stream['baseUrl'] = os.path.dirname(s.video.url) stream['profiles'] = list(set(map(lambda s: int(os.path.splitext(s['profile'])[0][:-1]), self.streams.all().values('profile')))) @@ -281,7 +281,7 @@ class Movie(models.Model): return layers def get_json(self, fields=None): - movie = {} + item = {} for key in self._public_fields: pub_key = self._public_fields.get(key, key) if not fields or pub_key in fields: @@ -290,18 +290,18 @@ class Movie(models.Model): else: value = self.get(key) if callable(value): - movie[pub_key] = value() + item[pub_key] = value() else: - movie[pub_key] = value + item[pub_key] = value if not fields: - movie['stream'] = self.get_stream() - movie['poster'] = self.get_poster() - movie['posters'] = self.get_posters() + item['stream'] = self.get_stream() + item['poster'] = self.get_poster() + item['posters'] = self.get_posters() if fields: for f in fields: if f.endswith('.length') and f[:-7] in ('cast', 'genre', 'trivia'): - movie[f] = getattr(self.sort, f[:-7]) - return movie + item[f] = getattr(self.sort, f[:-7]) + return item def fields(self): fields = {} @@ -325,8 +325,8 @@ class Movie(models.Model): def updateFind(self): try: f = self.find - except MovieFind.DoesNotExist: - f = MovieFind(movie=self) + except ItemFind.DoesNotExist: + f = ItemFind(item=self) f.title = '\n'.join([self.get('title'), self.get('original_title', '')]) #FIXME: filter us/int title @@ -349,7 +349,7 @@ class Movie(models.Model): #FIXME: #f.dialog = 'fixme' - f.dialog = '\n'.join([l.value for l in Layer.objects.filter(type='subtitle', movie=self).order_by('start')]) + f.dialog = '\n'.join([l.value for l in Layer.objects.filter(type='subtitle', item=self).order_by('start')]) #FIXME: collate filenames #f.filename = self.filename @@ -362,8 +362,8 @@ class Movie(models.Model): def updateSort(self): try: s = self.sort - except MovieSort.DoesNotExist: - s = MovieSort(movie=self) + except ItemSort.DoesNotExist: + s = ItemSort(item=self) def sortNames(values): sort_value = '' @@ -391,7 +391,7 @@ class Movie(models.Model): for key in ('keywords', 'genres', 'cast', 'summary', 'trivia', 'connections'): setattr(s, key, len(self.get(key, ''))) - s.movieId = self.movieId.replace('0x', 'xx') + s.itemId = self.itemId.replace('0x', 'xx') s.rating = self.get('rating', -1) s.votes = self.get('votes', -1) @@ -430,37 +430,37 @@ class Movie(models.Model): current_values = [i[1] for i in self.get('actor', [])] else: current_values = self.get(utils.plural_key(key), []) - saved_values = [i.value for i in Facet.objects.filter(movie=self, key=key)] + saved_values = [i.value for i in Facet.objects.filter(item=self, key=key)] removed_values = filter(lambda x: x not in current_values, saved_values) if removed_values: - Facet.objects.filter(movie=self, key=key, value__in=removed_values).delete() + Facet.objects.filter(item=self, key=key, value__in=removed_values).delete() for value in current_values: if value not in saved_values: value_sort = value if key in self.person_keys: value_sort = getPersonSort(value) f = Facet(key=key, value=value, value_sort=value_sort) - f.movie = self + f.item = self f.save() year = self.get('year', None) if year: - f, created = Facet.objects.get_or_create(key='year', value=year, value_sort=year, movie=self) + f, created = Facet.objects.get_or_create(key='year', value=year, value_sort=year, item=self) else: - Facet.objects.filter(movie=self, key='year').delete() + Facet.objects.filter(item=self, key='year').delete() ''' Video related functions ''' def frame(self, position, width=128): stream = self.streams.filter(profile=settings.VIDEO_PROFILE+'.webm')[0] - path = os.path.join(settings.MEDIA_ROOT, movieid_path(self.movieId), 'frames', "%d"%width, "%s.jpg"%position) + path = os.path.join(settings.MEDIA_ROOT, itemid_path(self.itemId), 'frames', "%d"%width, "%s.jpg"%position) if not os.path.exists(path): extract.frame(stream.video.path, path, position, width) return path @property def timeline_prefix(self): - return os.path.join(settings.MEDIA_ROOT, movieid_path(self.movieId), 'timeline') + return os.path.join(settings.MEDIA_ROOT, itemid_path(self.itemId), 'timeline') def updateStreams(self): files = {} @@ -469,7 +469,7 @@ class Movie(models.Model): #FIXME: how to detect if something changed? if files: - stream, created = Stream.objects.get_or_create(movie=self, profile='%s.webm' % settings.VIDEO_PROFILE) + stream, created = Stream.objects.get_or_create(item=self, profile='%s.webm' % settings.VIDEO_PROFILE) stream.video.name = stream_path(stream) cmd = [] @@ -501,7 +501,7 @@ class Movie(models.Model): def update_poster_urls(self): _current = {} for s in settings.POSTER_SERVICES: - url = '%s?movieId=%s'%(s, self.movieId) + url = '%s?itemId=%s'%(s, self.itemId) try: data = json.loads(ox.net.readUrlUnicode(url)) except: @@ -514,7 +514,7 @@ class Movie(models.Model): #FIXME: remove urls that are no longer listed for service in _current: for poster in _current[service]: - p, created = PosterUrl.objects.get_or_create(movie=self, url=poster['url'], service=service) + p, created = PosterUrl.objects.get_or_create(item=self, url=poster['url'], service=service) if created: p.width = poster['width'] p.height = poster['height'] @@ -558,7 +558,7 @@ class Movie(models.Model): posters = {} for f in self.files.filter(is_main=True, available=True): for frame in f.frames.all(): - path = os.path.join(movieid_path(self.movieId), 'poster.pandora.%s.%s.jpg'%(part, frame.position)) + path = os.path.join(itemid_path(self.itemId), 'poster.pandora.%s.%s.jpg'%(part, frame.position)) path = os.path.abspath(os.path.join(settings.MEDIA_ROOT, path)) posters[path] = frame.frame.path part += 1 @@ -574,18 +574,18 @@ class Movie(models.Model): '-f', frame, '-p', poster ] - if len(self.movieId) == 7: - cmd += ['-i', self.movieId] + if len(self.itemId) == 7: + cmd += ['-i', self.itemId] cmd += ['-o', self.oxdbId] p = subprocess.Popen(cmd) p.wait() return posters.keys() -class MovieFind(models.Model): +class ItemFind(models.Model): """ - used to search movies, all search values are in here + used to search items, all search values are in here """ - movie = models.OneToOneField('Movie', related_name='find', primary_key=True) + item = models.OneToOneField('Item', related_name='find', primary_key=True) all = models.TextField(blank=True) title = models.TextField(blank=True) @@ -612,7 +612,7 @@ class MovieFind(models.Model): #only for own files or as admin? filename = models.TextField(blank=True, default='') - _private_fields = ('id', 'movie') + _private_fields = ('id', 'item') #return available find fields #FIXME: should return mapping name -> verbose_name def fields(self): @@ -625,11 +625,11 @@ class MovieFind(models.Model): return tuple(fields) fields = classmethod(fields) -class MovieSort(models.Model): +class ItemSort(models.Model): """ - used to sort movies, all sort values are in here + used to sort items, all sort values are in here """ - movie = models.OneToOneField('Movie', related_name='sort', primary_key=True) + item = models.OneToOneField('Item', related_name='sort', primary_key=True) title = models.CharField(max_length=1000, db_index=True) director = models.TextField(blank=True, db_index=True) @@ -659,7 +659,7 @@ class MovieSort(models.Model): wpm = models.IntegerField('Words per Minute', null=True, blank=True, db_index=True) risk = models.IntegerField(null=True, blank=True, db_index=True) - movieId = models.CharField('ID', max_length=128, blank=True, db_index=True) + itemId = models.CharField('ID', max_length=128, blank=True, db_index=True) duration = models.FloatField(default=-1, db_index=True) resolution = models.IntegerField(blank=True, db_index=True) @@ -683,7 +683,7 @@ class MovieSort(models.Model): language_desc = models.TextField(blank=True, db_index=True) - _private_fields = ('id', 'movie') + _private_fields = ('id', 'item') #return available sort fields #FIXME: should return mapping name -> verbose_name def fields(self): @@ -697,7 +697,7 @@ class MovieSort(models.Model): fields = classmethod(fields) class Facet(models.Model): - movie = models.ForeignKey('Movie', related_name='facets') + item = models.ForeignKey('Item', related_name='facets') key = models.CharField(max_length=200, db_index=True) value = models.CharField(max_length=200) value_sort = models.CharField(max_length=200) @@ -749,7 +749,7 @@ class Person(models.Model): class Location(models.Model): name = models.CharField(max_length=200, unique=True) manual = models.BooleanField(default=False) - movies = models.ManyToManyField(Movie, related_name='locations_all') + items = models.ManyToManyField(Item, related_name='locations_all') #fixme: geo data lat_sw = models.FloatField(default=0) @@ -779,18 +779,18 @@ class List(models.Model): user = models.ForeignKey(User) name = models.CharField(max_length=255, unique=True) public = models.BooleanField(default=False) - movies = models.ManyToManyField(Movie, related_name='lists', through='ListItem') + items = models.ManyToManyField(Item, related_name='lists', through='ListItem') - def add(self, movie): - q = self.movies.filter(id=movie.id) + def add(self, item): + q = self.items.filter(id=item.id) if q.count() == 0: l = ListItem() l.list = self - l.movie = movie + l.item = item l.save() - def remove(self, movie): - self.ListItem.objects.all().filter(movie=movie, list=self).delete() + def remove(self, item): + self.ListItem.objects.all().filter(item=item, list=self).delete() def __unicode__(self): return u'%s (%s)' % (self.title, unicode(self.user)) @@ -805,17 +805,17 @@ class ListItem(models.Model): created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) list = models.ForeignKey(List) - movie = models.ForeignKey(Movie) + item = models.ForeignKey(Item) def __unicode__(self): - return u'%s in %s' % (unicode(self.movie), unicode(self.list)) + return u'%s in %s' % (unicode(self.item), unicode(self.list)) class Layer(models.Model): - #FIXME: here having a movie,start index would be good + #FIXME: here having a item,start index would be good created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) user = models.ForeignKey(User) - movie = models.ForeignKey(Movie) + item = models.ForeignKey(Item) #seconds start = models.FloatField(default=-1) @@ -841,22 +841,22 @@ class Collection(models.Model): users = models.ManyToManyField(User, related_name='collections') name = models.CharField(blank=True, max_length=2048) subdomain = models.CharField(unique=True, max_length=2048) - movies = models.ForeignKey(Movie) + items = models.ForeignKey(Item) def editable(self, user): return self.users.filter(id=user.id).count() > 0 -def movieid_path(h): - return os.path.join('movies', h[:2], h[2:4], h[4:6], h[6:]) +def itemid_path(h): + return os.path.join('items', h[:2], h[2:4], h[4:6], h[6:]) def stream_path(stream): - return os.path.join(movieid_path(stream.movie.movieId), stream.profile) + return os.path.join(itemid_path(stream.item.itemId), stream.profile) class Stream(models.Model): class Meta: - unique_together = ("movie", "profile") + unique_together = ("item", "profile") - movie = models.ForeignKey(Movie, related_name='streams') + item = models.ForeignKey(Item, related_name='streams') profile = models.CharField(max_length=255, default='96p.webm') video = models.FileField(default=None, blank=True, upload_to=lambda f, x: stream_path(f)) source = models.ForeignKey('Stream', related_name='derivatives', default=None, null=True) @@ -869,7 +869,7 @@ class Stream(models.Model): def extract_derivatives(self): if settings.VIDEO_H264: profile = self.profile.replace('.webm', '.mp4') - derivative, created = Stream.objects.get_or_create(profile=profile, movie=self.movie) + derivative, created = Stream.objects.get_or_create(profile=profile, item=self.item) if created: derivative.source = self derivative.video.name = self.video.name.replace(self.profile, profile) @@ -879,7 +879,7 @@ class Stream(models.Model): for p in settings.VIDEO_DERIVATIVES: profile = p + '.webm' target = self.video.path.replace(self.profile, profile) - derivative, created = Stream.objects.get_or_create(profile=profile, movie=self.movie) + derivative, created = Stream.objects.get_or_create(profile=profile, item=self.item) if created: derivative.source = self derivative.video.name = self.video.name.replace(self.profile, profile) @@ -888,7 +888,7 @@ class Stream(models.Model): if settings.VIDEO_H264: profile = p + '.mp4' - derivative, created = Stream.objects.get_or_create(profile=profile, movie=self.movie) + derivative, created = Stream.objects.get_or_create(profile=profile, item=self.item) if created: derivative.source = self derivative.video.name = self.video.name.replace(self.profile, profile) @@ -907,7 +907,7 @@ class Stream(models.Model): self.save() def __unicode__(self): - return u"%s (%s)" % (self.profile, self.movie) + return u"%s (%s)" % (self.profile, self.item) def save(self, *args, **kwargs): if self.video and not self.info: @@ -916,15 +916,15 @@ class Stream(models.Model): class PosterUrl(models.Model): class Meta: - unique_together = ("movie", "service", "url") + unique_together = ("item", "service", "url") ordering = ('-height', ) - movie = models.ForeignKey(Movie, related_name='poster_urls') + item = models.ForeignKey(Item, related_name='poster_urls') url = models.CharField(max_length=1024) service = models.CharField(max_length=1024) width = models.IntegerField(default=80) height = models.IntegerField(default=128) def __unicode__(self): - return u'%s %s %dx%d' % (unicode(self.movie), self.service, self.width, self.height) + return u'%s %s %dx%d' % (unicode(self.item), self.service, self.width, self.height) diff --git a/pandora/backend/tasks.py b/pandora/backend/tasks.py index 2249cdcf..7fbf533f 100644 --- a/pandora/backend/tasks.py +++ b/pandora/backend/tasks.py @@ -13,19 +13,19 @@ def cronjob(**kwargs): print "do some cleanup stuff once a day" @task(ignore_resulsts=True, queue='default') -def updatePoster(movieId): - movie = models.Movie.objects.get(movieId=movieId) - movie.download_poster(True) +def updatePoster(itemId): + item = models.Item.objects.get(itemId=itemId) + item.download_poster(True) @task(ignore_resulsts=True, queue='default') def updateImdb(imdbId): - movie = models.Movie.objects.get(movieId=imdbId) - movie.updateImdb() + item = models.Item.objects.get(itemId=imdbId) + item.updateImdb() @task(ignore_resulsts=True) -def findMovie(fileId): +def findItem(fileId): f = models.File.objects.get(pk=fileId) - f.findMovie() + f.findItem() @task(ignore_resulsts=True, queue="encoding") def extractData(fileId): @@ -37,11 +37,11 @@ def extractData(fileId): f.extract() @task(ignore_resulsts=True, queue="encoding") -def updateMovie(movidId): +def updateItem(movidId): ''' - update movie - create proxy stream and other related files extracted from movieFiles + update item + create proxy stream and other related files extracted from itemFiles ''' - m = models.Movie.objects.get(pk=movieId) + m = models.Item.objects.get(pk=itemId) m.extract() diff --git a/pandora/backend/utils.py b/pandora/backend/utils.py index d7122c5a..ae1f003e 100644 --- a/pandora/backend/utils.py +++ b/pandora/backend/utils.py @@ -57,7 +57,7 @@ def oxdb_directors(director): def oxdb_title(_title, searchTitle = False): ''' - normalize filename to get movie title + normalize filename to get item title ''' _title = os.path.basename(_title) _title = _title.replace('... ', '_dot_dot_dot_') diff --git a/pandora/backend/views.py b/pandora/backend/views.py index a8060e7e..7221da43 100644 --- a/pandora/backend/views.py +++ b/pandora/backend/views.py @@ -103,8 +103,8 @@ def _order_query(qs, sort, prefix='sort__'): for e in sort: operator = e['operator'] if operator != '-': operator = '' - key = {'id': 'movieId'}.get(e['key'], e['key']) - #FIXME: this should be a property of models.MovieSort!!! + key = {'id': 'itemId'}.get(e['key'], e['key']) + #FIXME: this should be a property of models.ItemSort!!! if operator=='-' and key in ('title', 'director', 'writer', 'producer', 'editor', 'cinematographer', 'language', 'country', 'year'): key = '%s_desc' % key order = '%s%s%s' % (operator, prefix, key) @@ -120,7 +120,7 @@ def _parse_query(data, user): for key in ('sort', 'keys', 'group', 'list', 'range', 'ids'): if key in data: query[key] = data[key] - query['qs'] = models.Movie.objects.find(data, user) + query['qs'] = models.Item.objects.find(data, user) #group by only allows sorting by name or number of itmes return query @@ -204,10 +204,10 @@ Positions else: query['sort'] = [{'key': 'name', 'operator':'+'}] response['data']['items'] = [] - items = 'movies' - movie_qs = query['qs'] - qs = models.Facet.objects.filter(key=query['group']).filter(movie__id__in=movie_qs) - qs = qs.values('value').annotate(movies=Count('id')).order_by() + items = 'items' + item_qs = query['qs'] + qs = models.Facet.objects.filter(key=query['group']).filter(item__id__in=item_qs) + qs = qs.values('value').annotate(items=Count('id')).order_by() name = 'value' name_sort = 'value_sort' @@ -234,7 +234,7 @@ Positions qs = _order_query(query['qs'], query['sort']) response['data']['positions'] = {} - ids = [j['movieId'] for j in qs.values('movieId')] + ids = [j['itemId'] for j in qs.values('itemId')] response['data']['positions'] = _get_positions(ids, query['ids']) elif 'keys' in query: @@ -251,8 +251,8 @@ Positions qs = qs[query['range'][0]:query['range'][1]] response['data']['items'] = [only_p(m['json']) for m in qs.values('json')] else: # otherwise stats - movies = query['qs'] - files = File.objects.all().filter(movie__in=movies) + items = query['qs'] + files = File.objects.all().filter(item__in=items) r = files.aggregate( Sum('duration'), Sum('pixels'), @@ -260,9 +260,9 @@ Positions ) response['data']['duration'] = r['duration__sum'] response['data']['files'] = files.count() - response['data']['items'] = movies.count() + response['data']['items'] = items.count() response['data']['pixels'] = r['pixels__sum'] - response['data']['runtime'] = movies.aggregate(Sum('sort__runtime'))['sort__runtime__sum'] + response['data']['runtime'] = items.aggregate(Sum('sort__runtime'))['sort__runtime__sum'] if response['data']['runtime'] == None: response['data']['runtime'] = 1337 response['data']['size'] = r['size__sum'] @@ -277,7 +277,7 @@ def api_getItem(request): ''' response = json_response({}) itemId = json.loads(request.POST['data']) - item = get_object_or_404_json(models.Movie, movieId=itemId) + item = get_object_or_404_json(models.Item, itemId=itemId) #FIXME: check permissions info = item.get_json() info['stream'] = item.get_stream() @@ -294,7 +294,7 @@ def api_editItem(request): 'data': {}} ''' data = json.loads(request.POST['data']) - item = get_object_or_404_json(models.Movie, movieId=data['id']) + item = get_object_or_404_json(models.Item, itemId=data['id']) if item.editable(request.user): response = json_response(status=501, text='not implemented') item.edit(data) @@ -312,7 +312,7 @@ def api_removeItem(request): ''' response = json_response({}) itemId = json.loads(request.POST['data']) - item = get_object_or_404_json(models.Movie, movieId=itemId) + item = get_object_or_404_json(models.Item, itemId=itemId) if item.editable(request.user): response = json_response(status=501, text='not implemented') else: @@ -436,12 +436,12 @@ def api_parse(request): #parse path and return info def api_setPosterFrame(request): #parse path and return info ''' param data - {id: movieId, position: float} + {id: itemId, position: float} return {'status': {'code': int, 'text': string}, data: {}} ''' data = json.loads(request.POST['data']) - item = get_object_or_404_json(models.Movie, movieId=data['id']) + item = get_object_or_404_json(models.Item, itemId=data['id']) if item.editable(request.user): #FIXME: some things need to be updated after changing this item.poster_frame = data['position'] @@ -454,12 +454,12 @@ def api_setPosterFrame(request): #parse path and return info def api_setPoster(request): #parse path and return info ''' param data - {id: movieId, url: string} + {id: itemId, url: string} return {'status': {'code': int, 'text': string}, data: {poster: {url,width,height}}} ''' data = json.loads(request.POST['data']) - item = get_object_or_404_json(models.Movie, movieId=data['id']) + item = get_object_or_404_json(models.Item, itemId=data['id']) if item.editable(request.user): valid_urls = [p.url for p in item.poster_urls.all()] if data['url'] in valid_urls: @@ -467,7 +467,7 @@ def api_setPoster(request): #parse path and return info if item.poster: item.poster.delete() item.save() - tasks.updatePoster.delay(item.movieId) + tasks.updatePoster.delay(item.itemId) response = json_response(status=200, text='ok') response['data']['poster'] = item.get_poster() else: @@ -535,45 +535,45 @@ def apidoc(request): media delivery ''' def frame(request, id, position, size): - movie = get_object_or_404(models.Movie, movieId=id) + item = get_object_or_404(models.Item, itemId=id) position = float(position.replace(',', '.')) - frame = movie.frame(position, int(size)) + frame = item.frame(position, int(size)) if not frame: raise Http404 return HttpFileResponse(frame, content_type='image/jpeg') def poster(request, id, size=None): - movie = get_object_or_404(models.Movie, movieId=id) + item = get_object_or_404(models.Item, itemId=id) if size == 'large': size = None - if movie.poster: + if item.poster: if size: size = int(size) - poster_path = movie.poster.path.replace('.jpg', '.%d.jpg'%size) + poster_path = item.poster.path.replace('.jpg', '.%d.jpg'%size) if not os.path.exists(poster_path): - poster_size = max(movie.poster.width, movie.poster.height) + poster_size = max(item.poster.width, item.poster.height) if size > poster_size: - return redirect('/%s/poster.jpg' % movie.movieId) - extract.resize_image(movie.poster.path, poster_path, size=size) + return redirect('/%s/poster.jpg' % item.itemId) + extract.resize_image(item.poster.path, poster_path, size=size) else: - poster_path = movie.poster.path + poster_path = item.poster.path else: if not size: size='large' - return redirect('http://0xdb.org/%s/poster.%s.jpg' % (movie.movieId, size)) + return redirect('http://0xdb.org/%s/poster.%s.jpg' % (item.itemId, size)) poster_path = os.path.join(settings.STATIC_ROOT, 'png/posterDark.48.png') return HttpFileResponse(poster_path, content_type='image/jpeg') def timeline(request, id, timeline, size, position): - movie = get_object_or_404(models.Movie, movieId=id) + item = get_object_or_404(models.Item, itemId=id) if timeline == 'strip': - timeline = '%s.%s.%04d.png' %(movie.timeline_prefix[:-8] + 'strip', size, int(position)) + timeline = '%s.%s.%04d.png' %(item.timeline_prefix[:-8] + 'strip', size, int(position)) else: - timeline = '%s.%s.%04d.png' %(movie.timeline_prefix, size, int(position)) + timeline = '%s.%s.%04d.png' %(item.timeline_prefix, size, int(position)) return HttpFileResponse(timeline, content_type='image/png') def video(request, id, profile): - movie = get_object_or_404(models.Movie, movieId=id) - stream = get_object_or_404(movie.streams, profile=profile) + item = get_object_or_404(models.Item, itemId=id) + stream = get_object_or_404(item.streams, profile=profile) path = stream.video.path content_type = path.endswith('.mp4') and 'video/mp4' or 'video/webm' return HttpFileResponse(path, content_type=content_type)