data/external_data, start properties for items and bin editing

This commit is contained in:
j 2010-11-14 22:49:16 +01:00
parent 67a31d1f58
commit 7f9a4e252e
4 changed files with 214 additions and 20 deletions

6
README
View file

@ -30,9 +30,11 @@ Install rabbitmq and carrot:
Development:
we are using django, http://docs.djangoproject.com/en/dev/
Nginx setup:
sudo apt-get install nginx
Apache setup:
sudo apt-get install libapache2-mod-wsgi libapache2-mod-xsendfile
or if you use apache:
sudo apt-get install libapache2-mod-xsendfile
add pandora repository:
sudo apt-get install python-software-properties

View file

@ -9,6 +9,7 @@ from oxdjango.shortcuts import json_response, render_to_json_response, get_objec
import models
from api.views import html_snapshot
from item.models import siteJson
def intro(request):
context = RequestContext(request, {'settings':settings})
@ -32,9 +33,11 @@ def api_getPage(request):
return render_to_json_response(response)
def site_json(request):
return render_to_json_response(siteJson())
'''
siteSettings = {}
for s in models.SiteSettings.objects.all():
siteSettings[s.key] = s.value
context = RequestContext(request, {'settings':settings, 'siteSettings': siteSettings})
return render_to_response('site.json', context, mimetype="application/javascript")
'''

View file

View file

