better demo config and info view

always pass oxdbId to poster script
use 0xdb like poster script for demo
This commit is contained in:
j 2012-06-13 17:59:10 +02:00
parent e4d0660074
commit 70892dd463
9 changed files with 183 additions and 316 deletions

View File

@ -62,7 +62,7 @@ def reloader_thread():
load_config() load_config()
_config_mtime = mtime _config_mtime = mtime
except: except:
print "reloading config failed" sys.stderr.write("reloading config failed\n")
time.sleep(1) time.sleep(1)
def update_static(): def update_static():

View File

@ -112,7 +112,7 @@ def getPage(request):
name = data['name'] name = data['name']
page, created = models.Page.objects.get_or_create(name=name) page, created = models.Page.objects.get_or_create(name=name)
if created: if created:
page.text= 'Insert text here' page.text= ''
page.save() page.save()
response = json_response({'name': page.name, 'text': page.text}) response = json_response({'name': page.name, 'text': page.text})
return render_to_json_response(response) return render_to_json_response(response)

View File

@ -8,7 +8,7 @@
{"key": "title", "operator": "+"} {"key": "title", "operator": "+"}
], ],
"annotations": { "annotations": {
"showUsers": true "showUsers": false
}, },
"cantPlay": { "cantPlay": {
"icon": "", "icon": "",
@ -66,17 +66,14 @@
text of clips. Excluding a layer from this list means it will not be text of clips. Excluding a layer from this list means it will not be
included in find annotations. // FIXME: the last bit is not implemented. included in find annotations. // FIXME: the last bit is not implemented.
*/ */
"clipLayers": ["transcripts", "keywords", "places", "events", "descriptions"], "clipLayers": ["publicnotes", "keywords", "subtitles"],
// fixme: either this, or filter: true in itemKeys, but not both // fixme: either this, or filter: true in itemKeys, but not both
"filters": [ "filters": [
{"id": "source", "title": "Sources", "type": "string"}, {"id": "director", "title": "Director", "type": "string"},
{"id": "project", "title": "Projects", "type": "string"}, {"id": "country", "title": "Country", "type": "string"},
{"id": "topic", "title": "Topics", "type": "string"}, {"id": "year", "title": "Year", "type": "integer"},
{"id": "name", "title": "People", "type": "string"},
{"id": "language", "title": "Languages", "type": "string"}, {"id": "language", "title": "Languages", "type": "string"},
{"id": "license", "title": "License", "type": "string"}, {"id": "featuring", "title": "Featuring", "type": "string"},
{"id": "places", "title": "Places", "type": "string"},
{"id": "events", "title": "Events", "type": "string"},
{"id": "keywords", "title": "Keywords", "type": "string"} {"id": "keywords", "title": "Keywords", "type": "string"}
], ],
/* /*
@ -120,41 +117,9 @@
"sort": true, "sort": true,
"sortType": "title" "sortType": "title"
}, },
{
"id": "source",
"title": "Source",
"type": "string",
"autocomplete": true,
"description": true,
"columnWidth": 180,
"filter": true,
"find": true,
"sort": true
},
{
"id": "project",
"title": "Project",
"type": "string",
"autocomplete": true,
"description": true,
"columnWidth": 120,
"filter": true,
"find": true,
"sort": true
},
{
"id": "topic",
"title": "Topic",
"type": ["string"],
"autocomplete": true,
"columnWidth": 180,
"filter": true,
"find": true,
"sort": true
},
{ {
"id": "name", "id": "name",
"title": "People", "title": "Name",
"type": ["string"], "type": ["string"],
"autocomplete": true, "autocomplete": true,
"find": true "find": true
@ -169,15 +134,6 @@
"sort": true, "sort": true,
"sortType": "person" "sortType": "person"
}, },
{
"id": "cinematographer",
"title": "Cinematographer",
"type": ["string"],
"autocomplete": true,
"columnWidth": 180,
"sort": true,
"sortType": "person"
},
{ {
"id": "featuring", "id": "featuring",
"title": "Featuring", "title": "Featuring",
@ -200,8 +156,8 @@
"sort": true "sort": true
}, },
{ {
"id": "location", "id": "country",
"title": "Location", "title": "Contry",
"type": "string", "type": "string",
"autocomplete": true, "autocomplete": true,
"columnWidth": 180, "columnWidth": 180,
@ -210,11 +166,14 @@
"sort": true "sort": true
}, },
{ {
"id": "date", "id": "year",
"title": "Date", "title": "Year",
"type": "string", "type": "year",
"columnWidth": 120, "additionalSort": [{"key": "director", "operator": "+"}, {"key": "title", "operator": "+"}],
//"format": {"type": "date", "args": ["%a, %b %e, %Y"]}, "autocomplete": true,
"columnWidth": 60,
"filter": true,
"find": true,
"sort": true "sort": true
}, },
{ {
@ -230,24 +189,6 @@
"columnWidth": 90, "columnWidth": 90,
"sort": true "sort": true
}, },
{
"id": "annotations",
"title": "Annotations",
"type": "string",
"find": true
},
{
"id": "places",
"title": "Places",
"type": "layer",
"find": true
},
{
"id": "events",
"title": "Events",
"type": "layer",
"find": true
},
{ {
"id": "keywords", "id": "keywords",
"title": "Keywords", "title": "Keywords",
@ -255,14 +196,14 @@
"find": true "find": true
}, },
{ {
"id": "descriptions", "id": "subtitles",
"title": "Descriptions", "title": "Subtitles",
"type": "layer", "type": "layer",
"find": true "find": true
}, },
{ {
"id": "transcripts", "id": "publicnotes",
"title": "Transcripts", "title": "Notes",
"type": "layer", "type": "layer",
"find": true "find": true
}, },
@ -405,14 +346,7 @@
"title": "User", "title": "User",
"type": "string", "type": "string",
"capability": "canSeeFiles", "capability": "canSeeFiles",
"find": true "find": false
},
{
"id": "filename",
"title": "Filename",
"type": ["string"],
"capability": "canSeeFiles",
"find": true
}, },
{ {
"id": "created", "id": "created",
@ -448,14 +382,6 @@
"format": {"type": "date", "args": ["%Y-%m-%d %H:%M:%S"]}, "format": {"type": "date", "args": ["%Y-%m-%d %H:%M:%S"]},
"sort": true "sort": true
}, },
{
"id": "license",
"title": "License",
"type": ["string"],
"columnWidth": 120,
"filter": true,
"sort": true
},
{ {
"id": "rightslevel", "id": "rightslevel",
"title": "Rights Level", "title": "Rights Level",
@ -492,43 +418,44 @@
], ],
"layers": [ "layers": [
{ {
"id": "places", "id": "privatenotes",
"title": "Places", "title": "Private Notes",
"canAddAnnotations": {"member": true, "staff": true, "admin": true}, "canAddAnnotations": {"member": true, "staff": true, "admin": true},
"item": "Place", "item": "Note",
"overlap": true, "overlap": true,
"type": "place" "private": true,
"showInfo": true,
"type": "text"
}, },
{ {
"id": "events", "id": "publicnotes",
"title": "Events", "title": "Notes",
"canAddAnnotations": {"member": true, "staff": true, "admin": true}, "canAddAnnotations": {"member": true, "staff": true, "admin": true},
"item": "Event", "hasEvents": true,
"hasPlaces": true,
"item": "Note",
"overlap": true, "overlap": true,
"type": "event" "showInfo": true,
"type": "text"
}, },
{ {
"id": "keywords", "id": "keywords",
"title": "Keywords", "title": "Keywords",
"canAddAnnotations": {"member": true, "staff": true, "admin": true}, "canAddAnnotations": {"member": true, "staff": true, "admin": true},
"hasEvents": true,
"hasPlaces": true,
"item": "Keyword", "item": "Keyword",
"overlap": true, "overlap": true,
"type": "string" "type": "string"
}, },
{ {
"id": "descriptions", "id": "subtitles",
"title": "Descriptions", "title": "Subtitles",
"canAddAnnotations": {"member": true, "staff": true, "admin": true}, "canAddAnnotations": {"staff": true, "admin": true},
"item": "Description", "hasEvents": true,
"showInfo": true, "hasPlaces": true,
"type": "text" "isSubtitles": true,
}, "item": "Subtitle",
{
"id": "transcripts",
"title": "Transcripts",
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
"item": "Transcript",
"showInfo": true,
"type": "text" "type": "text"
} }
], ],
@ -570,7 +497,7 @@
"system": "system@pandora.local" "system": "system@pandora.local"
}, },
"id": "pandora", "id": "pandora",
"name": "pan.do/ra", "name": "Demo",
"url": "pandora.local", "url": "pandora.local",
"videoprefix": "" "videoprefix": ""
}, },
@ -605,34 +532,33 @@
"annotationsCalendarSize": 128, "annotationsCalendarSize": 128,
"annotationsFont": "small", "annotationsFont": "small",
"annotationsMapSize": 128, "annotationsMapSize": 128,
"annotationsRange": "position", "annotationsRange": "all",
"annotationsSize": 256, "annotationsSize": 256,
"annotationsSort": "position", "annotationsSort": "position",
"clipsColumns": 2, "clipsColumns": 2,
"columns": { "columns": {
"Colors": { "Colors": {
"columns": ["title", "source", "project", "language", "hue", "saturation", "brightness"], "columns": ["title", "director", "language", "hue", "saturation", "brightness"],
"columnWidth": {} "columnWidth": {}
} }
}, },
"filters": [ "filters": [
{"id": "source", "sort": [{"key": "name", "operator": "+"}]}, {"id": "director", "sort": [{"key": "items", "operator": "-"}]},
{"id": "project", "sort": [{"key": "name", "operator": "+"}]}, {"id": "country", "sort": [{"key": "items", "operator": "-"}]},
{"id": "topic", "sort": [{"key": "items", "operator": "-"}]}, {"id": "year", "sort": [{"key": "name", "operator": "+"}]},
{"id": "name", "sort": [{"key": "items", "operator": "-"}]}, {"id": "featuring", "sort": [{"key": "items", "operator": "-"}]},
{"id": "keywords", "sort": [{"key": "items", "operator": "-"}]}, {"id": "keywords", "sort": [{"key": "items", "operator": "-"}]}
{"id": "places", "sort": [{"key": "items", "operator": "-"}]}
], ],
"filtersSize": 176, "filtersSize": 176,
"find": {"conditions": [], "operator": "&"}, "find": {"conditions": [], "operator": "&"},
"followPlayer": true, "followPlayer": true,
"icons": "frames", "icons": "posters",
"infoIconSize": 256, "infoIconSize": 256,
"item": "", "item": "",
"itemFind": "", "itemFind": "",
"itemSort": [{"key": "position", "operator": "+"}], "itemSort": [{"key": "position", "operator": "+"}],
"itemView": "info", "itemView": "info",
"listColumns": ["title", "source", "project", "topic", "language", "duration"], "listColumns": ["title", "director", "year", "language", "duration"],
"listColumnWidth": {}, "listColumnWidth": {},
"listSelection": [], "listSelection": [],
"listSort": [{"key": "title", "operator": "+"}], "listSort": [{"key": "title", "operator": "+"}],
@ -655,11 +581,10 @@
"showIconBrowser": false, "showIconBrowser": false,
"showInfo": true, "showInfo": true,
"showLayers": { "showLayers": {
"places": false,
"events": false,
"keywords": true, "keywords": true,
"descriptions": true, "privatenotes": true,
"transcripts": true "publicnotes": true,
"subtitles": true
}, },
"showMapControls": false, "showMapControls": false,
"showMapLabels": false, "showMapLabels": false,

View File

@ -34,7 +34,7 @@ class Command(BaseCommand):
for f in models.ItemSort._meta.fields: for f in models.ItemSort._meta.fields:
if not f.primary_key: if not f.primary_key:
name = f.name name = f.name
col_type = f.db_type() col_type = f.db_type(connection)
if name not in db_fields: if name not in db_fields:
sql = 'ALTER TABLE "%s" ADD COLUMN "%s" %s' % (table_name, name, col_type) sql = 'ALTER TABLE "%s" ADD COLUMN "%s" %s' % (table_name, name, col_type)
changes.append(sql) changes.append(sql)

View File

@ -314,7 +314,10 @@ class Item(models.Model):
#this does not work if another item without imdbid has the same metadata #this does not work if another item without imdbid has the same metadata
oxdbId = self.oxdb_id() oxdbId = self.oxdb_id()
if oxdbId: if not settings.USE_IMDB:
update_poster = self.oxdbId != oxdbId
self.oxdbId = oxdbId
elif oxdbId:
if self.oxdbId != oxdbId: if self.oxdbId != oxdbId:
q = Item.objects.filter(oxdbId=oxdbId).exclude(id=self.id) q = Item.objects.filter(oxdbId=oxdbId).exclude(id=self.id)
if q.count() != 0: if q.count() != 0:
@ -554,10 +557,8 @@ class Item(models.Model):
return i return i
def oxdb_id(self): def oxdb_id(self):
if not settings.USE_IMDB:
return self.itemId
if not self.get('title') and not self.get('director'): if not self.get('title') and not self.get('director'):
return None return self.itemId
return ox.get_oxid(self.get('seriesTitle', self.get('title', '')), return ox.get_oxid(self.get('seriesTitle', self.get('title', '')),
self.get('director', []), self.get('director', []),
self.get('seriesYear', self.get('year', '')), self.get('seriesYear', self.get('year', '')),
@ -1128,13 +1129,10 @@ class Item(models.Model):
cmd += [ cmd += [
'-l', timeline, '-l', timeline,
] ]
if settings.USE_IMDB: cmd += [
if len(self.itemId) == 7: '-i', self.itemId,
cmd += ['-i', self.itemId] '-o', self.oxdbId or self.oxdb_id() or self.itemId
oxdbId = self.oxdbId or self.oxdb_id() or self.itemId ]
cmd += ['-o', oxdbId]
else:
cmd += ['-i', self.itemId]
ox.makedirs(os.path.join(settings.MEDIA_ROOT,self.path())) ox.makedirs(os.path.join(settings.MEDIA_ROOT,self.path()))
p = subprocess.Popen(cmd) p = subprocess.Popen(cmd)
p.wait() p.wait()

View File

@ -129,7 +129,7 @@ def render_poster(title, director, year, series, oxdb_id, imdb_id, frame, timeli
def main(): def main():
parser = OptionParser() parser = OptionParser()
parser.add_option('-o', '--oxdbid', dest='oxdb_id', help='0xDB Id') parser.add_option('-o', '--oxdbid', dest='oxdb_id', help='0xDB Id')
parser.add_option('-i', '--id', dest='imdb_id', help='Item Id') parser.add_option('-i', '--id', dest='item_id', help='Item Id')
parser.add_option('-t', '--title', dest='title', help='Title') parser.add_option('-t', '--title', dest='title', help='Title')
parser.add_option('-d', '--director', dest='director', help='Director(s)', default='') parser.add_option('-d', '--director', dest='director', help='Director(s)', default='')
parser.add_option('-y', '--year', dest='year', help='Year') parser.add_option('-y', '--year', dest='year', help='Year')
@ -144,7 +144,7 @@ def main():
sys.exit() sys.exit()
opt = {} opt = {}
for key in ('oxdb_id', 'imdb_id', 'title', 'director', 'year', 'series', 'frame', 'timeline', 'poster'): for key in ('oxdb_id', 'item_id', 'title', 'director', 'year', 'series', 'frame', 'timeline', 'poster'):
opt[key] = getattr(options, key) opt[key] = getattr(options, key)
opt['title'] = opt['title'].decode('utf-8') opt['title'] = opt['title'].decode('utf-8')

View File

@ -16,68 +16,140 @@ from optparse import OptionParser
from ox.image import drawText, wrapText from ox.image import drawText, wrapText
import sys import sys
static_root = os.path.join(os.path.dirname(__file__), 'data') static_root = os.path.join(os.path.dirname(__file__), 'data')
def render_poster(id, title, frame, timeline, poster): def render_poster(title, director, year, series, oxdb_id, imdb_id, frame, timeline, poster):
def get_oxdb_color(oxdb_id, series=False):
i = int(round((int(oxdb_id[2:10], 16) * 762 / pow(2, 32))))
if i < 127:
color = (127, i, 0)
elif i < 254:
color = (254 - i, 127, 0)
elif i < 381:
color = (0, 127, i - 254)
elif i < 508:
color = (0, 508 - i, 127)
elif i < 635:
color = (i - 508, 0, 127)
else:
color = (127, 0, 762 - i)
if series:
color = tuple(map(lambda x: x + 128, color))
return color
poster_width = 640 poster_width = 640
poster_height = 1024 poster_height = 1024
poster_ratio = poster_width / poster_height poster_ratio = poster_width / poster_height
poster_color = (255, 255, 0)
poster_image = Image.new('RGB', (poster_width, poster_height)) poster_image = Image.new('RGB', (poster_width, poster_height))
draw = ImageDraw.Draw(poster_image)
font_file = os.path.join(static_root, 'DejaVuSansCondensedBold.ttf') font_file = os.path.join(static_root, 'DejaVuSansCondensedBold.ttf')
font_size = 48
font_size = {
'small': 28,
'large': 42,
}
# frame
frame_width = poster_width
frame_ratio = 4 / 3
frame_height = int(round(frame_width / frame_ratio))
if frame:
frame_image = Image.open(frame)
frame_image_ratio = frame_image.size[0] / frame_image.size[1]
if frame_ratio < frame_image_ratio:
frame_image = frame_image.resize((int(frame_height * frame_image_ratio), frame_height), Image.ANTIALIAS)
left = int((frame_image.size[0] - frame_width) / 2)
frame_image = frame_image.crop((left, 0, left + frame_width, frame_height))
else:
frame_image = frame_image.resize((frame_width, int(frame_width / frame_image_ratio)), Image.ANTIALIAS)
top = int((frame_image.size[1] - frame_height) / 2)
frame_image = frame_image.crop((0, top, frame_width, top + frame_height))
poster_image.paste(frame_image, (0, 0))
# timeline # timeline
timeline_width = poster_width
timeline_height = 64 timeline_height = 64
timeline_lines = 16
if timeline: if timeline:
timeline_image = Image.open(timeline) timeline_image = Image.open(timeline)
timeline_image = timeline_image.resize((10240, timeline_height), Image.ANTIALIAS) timeline_image = timeline_image.resize((timeline_width, timeline_height), Image.ANTIALIAS)
for i in range(timeline_lines): poster_image.paste(timeline_image, (0, frame_height))
line_image = timeline_image.crop((i * poster_width, 0, (i + 1) * poster_width, 64))
poster_image.paste(line_image, (0, i * timeline_height))
# id # text
text = '' + id
text_image = Image.new('RGB', (1, 1))
text_size = drawText(text_image, (0, 0), text, font_file, font_size, poster_color)
text_width = poster_width text_width = poster_width
text_height = timeline_height text_height = poster_height - frame_height - timeline_height
text_left = int((poster_width - text_width) / 2) text_top = frame_height + timeline_height
text_top = 14 * timeline_height text_bottom = text_top + text_height
for y in range(text_top, text_top + text_height): text_margin = 16
for x in range(text_left, text_left + text_width): text_color = get_oxdb_color(oxdb_id, series)
if y < text_top + 4 or y >= text_top + text_height - 4: font_color = tuple(map(lambda x: x - 128 if series else x + 128, text_color))
poster_image.putpixel((x, y), poster_color) draw.rectangle([(0, text_top), (text_width, text_bottom)], fill=text_color)
offset_top = text_top + text_margin
if not director:
title_max_lines = 7
else:
title_max_lines = min(len(wrapText(title, text_width - 2 * text_margin, 0, font_file, font_size['large'])), 6)
director_max_lines = 9 - int((title_max_lines * 3 - 1) / 2)
if director:
lines = wrapText(director, text_width - 2 * text_margin, director_max_lines, font_file, font_size['small'])
for i, line in enumerate(lines):
size = drawText(poster_image, (text_margin, offset_top), line, font_file, font_size['small'], font_color)
offset_top += font_size['small'] + 2
offset_top += size[1] - font_size['small'] + text_margin / 2
lines = wrapText(title, text_width - 2 * text_margin, title_max_lines, font_file, font_size['large'])
for i, line in enumerate(lines):
size = drawText(poster_image, (text_margin, offset_top + 5), line, font_file, font_size['large'], font_color)
offset_top += font_size['large'] + 3
offset_top += size[1] - font_size['small'] + text_margin / 2
if year:
drawText(poster_image, (text_margin, offset_top), year, font_file, font_size['small'], font_color)
item_id = imdb_id or oxdb_id
drawText(poster_image, (text_margin, text_bottom - text_margin - font_size['large'] + 2), item_id, font_file, font_size['large'], font_color)
'''
# logo
logo_height = 32
logo_image = Image.open(os.path.join(static_root, '..', '..', 'static', 'png', 'logo.png'))
logo_width = int(round(logo_height * logo_image.size[0] / logo_image.size[1]))
logo_image = logo_image.resize((logo_width, logo_height), Image.ANTIALIAS)
logo_left = text_width - text_margin - logo_width
logo_top = text_bottom - text_margin - logo_height
for y in range(logo_height):
for x in range(logo_width):
poster_color = poster_image.getpixel((logo_left + x, logo_top + y))
logo_color = logo_image.getpixel((x, y))[0]
alpha = logo_image.getpixel((x, y))[3]
if series:
poster_color = tuple(map(lambda x: int(x - (logo_color - 16) * alpha / 255), poster_color))
else: else:
pixel = list(poster_image.getpixel((x, y))) poster_color = tuple(map(lambda x: int(x + (logo_color - 16) * alpha / 255), poster_color))
for c in range(3): poster_image.putpixel((logo_left + x, logo_top + y), poster_color)
pixel[c] = int((pixel[c] + poster_color[c]) / 4) i '''
poster_image.putpixel((x, y), tuple(pixel))
drawText(poster_image, ((poster_width - text_size[0]) / 2, text_top + (text_height - text_size[1]) / 2), text, font_file, font_size, poster_color)
poster_image.save(poster) poster_image.save(poster)
def main(): def main():
parser = OptionParser() parser = OptionParser()
parser.add_option('-o', '--oxdbid', dest='oxdb_id', help='0xDB Id') parser.add_option('-o', '--oxdbid', dest='oxdb_id', help='0xDB Id')
parser.add_option('-i', '--id', dest='id', help='Item Id') parser.add_option('-i', '--id', dest='imdb_id', help='Item Id')
parser.add_option('-t', '--title', dest='title', help='Title', default='') parser.add_option('-t', '--title', dest='title', help='Title')
parser.add_option('-d', '--director', dest='director', help='Director', default='') parser.add_option('-d', '--director', dest='director', help='Director(s)', default='')
parser.add_option('-y', '--year', dest='year', help='Year', default='') parser.add_option('-y', '--year', dest='year', help='Year')
parser.add_option('-s', '--series', dest='series', help='Movie is an episode of a series', action='store_true')
parser.add_option('-f', '--frame', dest='frame', help='Poster frame (image file to be read)') parser.add_option('-f', '--frame', dest='frame', help='Poster frame (image file to be read)')
parser.add_option('-l', '--timeline', dest='timeline', help='Timeline (image file to be read)') parser.add_option('-l', '--timeline', dest='timeline', help='Timeline (image file to be read)')
parser.add_option('-p', '--poster', dest='poster', help='Poster (image file to be written)') parser.add_option('-p', '--poster', dest='poster', help='Poster (image file to be written)')
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
if options.oxdb_id and not options.id:
options.id = options.oxdb_id if None in (options.oxdb_id, options.title, options.poster):
if None in (options.id, options.poster):
parser.print_help() parser.print_help()
sys.exit() sys.exit()
opt = {} opt = {}
for key in ('id', 'title', 'frame', 'timeline', 'poster'): for key in ('oxdb_id', 'imdb_id', 'title', 'director', 'year', 'series', 'frame', 'timeline', 'poster'):
opt[key] = getattr(options, key) opt[key] = getattr(options, key)
opt['title'] = opt['title'].decode('utf-8') opt['title'] = opt['title'].decode('utf-8')
opt['director'] = opt['director'].decode('utf-8')
render_poster(**opt) render_poster(**opt)

View File

@ -133,77 +133,10 @@ pandora.ui.infoView = function(data) {
} }
var listKeys = [ var listKeys = [
'language', 'topic', 'director', 'cinematographer', 'featuring', 'country', 'language', 'director', 'featuring',
'groups', 'license' 'groups'
]; ];
// Source & Project --------------------------------------------------------
var count = 0;
['source', 'project'].forEach(function(key) {
$div = $('<div>').appendTo($data);
if (canEdit || data[key]) {
count && $('<br>').appendTo($div);
$('<div>')
.css({float: 'left'})
.html(
formatKey({
category: 'categories',
}[key] || key).replace('</span>', '&nbsp;</span>')
)
.appendTo($div);
Ox.Editable({
clickLink: pandora.clickLink,
format: function(value) {
return listKeys.indexOf(key) >= 0
? formatValue(value.split(', '), {
'director': 'name',
'cinematographer': 'name',
'features': 'name',
}[key] || key)
: value;
},
placeholder: formatLight('unknown'),
editable: canEdit,
tooltip: canEdit ? 'Doubleclick to edit' : '',
value: listKeys.indexOf(key) >= 0
? (data[key] || []).join(', ')
: data[key] || ''
})
.css({float: 'left'})
.bindEvent({
submit: function(event) {
editMetadata(key, event.value);
}
})
.appendTo($div);
if (canEdit || data[key + 'description']) {
$('<br>').css({'clear': 'both'}).appendTo($div);
$('<div>')
.append(
descriptions[key] = Ox.Editable({
clickLink: pandora.clickLink,
placeholder: formatLight('No ' + Ox.toTitleCase(key) + ' Description'),
editable: canEdit,
tooltip: canEdit ? 'Doubleclick to edit' : '',
type: 'textarea',
value: data[key + 'description'] || ''
})
.bindEvent({
submit: function(event) {
editMetadata(key + 'description', event.value);
}
})
.css(css)
).css({
'margin-top': '8px',
})
.appendTo($div);
}
count++;
}
});
// Title ------------------------------------------------------------------- // Title -------------------------------------------------------------------
$('<div>') $('<div>')
@ -232,11 +165,11 @@ pandora.ui.infoView = function(data) {
) )
.appendTo($center); .appendTo($center);
// Location, Date, Language and Duration ----------------------------------- // Year, Country, Language and Duration -----------------------------------
if (canEdit) { if (canEdit) {
$div = $('<div>').css(css).css({marginTop: '12px'}).appendTo($center); $div = $('<div>').css(css).css({marginTop: '12px'}).appendTo($center);
['location', 'date', 'language', 'duration'].forEach(function(key, i) { ['year', 'country', 'language', 'duration'].forEach(function(key, i) {
i && $('<div>').css({float: 'left'}).html(';&nbsp;').appendTo($div); i && $('<div>').css({float: 'left'}).html(';&nbsp;').appendTo($div);
$('<div>') $('<div>')
.css({float: 'left'}) .css({float: 'left'})
@ -266,7 +199,7 @@ pandora.ui.infoView = function(data) {
$('<br>').appendTo($center); $('<br>').appendTo($center);
} else { } else {
html = []; html = [];
['location', 'date', 'language', 'duration'].forEach(function(key) { ['year', 'country', 'language', 'duration'].forEach(function(key) {
if (data[key]) { if (data[key]) {
html.push(formatKey(key) + formatValue(data[key], key)); html.push(formatKey(key) + formatValue(data[key], key));
} }
@ -278,7 +211,7 @@ pandora.ui.infoView = function(data) {
if (canEdit) { if (canEdit) {
$div = $('<div>').css(css).css('clear', 'both').appendTo($center); $div = $('<div>').css(css).css('clear', 'both').appendTo($center);
['director', 'cinematographer', 'featuring'].forEach(function(key, i) { ['director', 'featuring'].forEach(function(key, i) {
i && $('<div>').css({float: 'left'}).html(';&nbsp;').appendTo($div); i && $('<div>').css({float: 'left'}).html(';&nbsp;').appendTo($div);
$('<div>') $('<div>')
.css({float: 'left'}) .css({float: 'left'})
@ -306,7 +239,7 @@ pandora.ui.infoView = function(data) {
$('<br>').appendTo($center); $('<br>').appendTo($center);
} else if (data.director || data.cinematographer || data.featuring) { } else if (data.director || data.cinematographer || data.featuring) {
html = []; html = [];
['director', 'cinematographer', 'featuring'].forEach(function(key) { ['director', 'featuring'].forEach(function(key) {
if (data[key] && data[key].length) { if (data[key] && data[key].length) {
html.push( html.push(
formatKey(key) formatKey(key)
@ -317,40 +250,6 @@ pandora.ui.infoView = function(data) {
$('<div>').css(css).html(html.join('; ')).appendTo($center); $('<div>').css(css).html(html.join('; ')).appendTo($center);
} }
// Topic -------------------------------------------------------------------
if (canEdit) {
var key = 'topic';
$div = $('<div>').css(css).css('clear', 'both').appendTo($center);
$('<div>')
.css({float: 'left'})
.html(formatKey('Topics').replace('</span>', '&nbsp;</span>'))
.appendTo($div);
Ox.Editable({
clickLink: pandora.clickLink,
format: function(value) {
return formatValue(value.split(', '), key);
},
placeholder: formatLight('unknown'),
tooltip: 'Doubleclick to edit',
value: listKeys.indexOf(key) >= 0
? (data[key] || []).join(', ')
: data[key] || ''
})
.css({float: 'left'})
.bindEvent({
submit: function(event) {
editMetadata(key, event.value);
}
})
.appendTo($div);
$('<br>').appendTo($center);
} else if (data.topic) {
html = formatKey('topics') + formatValue(data.topic, 'topic');
$('<div>').css(css).html(html).appendTo($center);
}
// Summary ------------------------------------------------------------- // Summary -------------------------------------------------------------
if (canEdit) { if (canEdit) {
@ -379,32 +278,6 @@ pandora.ui.infoView = function(data) {
$('<div>').css(css).html(data.summary).appendTo($center); $('<div>').css(css).html(data.summary).appendTo($center);
} }
// License -----------------------------------------------------------------
$div = $('<div>').css(css).css({marginTop: '16px'}).appendTo($center);
if (canEdit) {
$('<div>')
.css({float: 'left'})
.html(formatKey('license').replace('</span>', '&nbsp;</span>'))
.appendTo($div);
Ox.Editable({
placeholder: formatLight('No License'),
tooltip: 'Doubleclick to edit',
value: (data.license || []).join(', ')
})
.bindEvent({
submit: function(event) {
editMetadata('license', event.value);
}
})
.appendTo($div);
} else if (data.license) {
$div.html(
formatKey('License')
+ (data.license || []).join(', ')
);
}
// Hue, Saturation, Lightness, Volume -------------------------------------- // Hue, Saturation, Lightness, Volume --------------------------------------
['hue', 'saturation', 'lightness', 'volume'].forEach(function(key) { ['hue', 'saturation', 'lightness', 'volume'].forEach(function(key) {

View File

@ -38,7 +38,6 @@ DATABASES = {
} }
BROKER_PASSWORD = "$RABBITPWD" BROKER_PASSWORD = "$RABBITPWD"
XACCELREDIRECT = True XACCELREDIRECT = True
DB_GIN_TRGM = True
DEBUG = False DEBUG = False
TEMPLATE_DEBUG = DEBUG TEMPLATE_DEBUG = DEBUG
@ -49,7 +48,7 @@ cd /srv/pandora/pandora
sudo -u pandora python manage.py syncdb --noinput sudo -u pandora python manage.py syncdb --noinput
sudo -u pandora python manage.py sqlfindindex | sudo -u pandora python manage.py dbshell sudo -u pandora python manage.py sqlfindindex | sudo -u pandora python manage.py dbshell
echo "UPDATE django_site SET domain = '$HOST.local', name = '$HOST.local' WHERE 1=1;" | sudo -u pandora python manage.py dbshell echo "UPDATE django_site SET domain = '$HOST.local', name = '$HOST.local' WHERE 1=1;" | sudo -u pandora python manage.py dbshell
echo "DB_GIN_TRGM = True" >> /srv/pandora/pandora/local_settings.py
mkdir /srv/pandora/data mkdir /srv/pandora/data
chown -R pandora:pandora /srv/pandora chown -R pandora:pandora /srv/pandora