cleanup imports and syntax warnings
This commit is contained in:
parent
7fdae917cf
commit
2d5f924891
46 changed files with 452 additions and 517 deletions
|
|
@ -5,6 +5,7 @@ from django.contrib import admin
|
|||
|
||||
import models
|
||||
|
||||
|
||||
class ItemAdmin(admin.ModelAdmin):
|
||||
search_fields = ['itemId', 'data', 'external_data']
|
||||
list_display = ['available', 'itemId', '__unicode__']
|
||||
|
|
@ -12,8 +13,7 @@ class ItemAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(models.Item, ItemAdmin)
|
||||
|
||||
|
||||
class PropertyAdmin(admin.ModelAdmin):
|
||||
search_fields = ['name', 'title']
|
||||
admin.site.register(models.Property, PropertyAdmin)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
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",
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
import re
|
||||
from datetime import datetime
|
||||
from urllib2 import unquote
|
||||
from ox.utils import json
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import Q, Manager
|
||||
|
||||
|
||||
import models
|
||||
|
||||
|
||||
|
|
@ -21,6 +16,7 @@ def keyType(key):
|
|||
return "float"
|
||||
return "string"
|
||||
|
||||
|
||||
def parseCondition(condition):
|
||||
'''
|
||||
condition: {
|
||||
|
|
@ -33,13 +29,15 @@ def parseCondition(condition):
|
|||
operator: "!="
|
||||
}
|
||||
...
|
||||
'''
|
||||
'''
|
||||
k = condition.get('key', 'all')
|
||||
k = {'id': 'itemId'}.get(k, k)
|
||||
if not k: k = 'all'
|
||||
if not k:
|
||||
k = 'all'
|
||||
v = condition['value']
|
||||
op = condition.get('operator', None)
|
||||
if not op: op = '~'
|
||||
if not op:
|
||||
op = '~'
|
||||
if op.startswith('!'):
|
||||
op = op[1:]
|
||||
exclude = True
|
||||
|
|
@ -66,16 +64,17 @@ def parseCondition(condition):
|
|||
k = str(k)
|
||||
if exclude:
|
||||
if in_find and not k.startswith('itemId'):
|
||||
q = ~Q(**{'find__key':k, value_key:v})
|
||||
q = ~Q(**{'find__key': k, value_key: v})
|
||||
else:
|
||||
q = ~Q(**{k:v})
|
||||
q = ~Q(**{k: v})
|
||||
else:
|
||||
if in_find and not k.startswith('itemId'):
|
||||
q = Q(**{'find__key':k, value_key:v})
|
||||
q = Q(**{'find__key': k, value_key: v})
|
||||
else:
|
||||
q = Q(**{k:v})
|
||||
q = Q(**{k: v})
|
||||
return q
|
||||
else: #number or date
|
||||
|
||||
def parseDate(d):
|
||||
while len(d) < 3:
|
||||
d.append(1)
|
||||
|
|
@ -90,11 +89,11 @@ def parseCondition(condition):
|
|||
if exclude: #!1960-1970
|
||||
k1 = 'value__lt'
|
||||
k2 = 'value__gte'
|
||||
return Q(**{'find__key': k, k1:v1})|Q(**{'find__key': k, k2:v2})
|
||||
return Q(**{'find__key': k, k1: v1})|Q(**{'find__key': k, k2: v2})
|
||||
else: #1960-1970
|
||||
k1 = 'value__gte'
|
||||
k2 = 'value__lt'
|
||||
return Q(**{'find__key': k, k1:v1})&Q(**{'find__key': k, k2:v2})
|
||||
return Q(**{'find__key': k, k1: v1})&Q(**{'find__key': k, k2: v2})
|
||||
else:
|
||||
if keyType(k) == "date":
|
||||
v = parseDate(v.split('.'))
|
||||
|
|
@ -113,9 +112,10 @@ def parseCondition(condition):
|
|||
vk = str(vk)
|
||||
|
||||
if exclude: #!1960
|
||||
return ~Q(**{'find__key': k, vk:v})
|
||||
return ~Q(**{'find__key': k, vk: v})
|
||||
else: #1960
|
||||
return Q(**{'find__key': k, vk:v})
|
||||
return Q(**{'find__key': k, vk: v})
|
||||
|
||||
|
||||
def parseConditions(conditions, operator):
|
||||
'''
|
||||
|
|
@ -135,16 +135,18 @@ def parseConditions(conditions, operator):
|
|||
}
|
||||
],
|
||||
operator: "&"
|
||||
'''
|
||||
'''
|
||||
conn = []
|
||||
for condition in conditions:
|
||||
if 'conditions' in condition:
|
||||
q = parseConditions(condition['conditions'],
|
||||
condition.get('operator', '&'))
|
||||
if q: conn.append(q)
|
||||
if q:
|
||||
conn.append(q)
|
||||
pass
|
||||
else:
|
||||
if condition.get('value', '') != '' or condition.get('operator', '') == '=':
|
||||
if condition.get('value', '') != '' or \
|
||||
condition.get('operator', '') == '=':
|
||||
conn.append(parseCondition(condition))
|
||||
if conn:
|
||||
q = conn[0]
|
||||
|
|
@ -156,7 +158,9 @@ def parseConditions(conditions, operator):
|
|||
return q
|
||||
return None
|
||||
|
||||
|
||||
class ItemManager(Manager):
|
||||
|
||||
def get_query_set(self):
|
||||
return super(ItemManager, self).get_query_set()
|
||||
|
||||
|
|
@ -165,13 +169,14 @@ class ItemManager(Manager):
|
|||
l = l.split(":")
|
||||
only_public = True
|
||||
if not user.is_anonymous():
|
||||
if len(l) == 1: l = [request.user.username] + l
|
||||
if request.user.username == l[0]:
|
||||
if len(l) == 1:
|
||||
l = [user.username] + l
|
||||
if user.username == l[0]:
|
||||
only_public = False
|
||||
if len(l) == 2:
|
||||
lqs = models.List.objects.filter(name=l[1], user__username=l[0])
|
||||
if only_public:
|
||||
lqs = qls.filter(public=True)
|
||||
lqs = lqs.filter(public=True)
|
||||
if lqs.count() == 1:
|
||||
qs = qs.filter(listitem__list__id=lqs[0].id)
|
||||
return qs
|
||||
|
|
@ -196,7 +201,7 @@ class ItemManager(Manager):
|
|||
],
|
||||
operator: "&"
|
||||
}
|
||||
'''
|
||||
'''
|
||||
|
||||
#join query with operator
|
||||
qs = self.get_query_set()
|
||||
|
|
@ -212,4 +217,3 @@ class ItemManager(Manager):
|
|||
l = data.get('list', 'all')
|
||||
qs = self.filter_list(qs, l, user)
|
||||
return qs
|
||||
|
||||
|
|
|
|||
|
|
@ -4,26 +4,18 @@ from __future__ import division, with_statement
|
|||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import math
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
import unicodedata
|
||||
from glob import glob
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files.base import ContentFile
|
||||
from django.utils import simplejson as json
|
||||
from django.conf import settings
|
||||
|
||||
from ox.django import fields
|
||||
import ox
|
||||
from ox import stripTags
|
||||
from ox.django import fields
|
||||
from ox.normalize import canonicalTitle
|
||||
import ox.web.imdb
|
||||
from ox.normalize import canonicalTitle, canonicalName
|
||||
from firefogg import Firefogg
|
||||
|
||||
import managers
|
||||
import utils
|
||||
|
|
@ -31,23 +23,23 @@ import tasks
|
|||
from archive import extract
|
||||
|
||||
from annotaion.models import Annotation, Layer
|
||||
from person.models import get_name_sort, Person
|
||||
from person.models import get_name_sort
|
||||
|
||||
|
||||
def siteJson():
|
||||
r = {}
|
||||
r['findKeys'] = [{"id": "all", "title": "All"}]
|
||||
for p in Property.objects.all():
|
||||
if p.find:
|
||||
title = p.title
|
||||
if not title:
|
||||
title = p.name.capitalize()
|
||||
f = {"id": p.name, "title": title}
|
||||
f['autocomplete'] = p.autocomplete
|
||||
r['findKeys'].append(f)
|
||||
|
||||
r['groups'] = [p.name for p in Property.objects.filter(group=True)]
|
||||
r['layers'] = [l.json() for l in Layer.objects.all()]
|
||||
r = {}
|
||||
r['findKeys'] = [{"id": "all", "title": "All"}]
|
||||
for p in Property.objects.all():
|
||||
if p.find:
|
||||
title = p.title
|
||||
if not title:
|
||||
title = p.name.capitalize()
|
||||
f = {"id": p.name, "title": title}
|
||||
f['autocomplete'] = p.autocomplete
|
||||
r['findKeys'].append(f)
|
||||
|
||||
r['groups'] = [p.name for p in Property.objects.filter(group=True)]
|
||||
r['layers'] = [l.json() for l in Layer.objects.all()]
|
||||
|
||||
r['itemViews'] = [
|
||||
{"id": "info", "title": "Info"},
|
||||
|
|
@ -81,28 +73,28 @@ def siteJson():
|
|||
{"id": "public", "title": "Public Lists"},
|
||||
{"id": "featured", "title": "Featured Lists"}
|
||||
]
|
||||
r['sortKeys'] = []
|
||||
for p in Property.objects.exclude(sort=''):
|
||||
title = p.title
|
||||
if not title:
|
||||
title = p.name.capitalize()
|
||||
r['sortKeys'] = []
|
||||
for p in Property.objects.exclude(sort=''):
|
||||
title = p.title
|
||||
if not title:
|
||||
title = p.name.capitalize()
|
||||
|
||||
f = {
|
||||
"id": p.name,
|
||||
"title": title,
|
||||
"operator": p.operator,
|
||||
"align": p.align,
|
||||
"width": p.width,
|
||||
}
|
||||
if not p.removable:
|
||||
f['removable'] = False
|
||||
r['sortKeys'].append(f)
|
||||
r['sortKeys'].append([{"id": "id", "title": "ID", "operator": "", "align": "left", "width": 90}])
|
||||
f = {
|
||||
"id": p.name,
|
||||
"title": title,
|
||||
"operator": p.operator,
|
||||
"align": p.align,
|
||||
"width": p.width,
|
||||
}
|
||||
if not p.removable:
|
||||
f['removable'] = False
|
||||
r['sortKeys'].append(f)
|
||||
r['sortKeys'].append([{"id": "id", "title": "ID", "operator": "", "align": "left", "width": 90}])
|
||||
|
||||
r['totals'] = [{"id": "items"}]
|
||||
for p in Property.objects.filter(totals=True):
|
||||
f = {'id': p.name, 'admin': p.admin}
|
||||
r['totals'].append(f)
|
||||
r['totals'] = [{"id": "items"}]
|
||||
for p in Property.objects.filter(totals=True):
|
||||
f = {'id': p.name, 'admin': p.admin}
|
||||
r['totals'].append(f)
|
||||
|
||||
#FIXME: defaults should also be populated from properties
|
||||
r["user"] = {
|
||||
|
|
@ -127,7 +119,8 @@ def siteJson():
|
|||
},
|
||||
"username": ""
|
||||
}
|
||||
return r
|
||||
return r
|
||||
|
||||
|
||||
def get_item(info):
|
||||
'''
|
||||
|
|
@ -176,28 +169,30 @@ def get_item(info):
|
|||
item.save()
|
||||
return item
|
||||
|
||||
|
||||
class Property(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ('position', )
|
||||
verbose_name_plural = "Properties"
|
||||
|
||||
|
||||
name = models.CharField(null=True, max_length=255, unique=True)
|
||||
title = models.CharField(null=True, max_length=255, blank=True)
|
||||
#text, string, string from list(fixme), event, place, person
|
||||
#text, string, string from list(fixme), event, place, person
|
||||
type = models.CharField(null=True, max_length=255)
|
||||
array = models.BooleanField(default=False)
|
||||
position = models.IntegerField(default=0)
|
||||
width = models.IntegerField(default=180)
|
||||
align = models.CharField(null=True, max_length=255, default='left')
|
||||
operator = models.CharField(null=True, max_length=5, default='', blank=True)
|
||||
default = models.BooleanField('Enabled by default', default=False)
|
||||
removable = models.BooleanField(default=True)
|
||||
default = models.BooleanField('Enabled by default', default=False)
|
||||
removable = models.BooleanField(default=True)
|
||||
|
||||
#sort values: title, string, integer, float, date
|
||||
#sort values: title, string, integer, float, date
|
||||
sort = models.CharField(null=True, max_length=255, blank=True)
|
||||
find = models.BooleanField(default=False)
|
||||
autocomplete = models.BooleanField(default=False)
|
||||
group = models.BooleanField(default=False)
|
||||
find = models.BooleanField(default=False)
|
||||
autocomplete = models.BooleanField(default=False)
|
||||
group = models.BooleanField(default=False)
|
||||
|
||||
totals = models.BooleanField(default=False)
|
||||
admin = models.BooleanField(default=False)
|
||||
|
|
@ -207,19 +202,20 @@ class Property(models.Model):
|
|||
return self.title
|
||||
return self.name
|
||||
|
||||
def json(self):
|
||||
j = {}
|
||||
for key in ('type', 'sort', 'title', 'array', 'totals', 'admin'):
|
||||
value = getattr(self, key)
|
||||
if value:
|
||||
j[key] = value
|
||||
return j
|
||||
def json(self):
|
||||
j = {}
|
||||
for key in ('type', 'sort', 'title', 'array', 'totals', 'admin'):
|
||||
value = getattr(self, key)
|
||||
if value:
|
||||
j[key] = value
|
||||
return j
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.title:
|
||||
self.title = self.name.capitalize()
|
||||
super(Property, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
|
||||
class Item(models.Model):
|
||||
person_keys = ('director', 'writer', 'producer', 'editor', 'cinematographer', 'actor', 'character')
|
||||
facet_keys = person_keys + ('country', 'language', 'genre', 'keyword')
|
||||
|
|
@ -228,7 +224,7 @@ class Item(models.Model):
|
|||
published = models.DateTimeField(default=datetime.now, editable=False)
|
||||
|
||||
#only items that have data from files are available,
|
||||
#this is indicated by setting available to True
|
||||
#this is indicated by setting available to True
|
||||
available = models.BooleanField(default=False, db_index=True)
|
||||
itemId = models.CharField(max_length=128, unique=True, blank=True)
|
||||
oxdbId = models.CharField(max_length=42, unique=True, blank=True)
|
||||
|
|
@ -258,9 +254,9 @@ class Item(models.Model):
|
|||
|
||||
def edit(self, data):
|
||||
#FIXME: how to map the keys to the right place to write them to?
|
||||
for key in data:
|
||||
if key != 'id':
|
||||
setattr(self.data, key, data[key])
|
||||
for key in data:
|
||||
if key != 'id':
|
||||
setattr(self.data, key, data[key])
|
||||
self.oxdb.save()
|
||||
self.save()
|
||||
|
||||
|
|
@ -339,11 +335,11 @@ class Item(models.Model):
|
|||
#FIXME: this should not be used
|
||||
_public_fields = {
|
||||
'itemId': 'id',
|
||||
'title': 'title',
|
||||
'year': 'year',
|
||||
'title': 'title',
|
||||
'year': 'year',
|
||||
|
||||
'runtime': 'runtime',
|
||||
'release_date': 'release_date',
|
||||
'runtime': 'runtime',
|
||||
'release_date': 'release_date',
|
||||
|
||||
'countries': 'country',
|
||||
'directors': 'director',
|
||||
|
|
@ -402,7 +398,7 @@ class Item(models.Model):
|
|||
s = self.streams.all()[0]
|
||||
if s.video and s.info:
|
||||
stream['duration'] = s.info['duration']
|
||||
if 'video' in s.info and s.info['video']:
|
||||
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.itemId
|
||||
|
|
@ -414,7 +410,7 @@ class Item(models.Model):
|
|||
def get_layers(self):
|
||||
layers = {}
|
||||
layers['cuts'] = self.data.get('cuts', {})
|
||||
|
||||
|
||||
layers['subtitles'] = {}
|
||||
#FIXME: subtitles should be stored in Annotation
|
||||
qs = self.files.filter(is_subtitle=True, is_main=True, available=True)
|
||||
|
|
@ -468,7 +464,9 @@ class Item(models.Model):
|
|||
'''
|
||||
Search related functions
|
||||
'''
|
||||
|
||||
def update_find(self):
|
||||
|
||||
def save(key, value):
|
||||
f, created = ItemFind.objects.get_or_create(item=self, key=key)
|
||||
if value not in ('', '||'):
|
||||
|
|
@ -478,7 +476,7 @@ class Item(models.Model):
|
|||
f.delete()
|
||||
|
||||
save('title', '\n'.join([self.get('title'), self.get('original_title', '')]))
|
||||
|
||||
|
||||
#FIXME: filter us/int title
|
||||
#f.title += ' '.join([t.title for t in self.alternative_titles()])
|
||||
|
||||
|
|
@ -537,17 +535,17 @@ class Item(models.Model):
|
|||
|
||||
for key in ('keywords', 'genres', 'cast', 'summary', 'trivia', 'connections'):
|
||||
setattr(s, key, len(self.get(key, '')))
|
||||
|
||||
|
||||
s.itemId = self.itemId.replace('0x', 'xx')
|
||||
s.rating = self.get('rating', -1)
|
||||
s.votes = self.get('votes', -1)
|
||||
|
||||
# data from related subtitles
|
||||
s.scenes = 0 #FIXME
|
||||
s.dialog = 0 #FIXME
|
||||
s.words = 0 #FIXME
|
||||
s.wpm = 0 #FIXME
|
||||
s.risk = 0 #FIXME
|
||||
s.dialog = 0 #FIXME
|
||||
s.words = 0 #FIXME
|
||||
s.wpm = 0 #FIXME
|
||||
s.risk = 0 #FIXME
|
||||
# data from related files
|
||||
videos = self.main_videos()
|
||||
if len(videos) > 0:
|
||||
|
|
@ -574,7 +572,7 @@ class Item(models.Model):
|
|||
s.color = int(sum(self.data.get('color', [])))
|
||||
s.saturation = 0 #FIXME
|
||||
s.brightness = 0 #FIXME
|
||||
|
||||
|
||||
s.cuts = len(self.data.get('cuts', []))
|
||||
if s.duration:
|
||||
s.cutsperminute = s.cuts / (s.duration/60)
|
||||
|
|
@ -585,13 +583,13 @@ class Item(models.Model):
|
|||
if not getattr(s, key):
|
||||
setattr(s, key, u'zzzzzzzzzzzzzzzzzzzzzzzzz')
|
||||
if not s.year:
|
||||
s.year_desc = '';
|
||||
s.year = '9999';
|
||||
s.year_desc = ''
|
||||
s.year = '9999'
|
||||
#FIXME: also deal with number based rows like genre, keywords etc
|
||||
s.save()
|
||||
|
||||
def update_facets(self):
|
||||
#FIXME: what to do with Unkown Director, Year, Country etc.
|
||||
#FIXME: what to do with Unkown Director, Year, Country etc.
|
||||
for key in self.facet_keys:
|
||||
if key == 'actor':
|
||||
current_values = [i[0] for i in self.get('actor', [])]
|
||||
|
|
@ -616,7 +614,7 @@ class Item(models.Model):
|
|||
f, created = Facet.objects.get_or_create(key='year', value=year, value_sort=year, item=self)
|
||||
else:
|
||||
Facet.objects.filter(item=self, key='year').delete()
|
||||
|
||||
|
||||
def path(self, name=''):
|
||||
h = self.itemId
|
||||
return os.path.join('items', h[:2], h[2:4], h[4:6], h[6:], name)
|
||||
|
|
@ -624,6 +622,7 @@ class Item(models.Model):
|
|||
'''
|
||||
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, self.path(), 'frames', "%d"%width, "%s.jpg"%position)
|
||||
|
|
@ -647,14 +646,14 @@ class Item(models.Model):
|
|||
first.width == v.width and first.height == v.height:
|
||||
return True
|
||||
return False
|
||||
videos = filter(check, videos)
|
||||
videos = filter(check, videos)
|
||||
return videos
|
||||
|
||||
def update_streams(self):
|
||||
files = {}
|
||||
for f in self.main_videos():
|
||||
files[utils.sort_title(f.name)] = f.video.path
|
||||
|
||||
|
||||
#FIXME: how to detect if something changed?
|
||||
if files:
|
||||
stream, created = Stream.objects.get_or_create(item=self, profile='%s.webm' % settings.VIDEO_PROFILE)
|
||||
|
|
@ -693,6 +692,7 @@ class Item(models.Model):
|
|||
'''
|
||||
Poster related functions
|
||||
'''
|
||||
|
||||
def update_poster_urls(self):
|
||||
_current = {}
|
||||
for s in settings.POSTER_SERVICES:
|
||||
|
|
@ -781,12 +781,14 @@ class Item(models.Model):
|
|||
p.wait()
|
||||
return posters.keys()
|
||||
|
||||
|
||||
class ItemFind(models.Model):
|
||||
"""
|
||||
used to find items,
|
||||
item.update_find populates this table
|
||||
its used in manager.ItemManager
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
unique_together = ("item", "key")
|
||||
|
||||
|
|
@ -794,8 +796,9 @@ class ItemFind(models.Model):
|
|||
key = models.CharField(max_length=200, db_index=True)
|
||||
value = models.TextField(blank=True)
|
||||
|
||||
#FIXME: make sort based on site.json
|
||||
|
||||
class ItemSort(models.Model):
|
||||
#FIXME: make sort based on site.json
|
||||
"""
|
||||
used to sort items, all sort values are in here
|
||||
"""
|
||||
|
|
@ -872,6 +875,7 @@ class ItemSort(models.Model):
|
|||
return tuple(fields)
|
||||
fields = classmethod(fields)
|
||||
|
||||
|
||||
class Facet(models.Model):
|
||||
item = models.ForeignKey('Item', related_name='facets')
|
||||
key = models.CharField(max_length=200, db_index=True)
|
||||
|
|
@ -883,7 +887,9 @@ class Facet(models.Model):
|
|||
self.value_sort = self.value
|
||||
super(Facet, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class Stream(models.Model):
|
||||
|
||||
class Meta:
|
||||
unique_together = ("item", "profile")
|
||||
|
||||
|
|
@ -899,7 +905,7 @@ class Stream(models.Model):
|
|||
|
||||
def path(self):
|
||||
return self.item.path(self.profile)
|
||||
|
||||
|
||||
def extract_derivatives(self):
|
||||
if settings.VIDEO_H264:
|
||||
profile = self.profile.replace('.webm', '.mp4')
|
||||
|
|
@ -945,7 +951,9 @@ class Stream(models.Model):
|
|||
self.info = ox.avinfo(self.video.path)
|
||||
super(Stream, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class PosterUrl(models.Model):
|
||||
|
||||
class Meta:
|
||||
unique_together = ("item", "service", "url")
|
||||
ordering = ('-height', )
|
||||
|
|
@ -958,4 +966,3 @@ class PosterUrl(models.Model):
|
|||
|
||||
def __unicode__(self):
|
||||
return u'%s %s %dx%d' % (unicode(self.item), self.service, self.width, self.height)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,16 +11,19 @@ import models
|
|||
def cronjob(**kwargs):
|
||||
print "do some cleanup stuff once a day"
|
||||
|
||||
|
||||
@task(ignore_resulsts=True, queue='default')
|
||||
def update_poster(itemId):
|
||||
item = models.Item.objects.get(itemId=itemId)
|
||||
item.make_poster(True)
|
||||
|
||||
|
||||
@task(ignore_resulsts=True, queue='default')
|
||||
def update_imdb(itemId):
|
||||
item = models.Item.objects.get(itemId=itemId)
|
||||
item.update_imdb()
|
||||
|
||||
|
||||
@task(queue="encoding")
|
||||
def update_streams(itemId):
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ Replace these with more appropriate tests for your application.
|
|||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
|
|
@ -20,4 +22,3 @@ Another way to test that 1 + 1 is equal to 2.
|
|||
>>> 1 + 1 == 2
|
||||
True
|
||||
"""}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,4 +13,3 @@ urlpatterns = patterns("item.views",
|
|||
(r'^(?P<id>[A-Z0-9].*)/poster\.jpg$', 'poster'),
|
||||
(r'^(?P<id>[A-Z0-9].*)/timelines/(?P<timeline>.+)\.(?P<size>\d+)\.(?P<position>\d+)\.png$', 'timeline'),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,17 +2,15 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
#
|
||||
import errno
|
||||
from decimal import Decimal
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import hashlib
|
||||
import unicodedata
|
||||
|
||||
import ox
|
||||
import ox.iso
|
||||
from ox.normalize import normalizeName, normalizeTitle, canonicalTitle
|
||||
from ox.normalize import normalizeName, normalizeTitle
|
||||
|
||||
|
||||
def parse_decimal(string):
|
||||
|
|
@ -22,11 +20,13 @@ def parse_decimal(string):
|
|||
d = string.split('/')
|
||||
return Decimal(d[0]) / Decimal(d[1])
|
||||
|
||||
|
||||
def plural_key(term):
|
||||
return {
|
||||
'country': 'countries',
|
||||
}.get(term, term + 's')
|
||||
|
||||
|
||||
def oxid(title, directors, year='', seriesTitle='', episodeTitle='', season=0, episode=0):
|
||||
director = ', '.join(directors)
|
||||
oxid_value = u"\n".join([title, director, year])
|
||||
|
|
@ -38,6 +38,7 @@ def oxid(title, directors, year='', seriesTitle='', episodeTitle='', season=0, e
|
|||
oxid += hashlib.sha1(oxid_value.encode('utf-8')).hexdigest()[:20]
|
||||
return u"0x" + oxid
|
||||
|
||||
|
||||
def oxdb_id(title, directors=[], year='', season='', episode='', episode_title='', episode_directors=[], episode_year=''):
|
||||
# new id function, will replace oxid()
|
||||
def get_hash(string):
|
||||
|
|
@ -51,11 +52,13 @@ def oxdb_id(title, directors=[], year='', season='', episode='', episode_title='
|
|||
get_hash('\n'.join([str(episode), episode_director, episode_title, str(episode_year)]))[:8]
|
||||
return u'0x' + oxdb_id
|
||||
|
||||
|
||||
def oxdb_directors(director):
|
||||
director = os.path.basename(os.path.dirname(director))
|
||||
if director.endswith('_'):
|
||||
director = "%s." % director[:-1]
|
||||
directors = [normalizeName(d) for d in director.split('; ')]
|
||||
|
||||
def cleanup(director):
|
||||
director = director.strip()
|
||||
director = director.replace('Series', '')
|
||||
|
|
@ -65,6 +68,7 @@ def oxdb_directors(director):
|
|||
directors = filter(None, [cleanup(d) for d in directors])
|
||||
return directors
|
||||
|
||||
|
||||
def oxdb_title(_title, searchTitle = False):
|
||||
'''
|
||||
normalize filename to get item title
|
||||
|
|
@ -83,7 +87,7 @@ def oxdb_title(_title, searchTitle = False):
|
|||
else:
|
||||
stitle = _title.split('.')[-2]
|
||||
if stitle.startswith('Episode '):
|
||||
stitle = ''
|
||||
stitle = ''
|
||||
if searchTitle:
|
||||
title = '"%s" %s' % (title, stitle)
|
||||
else:
|
||||
|
|
@ -98,9 +102,11 @@ def oxdb_title(_title, searchTitle = False):
|
|||
title = normalizeTitle(title)
|
||||
return title
|
||||
|
||||
|
||||
def oxdb_year(data):
|
||||
return ox.findRe(data, '\.(\d{4})\.')
|
||||
|
||||
|
||||
def oxdb_series_title(path):
|
||||
seriesTitle = u''
|
||||
if path.startswith('Series'):
|
||||
|
|
@ -111,6 +117,7 @@ def oxdb_series_title(path):
|
|||
seriesTitle = t.split(" (S")[0]
|
||||
return seriesTitle
|
||||
|
||||
|
||||
def oxdb_episode_title(path):
|
||||
episodeTitle = u''
|
||||
ep = re.compile('.Episode \d+?\.(.*?)\.[a-zA-Z]').findall(path)
|
||||
|
|
@ -118,6 +125,7 @@ def oxdb_episode_title(path):
|
|||
episodeTitle = ep[0]
|
||||
return episodeTitle
|
||||
|
||||
|
||||
def oxdb_season_episode(path):
|
||||
season = 0
|
||||
episode = 0
|
||||
|
|
@ -137,6 +145,7 @@ def oxdb_season_episode(path):
|
|||
episode = int(se[0][1])
|
||||
return (season, episode)
|
||||
|
||||
|
||||
def oxdb_part(path):
|
||||
part = 1
|
||||
path = path.lower()
|
||||
|
|
@ -149,6 +158,7 @@ def oxdb_part(path):
|
|||
part = p[0]
|
||||
return part
|
||||
|
||||
|
||||
def parse_path(path):
|
||||
'''
|
||||
expects path in the form
|
||||
|
|
@ -178,6 +188,7 @@ def parse_path(path):
|
|||
episode_year='')
|
||||
return r
|
||||
|
||||
|
||||
def sort_title(title):
|
||||
#title
|
||||
title = re.sub(u'[\'!¿¡,\.;\-"\:\*\[\]]', '', title)
|
||||
|
|
@ -185,9 +196,8 @@ def sort_title(title):
|
|||
#title = title.replace(u'Æ', 'Ae')
|
||||
if isinstance(title, str):
|
||||
title = unicode(title)
|
||||
title = unicodedata.normalize('NFKD',title)
|
||||
title = unicodedata.normalize('NFKD', title)
|
||||
|
||||
#pad numbered titles
|
||||
title = re.sub('(\d+)', lambda x: '%010d' % int(x.group(0)), title)
|
||||
return title.strip()
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,10 @@
|
|||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from __future__ import division
|
||||
import os.path
|
||||
import re
|
||||
from datetime import datetime
|
||||
from urllib2 import unquote
|
||||
import mimetypes
|
||||
|
||||
from django import forms
|
||||
from django.core.paginator import Paginator
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import Q, Avg, Count, Sum
|
||||
from django.db.models import Count, Sum
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404, redirect
|
||||
from django.template import RequestContext
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.conf import settings
|
||||
|
||||
from ox.utils import json
|
||||
|
|
@ -28,13 +19,13 @@ import models
|
|||
import utils
|
||||
import tasks
|
||||
|
||||
from user.models import get_user_json
|
||||
|
||||
from archive.models import File
|
||||
from archive import extract
|
||||
|
||||
from api.actions import actions
|
||||
|
||||
|
||||
def _order_query(qs, sort, prefix='sort__'):
|
||||
order_by = []
|
||||
if len(sort) == 1:
|
||||
|
|
@ -44,7 +35,8 @@ def _order_query(qs, sort, prefix='sort__'):
|
|||
sort.append({'operator': '+', 'key': 'director'})
|
||||
for e in sort:
|
||||
operator = e['operator']
|
||||
if operator != '-': operator = ''
|
||||
if operator != '-':
|
||||
operator = ''
|
||||
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'):
|
||||
|
|
@ -82,7 +74,7 @@ def find(request):
|
|||
'sort': array,
|
||||
'range': array
|
||||
}
|
||||
|
||||
|
||||
query: query object, more on query syntax at
|
||||
https://wiki.0x2620.org/wiki/pandora/QuerySyntax
|
||||
sort: array of key, operator dics
|
||||
|
|
@ -111,7 +103,7 @@ Groups
|
|||
'group': string,
|
||||
'range': array
|
||||
}
|
||||
|
||||
|
||||
query: query object, more on query syntax at
|
||||
https://wiki.0x2620.org/wiki/pandora/QuerySyntax
|
||||
range: result range, array [from, to]
|
||||
|
|
@ -134,7 +126,7 @@ Positions
|
|||
'query': query,
|
||||
'ids': []
|
||||
}
|
||||
|
||||
|
||||
query: query object, more on query syntax at
|
||||
https://wiki.0x2620.org/wiki/pandora/QuerySyntax
|
||||
ids: ids of items for which positions are required
|
||||
|
|
@ -143,7 +135,7 @@ Positions
|
|||
if settings.JSON_DEBUG:
|
||||
print json.dumps(data, indent=2)
|
||||
query = _parse_query(data, request.user)
|
||||
|
||||
|
||||
response = json_response({})
|
||||
if 'group' in query:
|
||||
if 'sort' in query:
|
||||
|
|
@ -183,7 +175,7 @@ Positions
|
|||
elif 'ids' in query:
|
||||
#FIXME: this does not scale for larger results
|
||||
qs = _order_query(query['qs'], query['sort'])
|
||||
|
||||
|
||||
response['data']['positions'] = {}
|
||||
ids = [j['itemId'] for j in qs.values('itemId')]
|
||||
response['data']['positions'] = _get_positions(ids, query['ids'])
|
||||
|
|
@ -371,7 +363,8 @@ def getImdbId(request):
|
|||
}
|
||||
}
|
||||
'''
|
||||
imdbId = ox.web.imdb.guess(search_title, r['director'], timeout=-1)
|
||||
data = json.loads(request.POST['data'])
|
||||
imdbId = ox.web.imdb.getImdbId(data['title'], data['director'], timeout=-1)
|
||||
if imdbId:
|
||||
response = json_response({'imdbId': imdbId})
|
||||
else:
|
||||
|
|
@ -406,7 +399,8 @@ def poster(request, id, size=None):
|
|||
else:
|
||||
poster_path = item.poster.path
|
||||
else:
|
||||
if not size: size='large'
|
||||
if not size:
|
||||
size='large'
|
||||
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')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue