first round of makeing png/js/script/config overwrite more consistent
|
@ -7,3 +7,4 @@ bin
|
||||||
static/json/pandora.json
|
static/json/pandora.json
|
||||||
static/js/pandora.min.js
|
static/js/pandora.min.js
|
||||||
static/png/*.png
|
static/png/*.png
|
||||||
|
config.jsonc
|
||||||
|
|
2
README
|
@ -38,7 +38,7 @@ Get code from bazzar
|
||||||
create local_settings.py and create site.jsonc in /srv/pandora/pandora
|
create local_settings.py and create site.jsonc in /srv/pandora/pandora
|
||||||
do noy copy settings.py but only add your changes to local_settings.py
|
do noy copy settings.py but only add your changes to local_settings.py
|
||||||
(check https://wiki.0x2620.org/wiki/pandora/configuration
|
(check https://wiki.0x2620.org/wiki/pandora/configuration
|
||||||
and use settings.py / 0xdb.jsonc / padma.jsonc as example)
|
and use settings.py / config.jsonc / config.*.jsonc as example)
|
||||||
|
|
||||||
create and configure database as described below
|
create and configure database as described below
|
||||||
after that
|
after that
|
||||||
|
|
|
@ -90,7 +90,7 @@ def update_static():
|
||||||
with open(f) as j:
|
with open(f) as j:
|
||||||
data += j.read() + '\n'
|
data += j.read() + '\n'
|
||||||
js += [
|
js += [
|
||||||
'png/icon64.png',
|
'png/icon.png',
|
||||||
]
|
]
|
||||||
print 'write', pandora_js
|
print 'write', pandora_js
|
||||||
with open(pandora_js, 'w') as f:
|
with open(pandora_js, 'w') as f:
|
||||||
|
@ -109,24 +109,29 @@ def update_static():
|
||||||
if os.path.splitext(f)[-1] in ('.js', '.json'):
|
if os.path.splitext(f)[-1] in ('.js', '.json'):
|
||||||
f = os.path.join(root, f)
|
f = os.path.join(root, f)
|
||||||
os.system('gzip -9 -c "%s" > "%s.gz"' % (f, f))
|
os.system('gzip -9 -c "%s" > "%s.gz"' % (f, f))
|
||||||
|
|
||||||
for size in (16, 64, 256):
|
for name in ('logo', 'icon'):
|
||||||
pandora = os.path.join(settings.STATIC_ROOT, 'png/pandora/icon%d.png'%size)
|
site = os.path.join(settings.STATIC_ROOT, 'png/%s.%s.png'%(name, settings.CONFIG['site']['id']))
|
||||||
image = os.path.join(settings.STATIC_ROOT, 'png/icon%d.png'%size)
|
pandora = os.path.join(settings.STATIC_ROOT, 'png/%s.pandora.png'%name)
|
||||||
|
image = os.path.join(settings.STATIC_ROOT, 'png/%s.png'%name)
|
||||||
if not os.path.exists(image):
|
if not os.path.exists(image):
|
||||||
shutil.copyfile(pandora, image)
|
if os.path.exists(site):
|
||||||
|
shutil.copyfile(site, image)
|
||||||
|
else:
|
||||||
|
shutil.copyfile(pandora, image)
|
||||||
|
|
||||||
for size in (256, ):
|
|
||||||
pandora = os.path.join(settings.STATIC_ROOT, 'png/pandora/logo%d.png'%size)
|
|
||||||
image = os.path.join(settings.STATIC_ROOT, 'png/logo%d.png'%size)
|
|
||||||
if not os.path.exists(image):
|
|
||||||
shutil.copyfile(pandora, image)
|
|
||||||
#download geo data
|
#download geo data
|
||||||
update_geoip()
|
update_geoip()
|
||||||
#poster script
|
|
||||||
if not os.path.exists(settings.ITEM_POSTER):
|
#scripts
|
||||||
os.symlink(settings.ITEM_POSTER.replace('poster', 'oxdb_poster'),
|
for script in (settings.ITEM_POSTER, settings.ITEM_ICON, settings.LIST_ICON):
|
||||||
settings.ITEM_POSTER)
|
if not os.path.exists(script):
|
||||||
|
site_script = script.replace('.py', '.%s.py' % settings.CONFIG['site']['id'])
|
||||||
|
default_script = script.replace('.py', '.pandora.py')
|
||||||
|
if os.path.exists(site_script):
|
||||||
|
os.symlink(site_script, script)
|
||||||
|
else:
|
||||||
|
os.symlink(default_script, script)
|
||||||
|
|
||||||
def update_geoip(force=False):
|
def update_geoip(force=False):
|
||||||
path = os.path.join(settings.GEOIP_PATH, 'GeoLiteCity.dat')
|
path = os.path.join(settings.GEOIP_PATH, 'GeoLiteCity.dat')
|
||||||
|
@ -138,6 +143,6 @@ def update_geoip(force=False):
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
os.system('gunzip "%s.gz"' % path)
|
os.system('gunzip "%s.gz"' % path)
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
load_config()
|
load_config()
|
||||||
thread.start_new_thread(reloader_thread, ())
|
thread.start_new_thread(reloader_thread, ())
|
||||||
|
|
|
@ -645,7 +645,7 @@
|
||||||
// E-mail address uses by the system (from)
|
// E-mail address uses by the system (from)
|
||||||
"system": "0xDB@0xDB.org"
|
"system": "0xDB@0xDB.org"
|
||||||
},
|
},
|
||||||
"id": "oxdb",
|
"id": "0xdb",
|
||||||
"name": "0xDB",
|
"name": "0xDB",
|
||||||
"url": "0xDB.org",
|
"url": "0xDB.org",
|
||||||
"videoprefix": ""
|
"videoprefix": ""
|
692
pandora/config.pandora.jsonc
Normal file
|
@ -0,0 +1,692 @@
|
||||||
|
/*
|
||||||
|
Pan.do/ra Settings
|
||||||
|
|
||||||
|
You can edit this file.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
"additionalSort": [
|
||||||
|
{"key": "title", "operator": "+"}
|
||||||
|
],
|
||||||
|
"annotations": {
|
||||||
|
"showUsers": true
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
Capabilities are per user level.
|
||||||
|
They can either be general:
|
||||||
|
{level: true} means a user of that level has the capability)
|
||||||
|
or related to items:
|
||||||
|
{level: x} means a user of that level has the capability
|
||||||
|
for items of a rights level up to and including x
|
||||||
|
*/
|
||||||
|
"capabilities": {
|
||||||
|
"canDeleteItems": {"admin": true},
|
||||||
|
"canDownloadVideo": {"guest": 1, "member": 1, "staff": 4, "admin": 4},
|
||||||
|
"canEditAnnotations": {"staff": true, "admin": true},
|
||||||
|
"canEditEvents": {"staff": true, "admin": true},
|
||||||
|
"canEditFeaturedLists": {"staff": true, "admin": true},
|
||||||
|
"canEditMetadata": {"staff": true, "admin": true},
|
||||||
|
"canEditPlaces": {"staff": true, "admin": true},
|
||||||
|
"canEditSitePages": {"staff": true, "admin": true},
|
||||||
|
"canEditUsers": {"admin": true},
|
||||||
|
"canImportAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"canManageTitlesAndNames": {"member": true, "staff": true, "admin": true},
|
||||||
|
"canManagePlacesAndEvents": {"member": true, "staff": true, "admin": true},
|
||||||
|
"canManageUsers": {"staff": true, "admin": true},
|
||||||
|
"canPlayClips": {"guest": 1, "member": 1, "staff": 4, "admin": 4},
|
||||||
|
"canPlayVideo": {"guest": 1, "member": 1, "staff": 4, "admin": 4},
|
||||||
|
"canSeeAccessed": {"staff": true, "admin": true},
|
||||||
|
"canSeeDebugMenu": {"staff": true, "admin": true},
|
||||||
|
"canSeeExtraItemViews": {"staff": true, "admin": true},
|
||||||
|
"canSeeFiles": {"staff": true, "admin": true},
|
||||||
|
"canSeeItem": {"guest": 1, "member": 1, "staff": 4, "admin": 4},
|
||||||
|
"canSeeSize": {"staff": true, "admin": true},
|
||||||
|
"canSendMail": {"staff": true, "admin": true},
|
||||||
|
"canUploadVideo": {"guest": false, "member": true, "staff": true, "admin": true}
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
clipKeys are the properties that clips can by sorted by.
|
||||||
|
If sortOperator is not specified, it will be + for strings and - for numbers.
|
||||||
|
*/
|
||||||
|
"clipKeys": [
|
||||||
|
{"id": "text", "title": "Text", "type": "string"},
|
||||||
|
{"id": "position", "title": "Position", "type": "float", "sortOperator": "+"},
|
||||||
|
{"id": "duration", "title": "Duration", "type": "float"},
|
||||||
|
{"id": "hue", "title": "Hue", "type": "float", "sortOperator": "+"},
|
||||||
|
{"id": "saturation", "title": "Saturation", "type": "float"},
|
||||||
|
{"id": "lightness", "title": "Lightness", "type": "float"},
|
||||||
|
{"id": "volume", "title": "Volume", "type": "float"}
|
||||||
|
],
|
||||||
|
/*
|
||||||
|
clipLayers is the ordered list of public layers that will appear as the
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
"clipLayers": ["transcripts", "keywords", "places", "events", "descriptions"],
|
||||||
|
// fixme: either this, or filter: true in itemKeys, but not both
|
||||||
|
"filters": [
|
||||||
|
{"id": "source", "title": "Sources", "type": "string"},
|
||||||
|
{"id": "project", "title": "Projects", "type": "string"},
|
||||||
|
{"id": "topic", "title": "Topics", "type": "string"},
|
||||||
|
{"id": "name", "title": "People", "type": "string"},
|
||||||
|
{"id": "language", "title": "Languages", "type": "string"},
|
||||||
|
{"id": "license", "title": "License", "type": "string"},
|
||||||
|
{"id": "places", "title": "Places", "type": "string"},
|
||||||
|
{"id": "events", "title": "Events", "type": "string"},
|
||||||
|
{"id": "keywords", "title": "Keywords", "type": "string"}
|
||||||
|
],
|
||||||
|
/*
|
||||||
|
An itemKey must have the following properties:
|
||||||
|
id: The id of the key (as known by the server)
|
||||||
|
title: The title of the key (as displayed by the client)
|
||||||
|
type: text, string, float, integer, or array of any of these
|
||||||
|
and can have any of the following properties:
|
||||||
|
autocomplete: If true, find element will autocomplete
|
||||||
|
autocompleteSortKey: The key that suggestions will be sorted by
|
||||||
|
capability: A capability required to see this key
|
||||||
|
columnRequired: If true, the column can't be removed
|
||||||
|
columnWidth: Default column width in px
|
||||||
|
filter: if true, one can filter results by this key
|
||||||
|
find: If true, this key will appear as a find option
|
||||||
|
format: {type: "...", args: [...]}, for special formatting
|
||||||
|
(Ox.formatType(args) will be called)
|
||||||
|
sort: If true, one can sort results by this key
|
||||||
|
sortOperator: sort operator (+, -), in case it differs from the
|
||||||
|
default for the key's type (+ for strings, - for numbers)
|
||||||
|
sortType: special sort type (title, person)
|
||||||
|
value: {key: "...", type: "..."}, for keys that are derived
|
||||||
|
from other keys (like number of actors), or "capability"
|
||||||
|
*/
|
||||||
|
"itemKeys": [
|
||||||
|
{
|
||||||
|
"id": "*",
|
||||||
|
"title": "All",
|
||||||
|
"type": "text",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "title",
|
||||||
|
"title": "Title",
|
||||||
|
"type": "string",
|
||||||
|
"autocomplete": true,
|
||||||
|
"autocompleteSortKey": "timesaccessed",
|
||||||
|
"columnRequired": true,
|
||||||
|
"columnWidth": 180,
|
||||||
|
"find": true,
|
||||||
|
"sort": true,
|
||||||
|
"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",
|
||||||
|
"title": "People",
|
||||||
|
"type": ["string"],
|
||||||
|
"autocomplete": true,
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "director",
|
||||||
|
"title": "Director",
|
||||||
|
"type": ["string"],
|
||||||
|
"autocomplete": true,
|
||||||
|
"columnRequired": true,
|
||||||
|
"columnWidth": 180,
|
||||||
|
"sort": true,
|
||||||
|
"sortType": "person"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cinematographer",
|
||||||
|
"title": "Cinematographer",
|
||||||
|
"type": ["string"],
|
||||||
|
"autocomplete": true,
|
||||||
|
"columnWidth": 180,
|
||||||
|
"sort": true,
|
||||||
|
"sortType": "person"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "featuring",
|
||||||
|
"title": "Featuring",
|
||||||
|
"type": ["string"],
|
||||||
|
"autocomplete": true,
|
||||||
|
"columnRequired": true,
|
||||||
|
"columnWidth": 180,
|
||||||
|
"filter": true,
|
||||||
|
"sort": true,
|
||||||
|
"sortType": "person"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "language",
|
||||||
|
"title": "Language",
|
||||||
|
"type": ["string"],
|
||||||
|
"autocomplete": true,
|
||||||
|
"columnWidth": 120,
|
||||||
|
"filter": true,
|
||||||
|
"find": true,
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "location",
|
||||||
|
"title": "Location",
|
||||||
|
"type": "string",
|
||||||
|
"autocomplete": true,
|
||||||
|
"columnWidth": 180,
|
||||||
|
"filter": true,
|
||||||
|
"find": true,
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "date",
|
||||||
|
"title": "Date",
|
||||||
|
"type": "string",
|
||||||
|
"columnWidth": 120,
|
||||||
|
//"format": {"type": "date", "args": ["%a, %b %e, %Y"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "summary",
|
||||||
|
"title": "Summary",
|
||||||
|
"type": "text",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "id",
|
||||||
|
"title": "ID",
|
||||||
|
"type": "string",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"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",
|
||||||
|
"title": "Keywords",
|
||||||
|
"type": "layer",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "descriptions",
|
||||||
|
"title": "Descriptions",
|
||||||
|
"type": "layer",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "transcripts",
|
||||||
|
"title": "Transcripts",
|
||||||
|
"type": "layer",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "numberofannotations",
|
||||||
|
"title": "Annotations",
|
||||||
|
"type": "integer",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "duration",
|
||||||
|
"title": "Duration",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "duration", "args": [0, "short"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "resolution",
|
||||||
|
"title": "Resolution",
|
||||||
|
"type": ["integer"],
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "resolution", "args": ["px"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "aspectratio",
|
||||||
|
"title": "Aspect Ratio",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "unit", "args": [":1"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "pixels",
|
||||||
|
"title": "Pixels",
|
||||||
|
"type": "integer",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "value", "args": ["px"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "hue",
|
||||||
|
"title": "Hue",
|
||||||
|
"type": "hue",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "color", "args": ["hue"]},
|
||||||
|
"sort": true,
|
||||||
|
"sortOperator": "+"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "saturation",
|
||||||
|
"title": "Saturation",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "color", "args": ["saturation"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "lightness",
|
||||||
|
"title": "Lightness",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "color", "args": ["lightness"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "volume",
|
||||||
|
"title": "Volume",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "numberofcuts",
|
||||||
|
"title": "Number of Cuts",
|
||||||
|
"type": "integer",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "number", "args": []},
|
||||||
|
"sort": true,
|
||||||
|
"value": {"key": "cuts", "type": "length"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "cutsperminute",
|
||||||
|
"title": "Cuts per Minute",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "number", "args": [3]},
|
||||||
|
"sort": true,
|
||||||
|
"value": {"key": "cuts", "type": "lengthperminute"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "words",
|
||||||
|
"title": "Number of Words",
|
||||||
|
"type": "integer",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "number", "args": []},
|
||||||
|
"sort": true,
|
||||||
|
"value": {"layer": "subtitles", "type": "words"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "wordsperminute",
|
||||||
|
"title": "Words per Minute",
|
||||||
|
"type": "float",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "number", "args": [3]},
|
||||||
|
"sort": true,
|
||||||
|
"value": {"layer": "subtitles", "type": "wordsperminute"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "size",
|
||||||
|
"title": "Size",
|
||||||
|
"type": "integer",
|
||||||
|
"capability": "canSeeFiles",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "value", "args": ["B"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bitrate",
|
||||||
|
"title": "Bitrate",
|
||||||
|
"type": "integer",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "unit", "args": ["kbps"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "numberoffiles",
|
||||||
|
"title": "Number of Files",
|
||||||
|
"type": "integer",
|
||||||
|
"capability": "canSeeFiles",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"sort": true,
|
||||||
|
"value": {"key": "files", "type": "length"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "user",
|
||||||
|
"title": "User",
|
||||||
|
"type": "string",
|
||||||
|
"capability": "canSeeFiles",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "filename",
|
||||||
|
"title": "Filename",
|
||||||
|
"type": ["string"],
|
||||||
|
"capability": "canSeeFiles",
|
||||||
|
"find": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "created",
|
||||||
|
"title": "Date Created",
|
||||||
|
"type": "date",
|
||||||
|
"columnWidth": 120,
|
||||||
|
"format": {"type": "date", "args": ["%Y-%m-%d %H:%M:%S"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "modified",
|
||||||
|
"title": "Last Modified",
|
||||||
|
"type": "date",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "date", "args": ["%Y-%m-%d %H:%M:%S"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "accessed",
|
||||||
|
"title": "Last Accessed",
|
||||||
|
"type": "date",
|
||||||
|
"capability": "canSeeAccessed",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "date", "args": ["%Y-%m-%d %H:%M:%S"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "timesaccessed",
|
||||||
|
"title": "Times Accessed",
|
||||||
|
"type": "integer",
|
||||||
|
"capability": "canSeeAccessed",
|
||||||
|
"columnWidth": 60,
|
||||||
|
"format": {"type": "date", "args": ["%Y-%m-%d %H:%M:%S"]},
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "license",
|
||||||
|
"title": "License",
|
||||||
|
"type": ["string"],
|
||||||
|
"columnWidth": 120,
|
||||||
|
"filter": true,
|
||||||
|
"sort": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "rightslevel",
|
||||||
|
"title": "Rights Level",
|
||||||
|
"type": "enum",
|
||||||
|
"columnWidth": 90,
|
||||||
|
"format": {"type": "ColorLevel", "args": [
|
||||||
|
["Public", "Restricted", "Private"]
|
||||||
|
]},
|
||||||
|
"sort": true,
|
||||||
|
"sortOperator": "+",
|
||||||
|
"values": ["Public", "Restricted", "Private", "Unknown"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "random",
|
||||||
|
"title": "Random",
|
||||||
|
"type": "integer",
|
||||||
|
"sort": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"itemName": {
|
||||||
|
"singular": "Video",
|
||||||
|
"plural": "Videos"
|
||||||
|
},
|
||||||
|
"itemViews": [
|
||||||
|
{"id": "info", "title": "Info"},
|
||||||
|
{"id": "player", "title": "Player"},
|
||||||
|
{"id": "editor", "title": "Editor"},
|
||||||
|
{"id": "timeline", "title": "Timeline"},
|
||||||
|
{"id": "clips", "title": "Clips"},
|
||||||
|
{"id": "map", "title": "Map"},
|
||||||
|
{"id": "calendar", "title": "Calendar"},
|
||||||
|
{"id": "data", "title": "Data"},
|
||||||
|
{"id": "files", "title": "Files"}
|
||||||
|
],
|
||||||
|
"layers": [
|
||||||
|
{
|
||||||
|
"id": "places",
|
||||||
|
"title": "Places",
|
||||||
|
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"item": "Place",
|
||||||
|
"overlap": true,
|
||||||
|
"type": "place"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "events",
|
||||||
|
"title": "Events",
|
||||||
|
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"item": "Event",
|
||||||
|
"overlap": true,
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "keywords",
|
||||||
|
"title": "Keywords",
|
||||||
|
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"item": "Keyword",
|
||||||
|
"overlap": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "descriptions",
|
||||||
|
"title": "Descriptions",
|
||||||
|
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"item": "Description",
|
||||||
|
"showInfo": true,
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "transcripts",
|
||||||
|
"title": "Transcripts",
|
||||||
|
"canAddAnnotations": {"member": true, "staff": true, "admin": true},
|
||||||
|
"item": "Transcript",
|
||||||
|
"showInfo": true,
|
||||||
|
"type": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"listViews": [
|
||||||
|
{"id": "list", "title": "as List"},
|
||||||
|
{"id": "grid", "title": "as Grid"},
|
||||||
|
//{"id": "info", "title": "with Info"},
|
||||||
|
{"id": "timelines", "title": "with Timelines"},
|
||||||
|
{"id": "clips", "title": "with Clips"},
|
||||||
|
//{"id": "maps", "title": "with Maps"},
|
||||||
|
//{"id": "calendars", "title": "with Calendars"},
|
||||||
|
{"id": "clip", "title": "as Clips"},
|
||||||
|
//{"id": "video", "title": "as Video"},
|
||||||
|
{"id": "map", "title": "on Map"},
|
||||||
|
{"id": "calendar", "title": "on Calendar"}
|
||||||
|
],
|
||||||
|
"media": {
|
||||||
|
"importPosters": false,
|
||||||
|
"importFrames": false
|
||||||
|
},
|
||||||
|
"personalLists": [
|
||||||
|
{"title": "Favorites"}
|
||||||
|
],
|
||||||
|
"rightsLevel": {"member": 2, "staff": 2, "admin": 2},
|
||||||
|
"rightsLevels": [
|
||||||
|
{"name": "Public", "color": [128, 255, 128]},
|
||||||
|
{"name": "Restricted", "color": [255, 192, 128]},
|
||||||
|
{"name": "Private", "color": [255, 128, 128]}
|
||||||
|
],
|
||||||
|
"sendReferrer": true,
|
||||||
|
"site": {
|
||||||
|
"description": "pan.do/ra is a free, open source media archive. It allows you to manage large, decentralized collections of video, to collaboratively create metadata and time-based annotations, and to serve your archive as a cutting-edge web application.",
|
||||||
|
"email": {
|
||||||
|
// E-mail address in contact form (to)
|
||||||
|
"contact": "system@pandora.local",
|
||||||
|
"footer": "-- \npan.do/ra - http://pan.do/ra",
|
||||||
|
"prefix": "pan.do/ra News -",
|
||||||
|
// E-mail address uses by the system (from)
|
||||||
|
"system": "system@pandora.local"
|
||||||
|
},
|
||||||
|
"id": "pandora",
|
||||||
|
"name": "pan.do/ra",
|
||||||
|
"url": "pandora.local",
|
||||||
|
"videoprefix": ""
|
||||||
|
},
|
||||||
|
"sitePages": [
|
||||||
|
{"id": "about", "title": "About"},
|
||||||
|
{"id": "news", "title": "News"},
|
||||||
|
//{"id": "tour", "title": "Take a Tour"},
|
||||||
|
{"id": "faq", "title": "Frequently Asked Questions"},
|
||||||
|
{"id": "terms", "title": "Terms of Service"},
|
||||||
|
{"id": "license", "title": "License"},
|
||||||
|
{"id": "contact", "title": "Contact"}
|
||||||
|
],
|
||||||
|
"timelines": [
|
||||||
|
{"id": "antialias", "title": "Anti-Alias"},
|
||||||
|
{"id": "slitscan", "title": "Slit-Scan"},
|
||||||
|
{"id": "keyframes", "title": "Key Frames"},
|
||||||
|
{"id": "audio", "title": "Audio"}
|
||||||
|
],
|
||||||
|
"totals": [
|
||||||
|
{"id": "items"},
|
||||||
|
{"id": "files", "admin": true},
|
||||||
|
{"id": "duration", "admin": true},
|
||||||
|
{"id": "size", "admin": true},
|
||||||
|
{"id": "pixels"}
|
||||||
|
],
|
||||||
|
"tv": {
|
||||||
|
"showLogo": false
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"level": "guest",
|
||||||
|
"ui": {
|
||||||
|
"annotationsCalendarSize": 128,
|
||||||
|
"annotationsFont": "small",
|
||||||
|
"annotationsMapSize": 128,
|
||||||
|
"annotationsRange": "position",
|
||||||
|
"annotationsSize": 256,
|
||||||
|
"annotationsSort": "position",
|
||||||
|
"clipsColumns": 2,
|
||||||
|
"columns": {
|
||||||
|
"Colors": {
|
||||||
|
"columns": ["title", "source", "project", "language", "hue", "saturation", "brightness"],
|
||||||
|
"columnWidth": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"filters": [
|
||||||
|
{"id": "source", "sort": [{"key": "name", "operator": "+"}]},
|
||||||
|
{"id": "project", "sort": [{"key": "name", "operator": "+"}]},
|
||||||
|
{"id": "topic", "sort": [{"key": "items", "operator": "-"}]},
|
||||||
|
{"id": "name", "sort": [{"key": "items", "operator": "-"}]},
|
||||||
|
{"id": "keywords", "sort": [{"key": "items", "operator": "-"}]},
|
||||||
|
{"id": "places", "sort": [{"key": "items", "operator": "-"}]}
|
||||||
|
],
|
||||||
|
"filtersSize": 176,
|
||||||
|
"find": {"conditions": [], "operator": "&"},
|
||||||
|
"followPlayer": true,
|
||||||
|
"icons": "frames",
|
||||||
|
"infoIconSize": 256,
|
||||||
|
"item": "",
|
||||||
|
"itemFind": "",
|
||||||
|
"itemSort": [{"key": "position", "operator": "+"}],
|
||||||
|
"itemView": "info",
|
||||||
|
"listColumns": ["title", "source", "project", "topic", "language", "duration"],
|
||||||
|
"listColumnWidth": {},
|
||||||
|
"listSelection": [],
|
||||||
|
"listSort": [{"key": "title", "operator": "+"}],
|
||||||
|
"listView": "grid",
|
||||||
|
"lists": {},
|
||||||
|
"mapFind": "",
|
||||||
|
"mapSelection": "",
|
||||||
|
"page": "",
|
||||||
|
"section": "items",
|
||||||
|
"showAnnotations": true,
|
||||||
|
"showAnnotationsCalendar": true,
|
||||||
|
"showAnnotationsMap": true,
|
||||||
|
"showBrowser": true,
|
||||||
|
"showCalendarControls": true, // fixme: should be false
|
||||||
|
"showFilters": true,
|
||||||
|
"showFlags": false,
|
||||||
|
"showHome": true,
|
||||||
|
"showIconBrowser": false,
|
||||||
|
"showInfo": true,
|
||||||
|
"showLayers": {
|
||||||
|
"places": false,
|
||||||
|
"events": false,
|
||||||
|
"keywords": true,
|
||||||
|
"descriptions": true,
|
||||||
|
"transcripts": true
|
||||||
|
},
|
||||||
|
"showMapControls": false,
|
||||||
|
"showMapLabels": false,
|
||||||
|
"showFolder": {
|
||||||
|
"items": {
|
||||||
|
"personal": true,
|
||||||
|
"favorite": true,
|
||||||
|
"featured": true,
|
||||||
|
"volumes": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"showSidebar": true,
|
||||||
|
"showSitePosters": false,
|
||||||
|
"showTimeline": true,
|
||||||
|
"sidebarSize": 256,
|
||||||
|
"theme": "classic",
|
||||||
|
"videoMuted": false,
|
||||||
|
"videoPoints": {},
|
||||||
|
"videoResolution": 240,
|
||||||
|
"videoScale": "fit",
|
||||||
|
"videoSize": "large",
|
||||||
|
"videoTimeline": "antialias",
|
||||||
|
"videoView": "player",
|
||||||
|
"videoVolume": 1
|
||||||
|
},
|
||||||
|
"username": "",
|
||||||
|
"volumes": []
|
||||||
|
},
|
||||||
|
"userLevels": ["guest", "member", "staff", "admin"],
|
||||||
|
"video": {
|
||||||
|
"download": true,
|
||||||
|
"formats": ["webm"],
|
||||||
|
"previewRatio": 1.3333333333,
|
||||||
|
//supported resolutions are
|
||||||
|
//1080, 720, 480, 432, 360, 288, 240, 144, 96
|
||||||
|
"resolutions": [480, 240, 96]
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,4 +18,8 @@ except ImportError:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
if not os.path.exists(settings.SITE_CONFIG):
|
||||||
|
import sys
|
||||||
|
sys.stderr.write("Error: Can't find '%s'.\nBefore you run pan.do/ra you must create it\n" % settings.SITE_CONFIG)
|
||||||
|
sys.exit(1)
|
||||||
execute_manager(settings)
|
execute_manager(settings)
|
||||||
|
|
|
@ -162,9 +162,10 @@ XSENDFILE = False
|
||||||
#with nginx X-Accel-Redirect set this to True
|
#with nginx X-Accel-Redirect set this to True
|
||||||
XACCELREDIRECT = False
|
XACCELREDIRECT = False
|
||||||
|
|
||||||
SITE_CONFIG = join(PROJECT_ROOT, 'pandora.jsonc')
|
SITE_CONFIG = join(PROJECT_ROOT, 'config.jsonc')
|
||||||
|
|
||||||
#used if CONFIG['video']['download'] is set
|
#used if CONFIG['video']['download'] is set
|
||||||
TRACKER_URL="http://url2torrent.net:6970/announce"
|
TRACKER_URL="udp://tracker.openbittorrent.com:80"
|
||||||
|
|
||||||
DATA_SERVICE = ''
|
DATA_SERVICE = ''
|
||||||
POSTER_PRECEDENCE = ()
|
POSTER_PRECEDENCE = ()
|
||||||
|
@ -178,10 +179,10 @@ VIDEO_PREFIX=''
|
||||||
|
|
||||||
SCRIPT_ROOT = normpath(join(PROJECT_ROOT, '..', 'scripts'))
|
SCRIPT_ROOT = normpath(join(PROJECT_ROOT, '..', 'scripts'))
|
||||||
#change script to customize
|
#change script to customize
|
||||||
ITEM_POSTER = join(SCRIPT_ROOT, 'poster')
|
ITEM_POSTER = join(SCRIPT_ROOT, 'poster.py')
|
||||||
#ITEM_POSTER = join(SCRIPT_ROOT, 'padma_poster')
|
#ITEM_POSTER = join(SCRIPT_ROOT, 'padma_poster')
|
||||||
ITEM_ICON = join(SCRIPT_ROOT, 'item_icon')
|
ITEM_ICON = join(SCRIPT_ROOT, 'item_icon.py')
|
||||||
LIST_ICON = join(SCRIPT_ROOT, 'list_icon')
|
LIST_ICON = join(SCRIPT_ROOT, 'list_icon.py')
|
||||||
|
|
||||||
DB_GIN_TRGM = False
|
DB_GIN_TRGM = False
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>{{sitename}} API</title>
|
<title>{{sitename}} API</title>
|
||||||
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/png/icon16.png"/>
|
<link rel="shortcut icon" type="image/png" href="/static/png/icon.png"/>
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/highlight.css"/>
|
<link rel="stylesheet" type="text/css" href="/static/css/highlight.css"/>
|
||||||
<script type="text/javascript" src="/static/oxjs/build/Ox.js"></script>
|
<script type="text/javascript" src="/static/oxjs/build/Ox.js"></script>
|
||||||
<script type="text/javascript" src="/static/js/api/highlight.pack.js"></script>
|
<script type="text/javascript" src="/static/js/api/highlight.pack.js"></script>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>{{title}}</title>
|
<title>{{title}}</title>
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/png/icon16.png"/>
|
<link rel="shortcut icon" type="image/png" href="/static/png/icon.png"/>
|
||||||
<link rel="icon" href="/static/png/icon64.png" sizes="32x32"/>
|
<link rel="icon" href="/static/png/icon.png" sizes="32x32"/>
|
||||||
<link rel="icon" href="/static/png/icon64.png" sizes="48x48"/>
|
<link rel="icon" href="/static/png/icon.png" sizes="48x48"/>
|
||||||
<meta name="application-name" content="{{settings.SITENAME}}"/>
|
<meta name="application-name" content="{{settings.SITENAME}}"/>
|
||||||
<meta name="application-url" content="{{base_url}}"/>
|
<meta name="application-url" content="{{base_url}}"/>
|
||||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="{{settings.SITENAME}}" />
|
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="{{settings.SITENAME}}" />
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<meta property="og:title" content="{{title}}"/>
|
<meta property="og:title" content="{{title}}"/>
|
||||||
<meta property="og:type" content="website"/>
|
<meta property="og:type" content="website"/>
|
||||||
<meta property="og:url" content="{{base_url}}"/>
|
<meta property="og:url" content="{{base_url}}"/>
|
||||||
<meta property="og:image" content="{{base_url}}static/png/icon64.png"/>
|
<meta property="og:image" content="{{base_url}}static/png/icon.png"/>
|
||||||
<meta property="og:site_name" content="{{settings.SITENAME}}"/>
|
<meta property="og:site_name" content="{{settings.SITENAME}}"/>
|
||||||
<meta property="og:description" content="{{settings.CONFIG.site.description|safe}}"/>
|
<meta property="og:description" content="{{settings.CONFIG.site.description|safe}}"/>
|
||||||
<meta name=”google” value=”notranslate”>
|
<meta name=”google” value=”notranslate”>
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>{{settings.SITENAME}} - {{title}}</title>
|
<title>{{settings.SITENAME}} - {{title}}</title>
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/png/icon16.png"/>
|
<link rel="shortcut icon" type="image/png" href="/static/png/icon.png"/>
|
||||||
<link rel="icon" href="/static/png/icon64.png" sizes="32x32"/>
|
<link rel="icon" href="/static/png/icon.png" sizes="32x32"/>
|
||||||
<link rel="icon" href="/static/png/icon64.png" sizes="48x48"/>
|
<link rel="icon" href="/static/png/icon.png" sizes="48x48"/>
|
||||||
<meta name="application-name" content="{{settings.SITENAME}}"/>
|
<meta name="application-name" content="{{settings.SITENAME}}"/>
|
||||||
<meta name="application-url" content="{{base_url}}"/>
|
<meta name="application-url" content="{{base_url}}"/>
|
||||||
<link rel="alternate" type="application/json+oembed" href="{{base_url}}oembed?url={{current_url|urlencode}}" title="oEmbed Profile" />
|
<link rel="alternate" type="application/json+oembed" href="{{base_url}}oembed?url={{current_url|urlencode}}" title="oEmbed Profile" />
|
||||||
|
|
|
@ -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', '--imdbid', dest='imdb_id', help='IMDb Id')
|
parser.add_option('-i', '--id', dest='imdb_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')
|
|
@ -60,7 +60,7 @@ def render_poster(id, title, frame, timeline, 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='Pad.ma Id')
|
parser.add_option('-i', '--id', dest='id', help='Item Id')
|
||||||
parser.add_option('-t', '--title', dest='title', help='Title', default='')
|
parser.add_option('-t', '--title', dest='title', help='Title', default='')
|
||||||
parser.add_option('-d', '--director', dest='director', help='Director', default='')
|
parser.add_option('-d', '--director', dest='director', help='Director', default='')
|
||||||
parser.add_option('-y', '--year', dest='year', help='Year', default='')
|
parser.add_option('-y', '--year', dest='year', help='Year', default='')
|
86
scripts/poster.pandora.py
Executable file
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
from __future__ import division
|
||||||
|
import os
|
||||||
|
|
||||||
|
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
||||||
|
|
||||||
|
#using virtualenv's activate_this.py to reorder sys.path
|
||||||
|
activate_this = os.path.join(root_dir, 'bin', 'activate_this.py')
|
||||||
|
execfile(activate_this, dict(__file__=activate_this))
|
||||||
|
|
||||||
|
import Image
|
||||||
|
import ImageDraw
|
||||||
|
from optparse import OptionParser
|
||||||
|
from ox.image import drawText, wrapText
|
||||||
|
import sys
|
||||||
|
|
||||||
|
static_root = os.path.join(os.path.dirname(__file__), 'data')
|
||||||
|
|
||||||
|
def render_poster(id, title, frame, timeline, poster):
|
||||||
|
poster_width = 640
|
||||||
|
poster_height = 1024
|
||||||
|
poster_ratio = poster_width / poster_height
|
||||||
|
poster_color = (255, 255, 0)
|
||||||
|
poster_image = Image.new('RGB', (poster_width, poster_height))
|
||||||
|
font_file = os.path.join(static_root, 'DejaVuSansCondensedBold.ttf')
|
||||||
|
font_size = 48
|
||||||
|
|
||||||
|
# timeline
|
||||||
|
timeline_height = 64
|
||||||
|
timeline_lines = 16
|
||||||
|
if timeline:
|
||||||
|
timeline_image = Image.open(timeline)
|
||||||
|
timeline_image = timeline_image.resize((10240, timeline_height), Image.ANTIALIAS)
|
||||||
|
for i in range(timeline_lines):
|
||||||
|
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 = '' + 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_height = timeline_height
|
||||||
|
text_left = int((poster_width - text_width) / 2)
|
||||||
|
text_top = 14 * timeline_height
|
||||||
|
for y in range(text_top, text_top + text_height):
|
||||||
|
for x in range(text_left, text_left + text_width):
|
||||||
|
if y < text_top + 4 or y >= text_top + text_height - 4:
|
||||||
|
poster_image.putpixel((x, y), poster_color)
|
||||||
|
else:
|
||||||
|
pixel = list(poster_image.getpixel((x, y)))
|
||||||
|
for c in range(3):
|
||||||
|
pixel[c] = int((pixel[c] + poster_color[c]) / 4)
|
||||||
|
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)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = OptionParser()
|
||||||
|
parser.add_option('-o', '--oxdbid', dest='oxdb_id', help='0xDB Id')
|
||||||
|
parser.add_option('-i', '--id', dest='id', help='Item Id')
|
||||||
|
parser.add_option('-t', '--title', dest='title', help='Title', default='')
|
||||||
|
parser.add_option('-d', '--director', dest='director', help='Director', default='')
|
||||||
|
parser.add_option('-y', '--year', dest='year', help='Year', default='')
|
||||||
|
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('-p', '--poster', dest='poster', help='Poster (image file to be written)')
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
if options.oxdb_id and not options.id:
|
||||||
|
options.id = options.oxdb_id
|
||||||
|
if None in (options.id, options.poster):
|
||||||
|
parser.print_help()
|
||||||
|
sys.exit()
|
||||||
|
opt = {}
|
||||||
|
for key in ('id', 'title', 'frame', 'timeline', 'poster'):
|
||||||
|
opt[key] = getattr(options, key)
|
||||||
|
|
||||||
|
opt['title'] = opt['title'].decode('utf-8')
|
||||||
|
|
||||||
|
render_poster(**opt)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
png/icon16.png
|
png/icon.png
|
|
@ -12,7 +12,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body class="OxThemeModern">
|
<body class="OxThemeModern">
|
||||||
<img src="/static/png/logo256.png" style="width: 320px; padding-top: 160px"/>
|
<img src="/static/png/logo.png" style="width: 320px; padding-top: 160px"/>
|
||||||
<div style="padding-top: 16px">We will be back in a moment.</div>
|
<div style="padding-top: 16px">We will be back in a moment.</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -75,7 +75,7 @@ appPanel
|
||||||
images.reflection.style.MozTransform = 'scaleY(-1)';
|
images.reflection.style.MozTransform = 'scaleY(-1)';
|
||||||
images.reflection.style.OTransform = 'scaleY(-1)';
|
images.reflection.style.OTransform = 'scaleY(-1)';
|
||||||
images.reflection.style.WebkitTransform = 'scaleY(-1)';
|
images.reflection.style.WebkitTransform = 'scaleY(-1)';
|
||||||
images.reflection.src = '/static/png/logo256.png';
|
images.reflection.src = '/static/png/logo.png';
|
||||||
images.loadingIcon = document.createElement('img');
|
images.loadingIcon = document.createElement('img');
|
||||||
images.loadingIcon.setAttribute('id', 'loadingIcon');
|
images.loadingIcon.setAttribute('id', 'loadingIcon');
|
||||||
images.loadingIcon.style.position = 'absolute';
|
images.loadingIcon.style.position = 'absolute';
|
||||||
|
@ -90,7 +90,7 @@ appPanel
|
||||||
+ '/Ox.UI/themes/' + theme + '/svg/symbolLoadingAnimated.svg';
|
+ '/Ox.UI/themes/' + theme + '/svg/symbolLoadingAnimated.svg';
|
||||||
callback(images);
|
callback(images);
|
||||||
};
|
};
|
||||||
images.logo.src = '/static/png/logo256.png';
|
images.logo.src = '/static/png/logo.png';
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadScreen(images) {
|
function loadScreen(images) {
|
||||||
|
|
|
@ -94,7 +94,7 @@ pandora.ui.accountDialogOptions = function(action, value) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
@ -335,7 +335,7 @@ pandora.ui.accountSignoutDialog = function() {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
@ -374,7 +374,7 @@ pandora.ui.accountWelcomeDialog = function() {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -21,7 +21,7 @@ pandora.ui.allItems = function() {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
$icon = $('<img>')
|
$icon = $('<img>')
|
||||||
.attr({src: '/static/png/icon16.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({float: 'left', width: '14px', height: '14px', margin: '1px'})
|
.css({float: 'left', width: '14px', height: '14px', margin: '1px'})
|
||||||
.appendTo(that),
|
.appendTo(that),
|
||||||
$name = $('<div>')
|
$name = $('<div>')
|
||||||
|
|
|
@ -26,7 +26,7 @@ pandora.ui.annotationDialog = function(layer) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -120,7 +120,7 @@ pandora.ui.contactForm = function() {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -31,7 +31,7 @@ pandora.ui.deleteItemDialog = function(item) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -45,7 +45,7 @@ pandora.ui.deleteListDialog = function(list) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -26,7 +26,7 @@ pandora.ui.errorDialog = function(data) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
@ -66,7 +66,7 @@ pandora.ui.errorDialog = function(data) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -11,7 +11,7 @@ pandora.ui.folderBrowserList = function(id) {
|
||||||
clickable: true,
|
clickable: true,
|
||||||
format: function(value) {
|
format: function(value) {
|
||||||
return $('<img>').attr({
|
return $('<img>').attr({
|
||||||
src: '/list/' + value + '/icon16.jpg'
|
src: '/list/' + value + '/icon.jpg'
|
||||||
}).css({
|
}).css({
|
||||||
width: '14px',
|
width: '14px',
|
||||||
height: '14px',
|
height: '14px',
|
||||||
|
|
|
@ -14,7 +14,7 @@ pandora.ui.folderList = function(id) {
|
||||||
},
|
},
|
||||||
format: function(value, data) {
|
format: function(value, data) {
|
||||||
return $('<img>').attr({
|
return $('<img>').attr({
|
||||||
src: '/list/' + data.id + '/icon16.jpg'
|
src: '/list/' + data.id + '/icon.jpg'
|
||||||
}).css({
|
}).css({
|
||||||
width: '14px',
|
width: '14px',
|
||||||
height: '14px',
|
height: '14px',
|
||||||
|
|
|
@ -304,7 +304,7 @@ pandora.ui.folders = function() {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -14,7 +14,7 @@ pandora.ui.home = function() {
|
||||||
zIndex: 1001
|
zIndex: 1001
|
||||||
}),
|
}),
|
||||||
$reflectionImage = $('<img>')
|
$reflectionImage = $('<img>')
|
||||||
.attr({src: '/static/png/logo256.png'})
|
.attr({src: '/static/png/logo.png'})
|
||||||
.css({
|
.css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
left: 0,
|
||||||
|
@ -45,7 +45,7 @@ pandora.ui.home = function() {
|
||||||
$logo = $('<img>')
|
$logo = $('<img>')
|
||||||
.attr({
|
.attr({
|
||||||
id: 'logo',
|
id: 'logo',
|
||||||
src: '/static/png/logo256.png'
|
src: '/static/png/logo.png'
|
||||||
})
|
})
|
||||||
.css({
|
.css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
|
@ -26,7 +26,7 @@ pandora.ui.home = function() {
|
||||||
})
|
})
|
||||||
.appendTo(that),
|
.appendTo(that),
|
||||||
$reflectionImage = $('<img>')
|
$reflectionImage = $('<img>')
|
||||||
.attr({src: '/static/png/logo256.png'})
|
.attr({src: '/static/png/logo.png'})
|
||||||
.css({
|
.css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
left: 0,
|
||||||
|
@ -55,7 +55,7 @@ pandora.ui.home = function() {
|
||||||
$logo = $('<img>')
|
$logo = $('<img>')
|
||||||
.attr({
|
.attr({
|
||||||
id: 'logo',
|
id: 'logo',
|
||||||
src: '/static/png/logo256.png'
|
src: '/static/png/logo.png'
|
||||||
})
|
})
|
||||||
.css({
|
.css({
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
|
|
|
@ -32,7 +32,7 @@ pandora.ui.homePage = function() {
|
||||||
.html('right')
|
.html('right')
|
||||||
.appendTo(that.$element),
|
.appendTo(that.$element),
|
||||||
$logo = $('<img>')
|
$logo = $('<img>')
|
||||||
.attr({src: '/static/png/logo256.png'})
|
.attr({src: '/static/png/logo.png'})
|
||||||
.appendTo($center);
|
.appendTo($center);
|
||||||
// fixme: duplicated
|
// fixme: duplicated
|
||||||
$select = Ox.Select({
|
$select = Ox.Select({
|
||||||
|
|
|
@ -475,7 +475,7 @@ pandora.ui.listIconPanel = function(listData) {
|
||||||
pandora.$ui.folderList[listData.folder].$element
|
pandora.$ui.folderList[listData.folder].$element
|
||||||
.find('img[src*="/' + listData.id + '/"]')
|
.find('img[src*="/' + listData.id + '/"]')
|
||||||
.attr({
|
.attr({
|
||||||
src: '/list/' + listData.id + '/icon16.jpg?' + Ox.uid()
|
src: '/list/' + listData.id + '/icon.jpg?' + Ox.uid()
|
||||||
});
|
});
|
||||||
pandora.$ui.info.updateListInfo();
|
pandora.$ui.info.updateListInfo();
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ pandora.ui.makeListPrivateDialog = function(name, subscribers, callback) {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
|
@ -12,7 +12,7 @@ pandora.ui.preferencesDialog = function() {
|
||||||
.css({overflowY: 'auto'})
|
.css({overflowY: 'auto'})
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px'})
|
.css({position: 'absolute', left: '16px', top: '16px'})
|
||||||
);
|
);
|
||||||
if (id == 'account') {
|
if (id == 'account') {
|
||||||
|
|
|
@ -97,8 +97,8 @@ pandora.ui.siteDialog = function(section) {
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/' + (
|
.attr({src: '/static/png/' + (
|
||||||
id == 'software' ? 'pandora/icon' : 'logo'
|
id == 'software' ? 'software.png' : 'logo.png'
|
||||||
) + '256.png'})
|
)})
|
||||||
.css({width: '256px'})
|
.css({width: '256px'})
|
||||||
),
|
),
|
||||||
size: 272
|
size: 272
|
||||||
|
|
|
@ -59,7 +59,7 @@ pandora.ui.tv = function() {
|
||||||
duration: result.data.duration,
|
duration: result.data.duration,
|
||||||
enableSubtitles: pandora.user.ui.videoSubtitles,
|
enableSubtitles: pandora.user.ui.videoSubtitles,
|
||||||
fullscreen: true,
|
fullscreen: true,
|
||||||
logo: pandora.site.tv.showLogo ? '/static/png/logo256.png' : '',
|
logo: pandora.site.tv.showLogo ? '/static/png/logo.png' : '',
|
||||||
muted: muted || pandora.user.ui.videoMuted,
|
muted: muted || pandora.user.ui.videoMuted,
|
||||||
position: result.data.position,
|
position: result.data.position,
|
||||||
resolution: pandora.user.ui.videoResolution,
|
resolution: pandora.user.ui.videoResolution,
|
||||||
|
|
|
@ -888,7 +888,7 @@ pandora.ui.usersDialog = function() {
|
||||||
content: Ox.Element()
|
content: Ox.Element()
|
||||||
.append(
|
.append(
|
||||||
$('<img>')
|
$('<img>')
|
||||||
.attr({src: '/static/png/icon64.png'})
|
.attr({src: '/static/png/icon.png'})
|
||||||
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
.css({position: 'absolute', left: '16px', top: '16px', width: '64px', height: '64px'})
|
||||||
)
|
)
|
||||||
.append(
|
.append(
|
||||||
|
|
BIN
static/png/icon.0xdb.org
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
static/png/icon.padma.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
BIN
static/png/logo.0xdb.org
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
static/png/logo.padma.png
Normal file
After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 7.4 KiB |
BIN
static/png/rights.png
Normal file
After Width: | Height: | Size: 158 KiB |
BIN
static/png/software.png
Normal file
After Width: | Height: | Size: 54 KiB |
|
@ -22,8 +22,11 @@ rabbitmqctl set_permissions -p /pandora pandora ".*" ".*" ".*"
|
||||||
|
|
||||||
#pandora
|
#pandora
|
||||||
HOST=$(hostname -s)
|
HOST=$(hostname -s)
|
||||||
SITE_CONFIG="/srv/pandora/pandora/$HOST.jsonc"
|
HOST_CONFIG="/srv/pandora/pandora/config.$HOST.jsonc"
|
||||||
test -e $SITE_CONFIG || cp /srv/pandora/pandora/0xdb.jsonc $SITE_CONFIG
|
SITE_CONFIG="/srv/pandora/pandora/config.jsonc"
|
||||||
|
test -e $HOST_CONFIG && cp $HOST_CONFIG $SITE_CONFIG
|
||||||
|
test -e $SITE_CONFIG || cp /srv/pandora/pandora/config.pandora.jsonc $SITE_CONFIG
|
||||||
|
|
||||||
cat > /srv/pandora/pandora/local_settings.py << EOF
|
cat > /srv/pandora/pandora/local_settings.py << EOF
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
@ -33,12 +36,13 @@ DATABASES = {
|
||||||
'PASSWORD': '',
|
'PASSWORD': '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG = False
|
|
||||||
DATA_SERVICE = ""
|
|
||||||
SITE_CONFIG = '$SITE_CONFIG'
|
|
||||||
BROKER_PASSWORD = "$RABBITPWD"
|
BROKER_PASSWORD = "$RABBITPWD"
|
||||||
XACCELREDIRECT = True
|
XACCELREDIRECT = True
|
||||||
DB_GIN_TRGM = True
|
DB_GIN_TRGM = True
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
TEMPLATE_DEBUG = DEBUG
|
||||||
|
JSON_DEBUG = False
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cd /srv/pandora/pandora
|
cd /srv/pandora/pandora
|
||||||
|
|