@ -29,6 +29,195 @@ import utils
from archive import extract
class Property(models.Model):
name = models.CharField(null=True, max_length=255, unique=True)
title = models.CharField(null=True, max_length=255)
#types: string, person, role, location, date, array
type = models.CharField(null=True, max_length=255)
array = models.BooleanField(default=False)
position = models.IntegerField(default=0)
#sort values: title, string, integer, float, date
sort = models.CharField(null=True, max_length=255)
totals = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
def json(self):
j = {}
for key in ('type', 'sort', 'title', 'array', 'totals', 'admin'):
value = getattr(self, key)
if value:
j[key] = value
return j
class Bin(models.Model):
name = models.CharField(null=True, max_length=255, unique=True)
title = models.CharField(null=True, max_length=255)
#types: keyword, location, text
type = models.CharField(null=True, max_length=255)
position = models.IntegerField(default=0)
overlapping = models.BooleanField(default=True)
find = models.BooleanField(default=True)
#words / item duration(wpm), total words, cuts per minute, cuts, number of layers, number of layers/duration
sort = models.CharField(null=True, max_length=255)
def properties(self):
p = {}
if self.find:
p[self.name] = {'type': 'bin', 'find': True}
if self.sort:
print 'FIXME: need to add sort stuff'
return p
properties = {
'title': {'type': 'string', 'sort': 'title', 'find': True},
'director': {'type': 'person', 'array': True, 'sort': 'string', 'find': True},
'country': {'type': 'string', 'array': True, 'sort': 'sring', 'find': True},
'year': {'type': 'string', 'sort': 'string', 'find': True},
'language': {'type': 'string', 'array': True, 'sort': 'string', 'find': True},
'runtime': {'type': 'integer', 'sort': 'integer'},
'writer': {'type': 'person', 'array': True, 'sort': 'string', 'find': True},
'producer': {'type': 'person', 'array': True, 'sort': 'string', 'find': True},
'cinematographer': {'type': 'person', 'array': True, 'sort': 'string', 'find': True},
'editor': {'type': 'person', 'array': True, 'sort': 'string', 'find': True},
'actors': {'type': 'role', 'array': True, 'sort': 'length', 'find': True},
'genre': {'type': 'string', 'array': True, 'sort': 'length', 'find': True},
'keywords': {'type': 'string', 'array': True, 'sort': 'length', 'find': True},
'summary': {'type': 'title', 'sort': 'length', 'find': True},
'trivia': {'type': 'title', 'sort': 'length', 'find': True},
'releasedate': {'type': 'date', 'sort': 'date', 'find': True},
'runtime': {'type': 'integer', 'sort': 'integer', 'totals': True},
'budget': {'type': 'float', 'sort': 'float'},
'gross': {'type': 'float', 'sort': 'float'},
'profit': {'type': 'float', 'sort': 'float'},
'rating': {'type': 'integer', 'sort': 'integer'},
'votes': {'type': 'integer', 'sort': 'integer'},
'published': {'type': 'date', 'sort': 'date'},
'modified': {'type': 'date', 'sort': 'date'},
'popularity': {'type': 'date', 'sort': 'date'},
#file properties // are those even configurable? think not
'aspectratio': {'type': 'faction', 'sort': 'float'},
'duration': {'type': 'float', 'sort': 'float', 'totals': True, "admin": True},
'color': {'type': 'color', 'sort': 'color'},
'saturation': {'type': 'integer', 'sort': 'integer'},
'brightness': {'type': 'integer', 'sort': 'integer'},
'volume': {'type': 'integer', 'sort': 'integer'},
'resolution': {'type': 'integer', 'array': True, 'sort': 'integer'}, #FIXME
'pixels': {'type': 'integer', 'sort': 'string', 'totals': True},
'size': {'type': 'title', 'sort': 'string', 'totals': True, 'admin': True},
'bitrate': {'type': 'title', 'sort': 'string'},
'files': {'type': 'title', 'sort': 'string', 'totals': True, 'admin': True},
'filename': {'type': 'title', 'sort': 'string'},
#Layer properties // those need to be defined with bins
'dialog': {'type': 'title', 'find': True},
#'clips': {'type': 'title', 'sort': 'string'},
#'cuts': {'type': 'title', 'sort': 'string'},
'cutsperminute': {'type': 'integer', 'title': 'Cuts per minute', 'sort': 'string'},
'words': {'type': 'title', 'sort': 'string'},
'wordsperminute': {'type': 'integer','title': 'Words per minute', 'sort': 'string'},
}
def siteJson():
r = {}
r['findKeys'] = [{"id": "all", "title": "All"}]
for k in properties:
i = properties[k]
if i.get('find', False):
f = {"id": k, "title": i.get('title', k.capitalize())}
if i.get('autocomplete', False):
f['autocomplete'] = True
r['findKeys'].append(f)
r['groups'] = filter(lambda k: 'array' in properties[k], properties.keys())
r['itemViews'] = [
{"id": "info", "title": "Info"},
{"id": "statistics", "title": "Statistics"},
{"id": "clips", "title": "Clips"},
{"id": "timeline", "title": "Timeline"},
{"id": "map", "title": "Map"},
{"id": "calendar", "title": "Calendar"},
{"id": "files", "title": "Files", "admin": True}
]
r['listViews'] = [
{"id": "list", "title": "as List"},
{"id": "icons", "title": "as Icons"},
{"id": "info", "title": "with Info"},
{"id": "clips", "title": "with Clips"},
{"id": "timelines", "title": "with Timelines"},
{"id": "maps", "title": "with Maps"},
{"id": "calendars", "title": "with Calendars"},
{"id": "clip", "title": "as Clips"},
{"id": "map", "title": "on Map"},
{"id": "calendar", "title": "on Calendar"}
]
r['site'] = {
"name": settings.SITENAME,
"id": settings.SITEID,
"url": settings.URL
}
r['sections'] = [
{"id": "history", "title": "History"},
{"id": "lists", "title": "My Lists"},
{"id": "public", "title": "Public Lists"},
{"id": "featured", "title": "Featured Lists"}
]
r['sortKeys'] = []
for k in properties:
i = properties[k]
if 'sort' in i:
f = {
"id": k,
"title": i.get('title', k.capitalize()),
"operator": i.get('operator', ''),
"align": i.get('align', 'left'),
"width": i.get('width', 180),
}
if not i.get('removable', True):
f['removable'] = False
r['sortKeys'].append(f)
r['totals'] = [{"id": "items"}]
for k in properties:
i = properties[k]
if i.get('totals', False):
f = {"id": k}
if i.get('admin', False):
f['admin'] = True
r['totals'].append(f)
#FIXME: defaults should also be populated from properties
r["user"] = {
"group": "guest",
"preferences": {},
"ui": {
"columns": ["id", "title", "director", "country", "year", "language", "genre"],
"findQuery": {"conditions": [], "operator": ""},
"groupsQuery": {"conditions": [], "operator": "|"},
"groupsSize": 128,
"itemView": "info",
"listQuery": {"conditions": [], "operator": ""},
"listsSize": 192,
"listView": "list",
"sections": ["history", "lists", "public", "featured"],
"showGroups": True,
"showInfo": True,
"showLists": True,
"showMovies": True,
"sort": [
{"key": "director", "operator": ""}
],
"theme": "classic"
},
"username": ""
}
return r
def getItem(info):
'''
info dict with:
@ -40,7 +229,7 @@ def getItem(info):
except Item.DoesNotExist:
item = Item(itemId=info['imdbId'])
if 'title' in info and 'directors' in info:
item.imdb = {
item.external_data = {
'title': info['title'],
'directors': info['directors'],
'year': info.get('year', '')
@ -59,7 +248,7 @@ def getItem(info):
item = Item.objects.get(itemId=info['oxdbId'])
except Item.DoesNotExist:
item = Item()
item.metadata = {
item.data = {
'title': info['title'],
'directors': info['directors'],
'year': info.get('year', '')
@ -68,7 +257,7 @@ def getItem(info):
for key in ('episode_title', 'series_title', 'season', 'episode'):
if key in info and info[key]:
item.metadata[key] = info[key]
item.data[key] = info[key]
item.save()
return item
@ -80,7 +269,7 @@ class Item(models.Model):
modified = models.DateTimeField(auto_now=True)
published = models.DateTimeField(default=datetime.now, editable=False)
#only items that have metadata from files are available,
#only items that have data from files are available,
#this is indicated by setting available to True
available = models.BooleanField(default=False, db_index=True)
@ -90,10 +279,10 @@ class Item(models.Model):
objects = managers.ItemManager()
def get(self, key, default=None):
if self.metadata and key in self.metadata:
return self.metadata[key]
if self.imdb and key in self.imdb:
return self.imdb[key]
if self.data and key in self.data:
return self.data[key]
if self.external_data and key in self.external_data:
return self.external_data[key]
return default
def editable(self, user):
@ -104,7 +293,7 @@ class Item(models.Model):
#FIXME: how to map the keys to the right place to write them to?
for key in data:
if key != 'id':
setattr(self.metadata, key, data[key])
setattr(self.data, key, data[key])
self.oxdb.save()
self.save()
@ -118,14 +307,14 @@ class Item(models.Model):
_reviews[w.title] = r[0]
return _reviews
imdb = fields.DictField(default={}, editable=False)
metadata = fields.DictField(default={}, editable=False)
external_data = fields.DictField(default={}, editable=False)
data = fields.DictField(default={}, editable=False)
json = fields.DictField(default={}, editable=False)
def updateImdb(self):
if len(self.itemId) == 7:
self.imdb = ox.web.imdb.Imdb(self.itemId)
self.external_data = ox.web.imdb.Imdb(self.itemId)
self.save()
poster = models.ImageField(default=None, blank=True, upload_to=lambda m, x: os.path.join(itemid_path(m.itemId), "poster.jpg"))
@ -272,7 +461,7 @@ class Item(models.Model):
def get_layers(self):
layers = {}
layers['cuts'] = self.metadata.get('cuts', {})
layers['cuts'] = self.data.get('cuts', {})
layers['subtitles'] = {}
#FIXME: subtitles should be stored in Layer
@ -491,9 +680,9 @@ class Item(models.Model):
if 'video' in stream.info:
extract.timeline(stream.video.path, self.timeline_prefix)
self.stream_aspect = stream.info['video'][0]['width']/stream.info['video'][0]['height']
self.metadata['cuts'] = extract.cuts(self.timeline_prefix)
self.metadata['average_color'] = extract.average_color(self.timeline_prefix)
#extract.timeline_strip(self, self.metadata['cuts'], stream.info, self.timeline_prefix[:-8])
self.data['cuts'] = extract.cuts(self.timeline_prefix)
self.data['average_color'] = extract.average_color(self.timeline_prefix)
#extract.timeline_strip(self, self.data['cuts'], stream.info, self.timeline_prefix[:-8])
stream.extract_derivatives()
#something with poster
@ -683,7 +872,7 @@ class Facet(models.Model):
def getPersonSort(name):
person, created = Person.objects.get_or_create(name=name)
name_sort = person.name_sort.replace(u'\xc5k', 'A')
name_sort = unicodedata.normalize('NFKD', person.name_sort)
return name_sort
class Person(models.Model):