forked from 0x2620/pandora
merge
This commit is contained in:
commit
cf44cc885d
72 changed files with 147 additions and 649 deletions
0
pandora/app/management/__init__.py
Normal file
0
pandora/app/management/__init__.py
Normal file
0
pandora/app/management/commands/__init__.py
Normal file
0
pandora/app/management/commands/__init__.py
Normal file
15
pandora/app/management/commands/update_static.py
Normal file
15
pandora/app/management/commands/update_static.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vi:si:et:sw=4:sts=4:ts=4
|
||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
from ... import models
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
help = 'update static files'
|
||||||
|
args = ''
|
||||||
|
|
||||||
|
def handle(self, **options):
|
||||||
|
models.update_static()
|
|
@ -10,6 +10,7 @@ import thread
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import ox.jsonc
|
import ox.jsonc
|
||||||
|
from ox.utils import json
|
||||||
|
|
||||||
_win = (sys.platform == "win32")
|
_win = (sys.platform == "win32")
|
||||||
|
|
||||||
|
@ -52,3 +53,28 @@ def reloader_thread():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
thread.start_new_thread(reloader_thread, ())
|
thread.start_new_thread(reloader_thread, ())
|
||||||
|
|
||||||
|
def update_static():
|
||||||
|
oxjs_build = os.path.join(settings.STATIC_ROOT, 'oxjs/tools/build/build.py')
|
||||||
|
if os.path.exists(oxjs_build):
|
||||||
|
os.system(oxjs_build)
|
||||||
|
|
||||||
|
data = ''
|
||||||
|
js = []
|
||||||
|
pandora_js = os.path.join(settings.STATIC_ROOT, 'js/pandora.js')
|
||||||
|
pandora_json = os.path.join(settings.STATIC_ROOT, 'json/pandora.json')
|
||||||
|
for root, folders, files in os.walk(os.path.join(settings.STATIC_ROOT, 'js/pandora')):
|
||||||
|
for f in files:
|
||||||
|
js.append(os.path.join(root, f)[len(settings.STATIC_ROOT)+1:])
|
||||||
|
with open(os.path.join(root, f)) as j:
|
||||||
|
data += j.read() + '\n'
|
||||||
|
|
||||||
|
print 'write', pandora_js
|
||||||
|
with open(pandora_js, 'w') as f:
|
||||||
|
#data = ox.js.minify(data)
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
print 'write', pandora_json
|
||||||
|
with open(pandora_json, 'w') as f:
|
||||||
|
json.dump(sorted(js), f, indent=2)
|
||||||
|
|
||||||
|
|
|
@ -91,3 +91,4 @@ def redirect_url(request, url):
|
||||||
return redirect(url)
|
return redirect(url)
|
||||||
else:
|
else:
|
||||||
return HttpResponse('<script>document.location.href=%s;</script>'%json.dumps(url))
|
return HttpResponse('<script>document.location.href=%s;</script>'%json.dumps(url))
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from forms import FileAdminForm, InstanceAdminForm
|
|
||||||
import models
|
import models
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,13 +14,11 @@ class FileAdmin(admin.ModelAdmin):
|
||||||
def itemId(self, obj):
|
def itemId(self, obj):
|
||||||
return '%s'%(obj.item.itemId)
|
return '%s'%(obj.item.itemId)
|
||||||
|
|
||||||
form = FileAdminForm
|
|
||||||
|
|
||||||
admin.site.register(models.File, FileAdmin)
|
admin.site.register(models.File, FileAdmin)
|
||||||
|
|
||||||
|
|
||||||
class InstanceAdmin(admin.ModelAdmin):
|
class InstanceAdmin(admin.ModelAdmin):
|
||||||
search_fields = ['path', 'volume__name', 'file__oshash']
|
search_fields = ['path', 'volume__name', 'file__oshash']
|
||||||
form = InstanceAdminForm
|
|
||||||
|
|
||||||
admin.site.register(models.Instance, InstanceAdmin)
|
admin.site.register(models.Instance, InstanceAdmin)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from ajax_filtered_fields.forms import ForeignKeyByLetter
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
||||||
|
@ -6,29 +5,3 @@ import models
|
||||||
from item.models import Item
|
from item.models import Item
|
||||||
|
|
||||||
|
|
||||||
ajax_filtered_js = (
|
|
||||||
settings.ADMIN_MEDIA_PREFIX + "js/SelectBox.js",
|
|
||||||
settings.ADMIN_MEDIA_PREFIX + "js/SelectFilter2.js",
|
|
||||||
settings.STATIC_URL + 'js/jquery/jquery.js',
|
|
||||||
settings.STATIC_URL + 'js/ajax_filtered_fields.js',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class FileAdminForm(forms.ModelForm):
|
|
||||||
item = ForeignKeyByLetter(Item, field_name='itemId')
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = models.File
|
|
||||||
|
|
||||||
class Media:
|
|
||||||
js = ajax_filtered_js
|
|
||||||
|
|
||||||
|
|
||||||
class InstanceAdminForm(forms.ModelForm):
|
|
||||||
file = ForeignKeyByLetter(models.File, field_name='path')
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = models.Instance
|
|
||||||
|
|
||||||
class Media:
|
|
||||||
js = ajax_filtered_js
|
|
||||||
|
|
|
@ -1,20 +1,2 @@
|
||||||
from ajax_filtered_fields.forms import AjaxManyToManyField, ForeignKeyByLetter
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
ajax_filtered_js = (
|
|
||||||
settings.ADMIN_MEDIA_PREFIX + "js/SelectBox.js",
|
|
||||||
settings.ADMIN_MEDIA_PREFIX + "js/SelectFilter2.js",
|
|
||||||
settings.STATIC_URL + 'js/jquery/jquery.js',
|
|
||||||
settings.STATIC_URL + 'js/ajax_filtered_fields.js',
|
|
||||||
)
|
|
||||||
"""
|
|
||||||
class ItemAdminForm(forms.ModelForm):
|
|
||||||
imdb = ForeignKeyByLetter(models.ItemImdb, field_name='title')
|
|
||||||
oxdb = ForeignKeyByLetter(models.ItemOxdb, field_name='title')
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = models.Item
|
|
||||||
|
|
||||||
class Media:
|
|
||||||
js = ajax_filtered_js
|
|
||||||
"""
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/png/icon16.png"/>
|
<link rel="shortcut icon" type="image/png" href="/static/png/icon16.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/highlight.pack.js"></script>
|
<script type="text/javascript" src="/static/js/api/highlight.pack.js"></script>
|
||||||
<script type="text/javascript" src="/static/js/pandora.api.js"></script>
|
<script type="text/javascript" src="/static/js/api/pandora.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<title>{{settings.SITENAME}}</title>
|
<title>{{settings.SITENAME}}</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
<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/pandoraEmbed.js"></script>
|
<script type="text/javascript" src="/static/js/embed/pandora.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="/static/oxjs/dev/Ox.js"></script>
|
<script type="text/javascript" src="/static/oxjs/build/Ox.js"></script>
|
||||||
<script type="text/javascript" src="/static/js/pandora.js"></script>
|
<script type="text/javascript" src="/static/js/init.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
-e bzr+http://code.0x2620.org/oxtimeline/#egg=oxtimeline
|
-e bzr+http://code.0x2620.org/oxtimeline/#egg=oxtimeline
|
||||||
simplejson
|
simplejson
|
||||||
chardet
|
chardet
|
||||||
-e hg+https://django-ajax-filtered-fields.googlecode.com/hg/#egg=django-ajax-filtered-fields
|
|
||||||
celery>2.1.1
|
celery>2.1.1
|
||||||
django-celery>2.1.1
|
django-celery>2.1.1
|
||||||
#django_extensions
|
#django_extensions
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
ajax_filtered_fields = {
|
|
||||||
|
|
||||||
request_url: "/ajax_filtered_fields/json_index/",
|
|
||||||
data_loaded: "data_loaded",
|
|
||||||
|
|
||||||
_appendOption: function(obj, selector) {
|
|
||||||
// append a json data row as an option to the selector
|
|
||||||
var option = $('<option>' + obj[1] + '</option>');
|
|
||||||
option.attr({value: obj[0]});
|
|
||||||
option.appendTo(selector);
|
|
||||||
return option;
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeOptions: function(selector) {
|
|
||||||
// remove all options from selector
|
|
||||||
selector.children("option").each(function(i) {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getManyToManyJSON: function(element_id, app_label, object_name,
|
|
||||||
lookup_string, select_related) {
|
|
||||||
// manage the ManyToMany ajax request
|
|
||||||
var selector_from = $("#" + element_id + "_from");
|
|
||||||
var selector_to = $("#" + element_id + "_to");
|
|
||||||
|
|
||||||
$("#" + element_id + "_input").val("");
|
|
||||||
selector_from.attr("disabled", true);
|
|
||||||
selector_to.attr("disabled", true);
|
|
||||||
|
|
||||||
this._removeOptions(selector_from);
|
|
||||||
|
|
||||||
$.getJSON(this.request_url, {
|
|
||||||
app_label: app_label,
|
|
||||||
object_name: object_name,
|
|
||||||
lookup_string: lookup_string,
|
|
||||||
select_related: select_related},
|
|
||||||
function(data){
|
|
||||||
$.each(data, function(i, obj){
|
|
||||||
var option_is_selected = selector_to.children("option[value='" + obj[0] + "']").length;
|
|
||||||
if (!option_is_selected) {
|
|
||||||
ajax_filtered_fields._appendOption(obj, selector_from);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
SelectBox.init(element_id + "_from");
|
|
||||||
selector_from.attr("disabled", false);
|
|
||||||
selector_to.attr("disabled", false);
|
|
||||||
selector_from.trigger(ajax_filtered_fields.data_loaded);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getForeignKeyJSON: function(element_id, app_label, object_name,
|
|
||||||
lookup_string, select_related) {
|
|
||||||
// manage the ForeignKey ajax request
|
|
||||||
var selector = $("#" + element_id);
|
|
||||||
var hidden = $("#hidden-" + element_id);
|
|
||||||
|
|
||||||
$("#" + element_id + "_input").val("");
|
|
||||||
selector.attr("disabled", true);
|
|
||||||
|
|
||||||
this._removeOptions(selector);
|
|
||||||
|
|
||||||
$.getJSON(this.request_url, {
|
|
||||||
app_label: app_label,
|
|
||||||
object_name: object_name,
|
|
||||||
lookup_string: lookup_string,
|
|
||||||
select_related: select_related},
|
|
||||||
function(data){
|
|
||||||
var selection = hidden.val();
|
|
||||||
ajax_filtered_fields._appendOption(new Array("", "---------"), selector);
|
|
||||||
$.each(data, function(i, obj){
|
|
||||||
ajax_filtered_fields._appendOption(obj, selector);
|
|
||||||
});
|
|
||||||
selector.children("option[value='" + selection + "']").attr("selected", "selected");
|
|
||||||
selector.attr("disabled", false);
|
|
||||||
SelectBox.init(element_id);
|
|
||||||
ajax_filtered_fields.bindForeignKeyOptions(element_id);
|
|
||||||
selector.trigger(ajax_filtered_fields.data_loaded);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
bindForeignKeyOptions: function(element_id) {
|
|
||||||
// bind the dummy options to the hidden field that do the work
|
|
||||||
var selector = $("#" + element_id);
|
|
||||||
var hidden = $("#hidden-" + element_id);
|
|
||||||
selector.change(function(e) {
|
|
||||||
hidden.val($(this).val());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -29,7 +29,7 @@ Ox.load({
|
||||||
hideScreen: false,
|
hideScreen: false,
|
||||||
loadImages: true,
|
loadImages: true,
|
||||||
showScreen: true,
|
showScreen: true,
|
||||||
theme: 'modern'
|
theme: localStorage?localStorage.theme:'modern'
|
||||||
},
|
},
|
||||||
Geo: {}
|
Geo: {}
|
||||||
}, function(browserSupported) {
|
}, function(browserSupported) {
|
||||||
|
@ -54,7 +54,7 @@ Ox.load({
|
||||||
ui: {}
|
ui: {}
|
||||||
});
|
});
|
||||||
|
|
||||||
loadResources('/static/json/pandora.json', function() {
|
loadResources(function() {
|
||||||
|
|
||||||
Ox.print('Ox.App load', data);
|
Ox.print('Ox.App load', data);
|
||||||
|
|
||||||
|
@ -144,34 +144,33 @@ Ox.load({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}, '/static/'); // fixme: why does loadResources have an argument after callback????
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function loadResources(json, callback, prefix) {
|
function loadResources(callback) {
|
||||||
prefix = prefix || '';
|
var prefix = '/static/';
|
||||||
$.getJSON(json, function(files) {
|
if(localStorage && localStorage.debug) {
|
||||||
var promises = [];
|
Ox.getJSON(prefix + 'json/pandora.json', function(files) {
|
||||||
files.forEach(function(file) {
|
var promises = [];
|
||||||
// fixme: opera doesnt fire onload for svgs
|
files.forEach(function(file) {
|
||||||
// (but neither do we support opera nor do we have svgs)
|
var dfd = new $.Deferred();
|
||||||
if ($.browser.opera && Ox.endsWith(file, '.svg')) {
|
promises.push(dfd.promise());
|
||||||
return;
|
Ox.loadFile(prefix + file, function() {
|
||||||
}
|
dfd.resolve();
|
||||||
var dfd = new $.Deferred();
|
});
|
||||||
promises.push(dfd.promise());
|
|
||||||
Ox.loadFile(prefix + file, function() {
|
|
||||||
dfd.resolve();
|
|
||||||
});
|
});
|
||||||
|
$.when.apply(null, promises)
|
||||||
|
.done(function() {
|
||||||
|
callback();
|
||||||
|
})
|
||||||
|
.fail(function() {
|
||||||
|
throw new Error('File not found.');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
$.when.apply(null, promises)
|
} else {
|
||||||
.done(function() {
|
Ox.loadFile(prefix + 'js/pandora.js', callback);
|
||||||
callback();
|
}
|
||||||
})
|
|
||||||
.fail(function() {
|
|
||||||
throw new Error('File not found.')
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
|
@ -1,393 +0,0 @@
|
||||||
if(typeof(pandora.afterLaunch) == "undefined")
|
|
||||||
pandora.afterLaunch = [];
|
|
||||||
|
|
||||||
//pandora.afterLaunch[0]();
|
|
||||||
pandora.afterLaunch.push(function() {
|
|
||||||
if (typeof(OxFF) == 'undefined')
|
|
||||||
return;
|
|
||||||
pandora.local = {
|
|
||||||
api: new OxFF(),
|
|
||||||
volumes: function(cb) {
|
|
||||||
var _this = this;
|
|
||||||
Ox.print('api.volumes');
|
|
||||||
this.api.login(window, pandora.user.username);
|
|
||||||
Ox.print('api.now access');
|
|
||||||
this.api.access(function(access) {
|
|
||||||
Ox.print('access callback', access);
|
|
||||||
if(!access) {
|
|
||||||
var dialogHeight = pandora.$document.height()/2,
|
|
||||||
dialogWidth = parseInt((dialogHeight - 48) * 0.75);
|
|
||||||
|
|
||||||
var $dialog = new Ox.Dialog({
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
title: 'Close',
|
|
||||||
click: function() {
|
|
||||||
$dialog.close();
|
|
||||||
delete $dialog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
height: dialogHeight,
|
|
||||||
padding: 0,
|
|
||||||
title: "Pan.do/ra OxFF Local Archive",
|
|
||||||
width: dialogWidth
|
|
||||||
})
|
|
||||||
.append("For this part of the page to work, you have to allow OxFF to send data to this site")
|
|
||||||
.open();
|
|
||||||
} else {
|
|
||||||
_this.api.volumes(function(result) {
|
|
||||||
var data = JSON.parse(result);
|
|
||||||
cb(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
files: function(archive, cb) {
|
|
||||||
this.api.login(window, pandora.user.username);
|
|
||||||
if(!this.api.access())
|
|
||||||
return false;
|
|
||||||
this.api.files(archive, function(result) {
|
|
||||||
var data = JSON.parse(result);
|
|
||||||
cb(data);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
upload: function(options, done_cb, progress_cb) {
|
|
||||||
function wrap(cb) {
|
|
||||||
if(!cb)
|
|
||||||
return null;
|
|
||||||
return function(result) {
|
|
||||||
var data = JSON.parse(result);
|
|
||||||
cb(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.api.upload(JSON.stringify(options),
|
|
||||||
wrap(done_cb),
|
|
||||||
wrap(progress_cb));
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
parsePath: function(path) {
|
|
||||||
var folder = path.split('/');
|
|
||||||
folder.pop();
|
|
||||||
if(folder.length==0) {
|
|
||||||
folder.push("rootfolder");
|
|
||||||
}
|
|
||||||
//FIXME: this is also done on the backend but might require more sub options
|
|
||||||
if (folder[folder.length-1] == "Extras" || folder[folder.length-1] == "Versions")
|
|
||||||
folder.pop();
|
|
||||||
folder = folder.join('/');
|
|
||||||
return {
|
|
||||||
folder: folder,
|
|
||||||
name: path.substring(folder.length),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loadVolumes: function() {
|
|
||||||
var _this = this;
|
|
||||||
Ox.print("load volumes");
|
|
||||||
var $section = new Ox.CollapsePanel({
|
|
||||||
id: 'volumes',
|
|
||||||
size: 'small',
|
|
||||||
title: 'Volumes'
|
|
||||||
});
|
|
||||||
|
|
||||||
pandora.$ui.sections.push($section);
|
|
||||||
// fixme: cleanup
|
|
||||||
pandora.local.volumes(function(data) {
|
|
||||||
Ox.print("got volumes", data);
|
|
||||||
var volumes = 0;
|
|
||||||
Ox.forEach(data, function(info, name) {
|
|
||||||
volumes ++;
|
|
||||||
Ox.print("add volume", name, info);
|
|
||||||
var status = info.available?"online":"offline";
|
|
||||||
var $line = $('<div>').css({ height: '20px' }).append(
|
|
||||||
$('<div>').css({ float: 'left', width: '16px', height: '16px', margin: '1px'}).append(
|
|
||||||
$('<img>').attr({ src: 'static/oxjs/build/png/ox.ui.modern/iconFind.png' })
|
|
||||||
.css({
|
|
||||||
width: '16px', height: '16px',
|
|
||||||
border: 0, background: 'rgb(64, 64, 64)',
|
|
||||||
WebkitBorderRadius: '2px' })
|
|
||||||
)
|
|
||||||
).append(
|
|
||||||
$('<div>').css({ float: 'left', width: '122px', height: '14px', margin: '2px' }).html(name)
|
|
||||||
).append(
|
|
||||||
$('<div>').css({ float: 'left', width: '40px', height: '14px', margin: '2px', textAlign: 'right' }).html(status)
|
|
||||||
);
|
|
||||||
$line.click(function() {
|
|
||||||
Ox.print("get files", name);
|
|
||||||
pandora.local.constructFileList(name);
|
|
||||||
});
|
|
||||||
$section.$content.append($line);
|
|
||||||
});
|
|
||||||
|
|
||||||
add_button = new Ox.Button({
|
|
||||||
id: 'add_volume',
|
|
||||||
title: 'add',
|
|
||||||
width: 32
|
|
||||||
}).bindEvent('click', function(data) {
|
|
||||||
if(_this.api.setLocation("Volume "+(volumes+1))) _this.loadVolumes();
|
|
||||||
});
|
|
||||||
var update_button = new Ox.Button({
|
|
||||||
id: 'update_archive',
|
|
||||||
title: 'update',
|
|
||||||
width: 48
|
|
||||||
}).bindEvent('click', function(data) {
|
|
||||||
update_button.options({disabled: true});
|
|
||||||
_this.api.update(function() {
|
|
||||||
update_button.options({disabled: false});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
pandora.$ui.lists.replaceWith(pandora.constructLists());
|
|
||||||
$section.find('.OxBar').append($('<div>')
|
|
||||||
.css({'text-align': 'right', 'margin': '2px'})
|
|
||||||
.append(update_button.$element)
|
|
||||||
.append(add_button.$element)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
uploadVideos: function(ids, done, progress, total) {
|
|
||||||
var _this = this;
|
|
||||||
if(typeof(total) == 'undefined')
|
|
||||||
total = ids.length;
|
|
||||||
|
|
||||||
if(ids.length>0) {
|
|
||||||
var oshash = ids.pop();
|
|
||||||
this.uploadVideo(oshash,
|
|
||||||
function(data) {
|
|
||||||
if(ids.length>0) {
|
|
||||||
Ox.print('more files in queue, calling again', ids, total);
|
|
||||||
_this.uploadVideos(ids, done, progress, total);
|
|
||||||
} else { //FIXME: should keep info about all uploads
|
|
||||||
done(data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
function(data) {
|
|
||||||
data.progress = data.progress/total;
|
|
||||||
progress(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
uploadVideo: function(oshash, done, progress) {
|
|
||||||
Ox.print('upload', oshash);
|
|
||||||
var url = pandora.local.absolute_url('/api/');
|
|
||||||
pandora.local.upload({
|
|
||||||
url: url,
|
|
||||||
data: {action: 'upload', oshash: oshash},
|
|
||||||
oshash: oshash,
|
|
||||||
action: 'frames'
|
|
||||||
},
|
|
||||||
function(result) {
|
|
||||||
Ox.print(result);
|
|
||||||
//FIXME: check result before posting video
|
|
||||||
profile = '96p.webm';
|
|
||||||
var url = pandora.local.absolute_url('/api/upload/') + '?profile=' + profile + '&oshash=' + oshash;
|
|
||||||
pandora.local.upload(
|
|
||||||
{
|
|
||||||
oshash: oshash,
|
|
||||||
action: 'video',
|
|
||||||
profile: profile,
|
|
||||||
url: url
|
|
||||||
},
|
|
||||||
done,
|
|
||||||
progress
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
uploadFile: function(oshash) {
|
|
||||||
Ox.print('upload file', oshash);
|
|
||||||
var url = pandora.local.absolute_url('/api/');
|
|
||||||
pandora.local.upload({
|
|
||||||
url: url,
|
|
||||||
data: {action: 'upload', oshash: oshash},
|
|
||||||
oshash: oshash,
|
|
||||||
action: 'file'
|
|
||||||
},
|
|
||||||
function(result) {
|
|
||||||
Ox.print(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
cancel: function(oshash) {
|
|
||||||
Ox.print('this function needs to be implemented: cancel ', oshash);
|
|
||||||
},
|
|
||||||
constructFileList: function(name) {
|
|
||||||
var _this = this,
|
|
||||||
$list = new Ox.TextList({
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "id",
|
|
||||||
operator: "+",
|
|
||||||
title: "ID",
|
|
||||||
unique: true,
|
|
||||||
visible: false,
|
|
||||||
width: 120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "path",
|
|
||||||
operator: "+",
|
|
||||||
title: "path",
|
|
||||||
unique: false,
|
|
||||||
visible: true,
|
|
||||||
width: 600
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "files",
|
|
||||||
operator: "+",
|
|
||||||
title: "files",
|
|
||||||
visible: true,
|
|
||||||
width: 80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "status",
|
|
||||||
operator: "+",
|
|
||||||
title: "status",
|
|
||||||
unique: false,
|
|
||||||
visible: true,
|
|
||||||
width:120
|
|
||||||
},
|
|
||||||
],
|
|
||||||
id: "volume",
|
|
||||||
request: function(options, callback) {
|
|
||||||
Ox.print("options, volumes", options)
|
|
||||||
if(!options.range) {
|
|
||||||
callback({
|
|
||||||
data: {
|
|
||||||
items: 58
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
pandora.local.files(name, function(result) {
|
|
||||||
var fileInfo = result.info;
|
|
||||||
pandora.api.update({
|
|
||||||
'volume': name, 'files': result.files
|
|
||||||
}, function(result) {
|
|
||||||
var videos = {};
|
|
||||||
function parseResult(result) {
|
|
||||||
//extract and upload requested videos
|
|
||||||
result.data.data.forEach(function(oshash) {
|
|
||||||
folder_ids.forEach(function(ids, i) {
|
|
||||||
if (ids.indexOf(oshash) > -1) {
|
|
||||||
if (!videos[i]) {
|
|
||||||
videos[i] = [];
|
|
||||||
var button = new Ox.Button({
|
|
||||||
id: 'upload_' + oshash,
|
|
||||||
title: 'Upload',
|
|
||||||
width: 48
|
|
||||||
}).bindEvent('click', function(fid) { return function(data) {
|
|
||||||
Ox.print(videos[fid]);
|
|
||||||
$($('#'+fid).find('.OxCell')[1]).html(function(fid) {
|
|
||||||
var button = new Ox.Button({
|
|
||||||
title: 'Cancel',
|
|
||||||
width: 48
|
|
||||||
}).bindEvent('click', function(data) {
|
|
||||||
videos[fid].forEach(function(oshash) {
|
|
||||||
_this.cancel(oshash);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return button.$element;
|
|
||||||
}(fid));
|
|
||||||
//$($('#'+fid).find('.OxCell')[2]).html('extracting data...');
|
|
||||||
pandora.local.uploadVideos(
|
|
||||||
videos[fid],
|
|
||||||
function(data) {
|
|
||||||
$($('#'+fid).find('.OxCell')[2]).html('done');
|
|
||||||
},
|
|
||||||
function(data) {
|
|
||||||
$($('#'+fid).find('.OxCell')[2]).html(parseInt(data.progress*100));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}}(i));
|
|
||||||
$($('#'+i).find('.OxCell')[2]).html(button.$element);
|
|
||||||
$('#'+i).css({'font-weight': 'bold'});
|
|
||||||
}
|
|
||||||
videos[i].push(oshash);
|
|
||||||
//add some double click callback here to trigger video upload
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//upload requested files
|
|
||||||
result.data.file.forEach(function(oshash) {
|
|
||||||
pandora.local.uploadFile(oshash);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if (result.data.info.length>0) {
|
|
||||||
var post = {'info': {}};
|
|
||||||
result.data.info.forEach(function(oshash) {
|
|
||||||
if(fileInfo[oshash]) {
|
|
||||||
post.info[oshash] = fileInfo[oshash];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pandora.api.update(post, function(result) {
|
|
||||||
parseResult(result);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
parseResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
var data = {
|
|
||||||
items: []
|
|
||||||
}
|
|
||||||
var folder_ids = {};
|
|
||||||
var folders = {};
|
|
||||||
result.files.forEach(function(file) {
|
|
||||||
var f = pandora.local.parsePath(file.path);
|
|
||||||
if(!folders[f.folder]) {
|
|
||||||
folders[f.folder] = {
|
|
||||||
id: file.oshash,
|
|
||||||
path: f.folder,
|
|
||||||
files: 0,
|
|
||||||
status:'ok',
|
|
||||||
ids: []
|
|
||||||
};
|
|
||||||
folder_ids[file.oshash] = [];
|
|
||||||
}
|
|
||||||
folders[f.folder].files++;
|
|
||||||
folder_ids[folders[f.folder].id].push(file.oshash);
|
|
||||||
});
|
|
||||||
var j = 1;
|
|
||||||
folders.forEach(function(folder) {
|
|
||||||
data.items.push(folder);
|
|
||||||
});
|
|
||||||
r = {
|
|
||||||
data: data,
|
|
||||||
}
|
|
||||||
Ox.print(r);
|
|
||||||
callback(r);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
sort: [
|
|
||||||
{
|
|
||||||
key: "path",
|
|
||||||
operator: "+"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
pandora.$ui.contentPanel.replace(1, $list);
|
|
||||||
},
|
|
||||||
absolute_url: function (url) {
|
|
||||||
var base = document.location.href;
|
|
||||||
if (url.substring(0, 1) == '/') {
|
|
||||||
base = document.location.protocol + '//' + document.location.hostname;
|
|
||||||
if(document.location.port) base += ':'+document.location.port
|
|
||||||
url = base + url;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(base.substring(base.length-1) == '/')
|
|
||||||
url = base + url;
|
|
||||||
else
|
|
||||||
url = base + '/' + url;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
pandora.local.loadVolumes();
|
|
||||||
});
|
|
|
@ -28,6 +28,7 @@ pandora.ui.item = function() {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (['video', 'timeline'].indexOf(pandora.user.ui.itemView) > -1) {
|
if (['video', 'timeline'].indexOf(pandora.user.ui.itemView) > -1) {
|
||||||
|
// fixme: layers have value, subtitles has text?
|
||||||
var subtitles = result.data.layers.subtitles
|
var subtitles = result.data.layers.subtitles
|
||||||
? result.data.layers.subtitles.map(function(subtitle) {
|
? result.data.layers.subtitles.map(function(subtitle) {
|
||||||
return {'in': subtitle['in'], out: subtitle.out, text: subtitle.value};
|
return {'in': subtitle['in'], out: subtitle.out, text: subtitle.value};
|
||||||
|
@ -54,7 +55,19 @@ pandora.ui.item = function() {
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
: [{'in': 0, out: result.data.duration}];
|
: [{'in': 0, out: result.data.duration}],
|
||||||
|
layers = [],
|
||||||
|
video = {};
|
||||||
|
|
||||||
|
pandora.site.layers.forEach(function(layer, i) {
|
||||||
|
layers[i] = Ox.extend({}, layer, {items: result.data.layers[layer.id]});
|
||||||
|
});
|
||||||
|
pandora.site.video.resolutions.forEach(function(resolution) {
|
||||||
|
video[resolution] = Ox.range(result.data.parts).map(function(i) {
|
||||||
|
return '/' + pandora.user.ui.item + '/'
|
||||||
|
+ resolution + 'p' + (i + 1) + '.' + pandora.user.videoFormat;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.data.rendered && [
|
if (!result.data.rendered && [
|
||||||
|
@ -64,7 +77,7 @@ pandora.ui.item = function() {
|
||||||
Ox.Element()
|
Ox.Element()
|
||||||
.css({marginTop: '32px', fontSize: '12px', textAlign: 'center'})
|
.css({marginTop: '32px', fontSize: '12px', textAlign: 'center'})
|
||||||
.html(
|
.html(
|
||||||
'Sorry, <i>' + result.data.title
|
'Sorry, <i>' + result.data.title
|
||||||
+ '</i> currently doesn\'t have a '
|
+ '</i> currently doesn\'t have a '
|
||||||
+ pandora.user.ui.itemView + ' view.'
|
+ pandora.user.ui.itemView + ' view.'
|
||||||
)
|
)
|
||||||
|
@ -135,18 +148,7 @@ pandora.ui.item = function() {
|
||||||
} else if (pandora.user.ui.itemView == 'video') {
|
} else if (pandora.user.ui.itemView == 'video') {
|
||||||
// fixme: duplicated
|
// fixme: duplicated
|
||||||
var clipsQuery = pandora.getClipsQuery(),
|
var clipsQuery = pandora.getClipsQuery(),
|
||||||
isClipsQuery = !!clipsQuery.conditions.length,
|
isClipsQuery = !!clipsQuery.conditions.length;
|
||||||
layers = [],
|
|
||||||
video = {};
|
|
||||||
pandora.site.layers.forEach(function(layer, i) {
|
|
||||||
layers[i] = Ox.extend({}, layer, {items: result.data.layers[layer.id]});
|
|
||||||
});
|
|
||||||
pandora.site.video.resolutions.forEach(function(resolution) {
|
|
||||||
video[resolution] = Ox.range(result.data.parts).map(function(i) {
|
|
||||||
return '/' + pandora.user.ui.item + '/'
|
|
||||||
+ resolution + 'p' + (i + 1) + '.' + pandora.user.videoFormat;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//
|
//
|
||||||
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.player = Ox.VideoPanelPlayer({
|
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.player = Ox.VideoPanelPlayer({
|
||||||
annotationsSize: pandora.user.ui.annotationsSize,
|
annotationsSize: pandora.user.ui.annotationsSize,
|
||||||
|
@ -200,18 +202,7 @@ pandora.ui.item = function() {
|
||||||
|
|
||||||
} else if (pandora.user.ui.itemView == 'timeline') {
|
} else if (pandora.user.ui.itemView == 'timeline') {
|
||||||
var clipsQuery = pandora.getClipsQuery(),
|
var clipsQuery = pandora.getClipsQuery(),
|
||||||
isClipsQuery = !!clipsQuery.conditions.length,
|
isClipsQuery = !!clipsQuery.conditions.length;
|
||||||
layers = [],
|
|
||||||
video = {};
|
|
||||||
pandora.site.layers.forEach(function(layer) {
|
|
||||||
layers.push(Ox.extend({items: result.data.layers[layer.id]}, layer));
|
|
||||||
});
|
|
||||||
pandora.site.video.resolutions.forEach(function(resolution) {
|
|
||||||
video[resolution] = Ox.range(result.data.parts).map(function(i) {
|
|
||||||
return '/' + pandora.user.ui.item + '/'
|
|
||||||
+ resolution + 'p' + (i + 1) + '.' + pandora.user.videoFormat;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.editor = Ox.VideoEditor({
|
pandora.$ui.contentPanel.replaceElement(1, pandora.$ui.editor = Ox.VideoEditor({
|
||||||
annotationsSize: pandora.user.ui.annotationsSize,
|
annotationsSize: pandora.user.ui.annotationsSize,
|
||||||
censored: censored,
|
censored: censored,
|
||||||
|
@ -237,7 +228,6 @@ pandora.ui.item = function() {
|
||||||
posterFrame: parseInt(video.duration / 2),
|
posterFrame: parseInt(video.duration / 2),
|
||||||
showAnnotations: pandora.user.ui.showAnnotations,
|
showAnnotations: pandora.user.ui.showAnnotations,
|
||||||
showLargeTimeline: true,
|
showLargeTimeline: true,
|
||||||
// fixme: layers have value, subtitles has text?
|
|
||||||
subtitles: subtitles,
|
subtitles: subtitles,
|
||||||
tooltips: true,
|
tooltips: true,
|
||||||
video: video,
|
video: video,
|
|
@ -1,60 +1,60 @@
|
||||||
[
|
[
|
||||||
"js/pandora/Query.js",
|
"js/pandora/Query.js",
|
||||||
"js/pandora/UI.js",
|
"js/pandora/UI.js",
|
||||||
"js/pandora/URL.js",
|
"js/pandora/URL.js",
|
||||||
"js/pandora/autovalidate.js",
|
"js/pandora/account.js",
|
||||||
"js/pandora/utils.js",
|
"js/pandora/appPanel.js",
|
||||||
"js/pandora/ui/filesView.js",
|
"js/pandora/autovalidate.js",
|
||||||
"js/pandora/ui/account.js",
|
"js/pandora/backButton.js",
|
||||||
"js/pandora/ui/appPanel.js",
|
"js/pandora/browser.js",
|
||||||
"js/pandora/ui/backButton.js",
|
"js/pandora/clipList.js",
|
||||||
"js/pandora/ui/browser.js",
|
"js/pandora/clipPlayer.js",
|
||||||
"js/pandora/ui/clipList.js",
|
"js/pandora/contactForm.js",
|
||||||
"js/pandora/ui/contentPanel.js",
|
"js/pandora/contentPanel.js",
|
||||||
"js/pandora/ui/contactForm.js",
|
"js/pandora/deleteListDialog.js",
|
||||||
"js/pandora/ui/deleteListDialog.js",
|
"js/pandora/editor.js",
|
||||||
"js/pandora/ui/editor.js",
|
"js/pandora/eventsDialog.js",
|
||||||
"js/pandora/ui/eventsDialog.js",
|
"js/pandora/filesView.js",
|
||||||
"js/pandora/ui/titlesDialog.js",
|
"js/pandora/filter.js",
|
||||||
"js/pandora/ui/filter.js",
|
"js/pandora/filterDialog.js",
|
||||||
"js/pandora/ui/filterDialog.js",
|
"js/pandora/findElement.js",
|
||||||
"js/pandora/ui/findElement.js",
|
"js/pandora/folderBrowser.js",
|
||||||
"js/pandora/ui/folderBrowser.js",
|
"js/pandora/folderBrowserBar.js",
|
||||||
"js/pandora/ui/folderBrowserBar.js",
|
"js/pandora/folderBrowserList.js",
|
||||||
"js/pandora/ui/folderBrowserList.js",
|
"js/pandora/folderList.js",
|
||||||
"js/pandora/ui/folderList.js",
|
"js/pandora/folders.js",
|
||||||
"js/pandora/ui/folders.js",
|
"js/pandora/group.js",
|
||||||
"js/pandora/ui/group.js",
|
"js/pandora/helpDialog.js",
|
||||||
"js/pandora/ui/home.js",
|
"js/pandora/home.js",
|
||||||
"js/pandora/ui/homePage.js",
|
"js/pandora/homePage.js",
|
||||||
"js/pandora/ui/info.js",
|
"js/pandora/info.js",
|
||||||
"js/pandora/ui/infoView.js",
|
"js/pandora/infoView.js",
|
||||||
"js/pandora/ui/item.js",
|
"js/pandora/item.js",
|
||||||
"js/pandora/ui/itemClips.js",
|
"js/pandora/itemClips.js",
|
||||||
"js/pandora/ui/leftPanel.js",
|
"js/pandora/leftPanel.js",
|
||||||
"js/pandora/ui/list.js",
|
"js/pandora/list.js",
|
||||||
"js/pandora/ui/listDialog.js",
|
"js/pandora/listDialog.js",
|
||||||
"js/pandora/ui/mainPanel.js",
|
"js/pandora/mainPanel.js",
|
||||||
"js/pandora/ui/mediaView.js",
|
"js/pandora/mediaView.js",
|
||||||
"js/pandora/ui/menu.js",
|
"js/pandora/menu.js",
|
||||||
"js/pandora/ui/namesDialog.js",
|
"js/pandora/namesDialog.js",
|
||||||
"js/pandora/ui/navigationView.js",
|
"js/pandora/navigationView.js",
|
||||||
"js/pandora/ui/orderButton.js",
|
"js/pandora/orderButton.js",
|
||||||
"js/pandora/ui/placesDialog.js",
|
"js/pandora/placesDialog.js",
|
||||||
"js/pandora/ui/preferencesDialog.js",
|
"js/pandora/preferencesDialog.js",
|
||||||
"js/pandora/ui/publicLists.js",
|
"js/pandora/publicLists.js",
|
||||||
"js/pandora/ui/rightPanel.js",
|
"js/pandora/rightPanel.js",
|
||||||
"js/pandora/ui/sectionButtons.js",
|
"js/pandora/sectionButtons.js",
|
||||||
"js/pandora/ui/sectionSelect.js",
|
"js/pandora/sectionSelect.js",
|
||||||
"js/pandora/ui/sectionbar.js",
|
"js/pandora/sectionbar.js",
|
||||||
"js/pandora/ui/siteDialog.js",
|
"js/pandora/siteDialog.js",
|
||||||
"js/pandora/ui/sortSelect.js",
|
"js/pandora/sortSelect.js",
|
||||||
"js/pandora/ui/status.js",
|
"js/pandora/status.js",
|
||||||
"js/pandora/ui/statusbar.js",
|
"js/pandora/statusbar.js",
|
||||||
"js/pandora/ui/toolbar.js",
|
"js/pandora/titlesDialog.js",
|
||||||
"js/pandora/ui/usersDialog.js",
|
"js/pandora/toolbar.js",
|
||||||
"js/pandora/ui/videoPreview.js",
|
"js/pandora/usersDialog.js",
|
||||||
"js/pandora/ui/viewSelect.js",
|
"js/pandora/utils.js",
|
||||||
"js/pandora/ui/helpDialog.js",
|
"js/pandora/videoPreview.js",
|
||||||
"js/pandora/ui/clipPlayer.js"
|
"js/pandora/viewSelect.js"
|
||||||
]
|
]
|
Loading…
Reference in a new issue