summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/AccountManager.py4
-rw-r--r--module/plugins/addons/MultiHoster.py4
-rw-r--r--module/remote/apitypes.py5
-rw-r--r--module/remote/apitypes_debug.py2
-rw-r--r--module/remote/pyload.thrift1
-rw-r--r--module/remote/wsbackend/AsyncHandler.py1
-rw-r--r--module/web/static/js/default.js2
-rw-r--r--module/web/static/js/views/abstract/modalView.js79
-rw-r--r--module/web/static/js/views/dashboard/dashboardView.js (renamed from module/web/static/js/views/dashboardView.js)2
-rw-r--r--module/web/static/js/views/dashboard/fileView.js (renamed from module/web/static/js/views/fileView.js)0
-rw-r--r--module/web/static/js/views/dashboard/filterView.js (renamed from module/web/static/js/views/filterView.js)0
-rw-r--r--module/web/static/js/views/dashboard/packageView.js (renamed from module/web/static/js/views/packageView.js)0
-rw-r--r--module/web/static/js/views/dashboard/selectionView.js (renamed from module/web/static/js/views/selectionView.js)0
-rw-r--r--module/web/static/js/views/input/inputLoader.js7
-rw-r--r--module/web/static/js/views/input/inputView.js55
-rw-r--r--module/web/static/js/views/input/textInput.js33
-rw-r--r--module/web/static/js/views/queryModal.js35
-rwxr-xr-xmodule/web/templates/default/backbone/queryDialog.html14
18 files changed, 182 insertions, 62 deletions
diff --git a/module/AccountManager.py b/module/AccountManager.py
index 45b4eef95..d90c957c3 100644
--- a/module/AccountManager.py
+++ b/module/AccountManager.py
@@ -100,7 +100,7 @@ class AccountManager:
if plugin in self.accounts and user in self.accounts[plugin]:
del self.accounts[plugin][user]
self.core.db.removeAccount(plugin, user)
- self.core.eventManager.dispatchEvent("accountDeleted", plugin, user)
+ self.core.eventManager.dispatchEvent("account:deleted", plugin, user)
else:
self.core.log.debug("Remove non existing account %s %s" % (plugin, user))
@@ -137,4 +137,4 @@ class AccountManager:
acc.getAccountInfo(True)
def sendChange(self, plugin, name):
- self.core.eventManager.dispatchEvent("accountUpdated", plugin, name) \ No newline at end of file
+ self.core.eventManager.dispatchEvent("account:updated", plugin, name) \ No newline at end of file
diff --git a/module/plugins/addons/MultiHoster.py b/module/plugins/addons/MultiHoster.py
index 05d25b958..825085df8 100644
--- a/module/plugins/addons/MultiHoster.py
+++ b/module/plugins/addons/MultiHoster.py
@@ -66,7 +66,7 @@ class MultiHoster(Addon):
- @AddEventListener("accountDeleted")
+ @AddEventListener("account:deleted")
def refreshAccounts(self, plugin=None, user=None):
self.plugins = {}
@@ -75,7 +75,7 @@ class MultiHoster(Addon):
if isinstance(account, MultiHosterAccount) and account.isUsable():
self.addHoster(account)
- @AddEventListener("accountUpdated")
+ @AddEventListener("account:updated")
def refreshAccount(self, plugin, user):
account = self.core.accountManager.getAccount(plugin, user)
diff --git a/module/remote/apitypes.py b/module/remote/apitypes.py
index 83eb19450..e81c960c8 100644
--- a/module/remote/apitypes.py
+++ b/module/remote/apitypes.py
@@ -127,16 +127,15 @@ class AddonService(BaseObject):
self.media = media
class ConfigHolder(BaseObject):
- __slots__ = ['name', 'label', 'description', 'long_description', 'items', 'info', 'handler']
+ __slots__ = ['name', 'label', 'description', 'long_description', 'items', 'info']
- def __init__(self, name=None, label=None, description=None, long_description=None, items=None, info=None, handler=None):
+ def __init__(self, name=None, label=None, description=None, long_description=None, items=None, info=None):
self.name = name
self.label = label
self.description = description
self.long_description = long_description
self.items = items
self.info = info
- self.handler = handler
class ConfigInfo(BaseObject):
__slots__ = ['name', 'label', 'description', 'category', 'user_context', 'activated']
diff --git a/module/remote/apitypes_debug.py b/module/remote/apitypes_debug.py
index 6909464d4..7b1b5e7f3 100644
--- a/module/remote/apitypes_debug.py
+++ b/module/remote/apitypes_debug.py
@@ -21,7 +21,7 @@ classes = {
'AccountInfo' : [basestring, basestring, int, bool, int, int, int, bool, bool, bool, (dict, basestring, basestring)],
'AddonInfo' : [basestring, basestring, basestring],
'AddonService' : [basestring, basestring, (list, basestring), (None, int)],
- 'ConfigHolder' : [basestring, basestring, basestring, basestring, (list, ConfigItem), (None, (list, AddonInfo)), (None, (list, InteractionTask))],
+ 'ConfigHolder' : [basestring, basestring, basestring, basestring, (list, ConfigItem), (None, (list, AddonInfo))],
'ConfigInfo' : [basestring, basestring, basestring, basestring, bool, (None, bool)],
'ConfigItem' : [basestring, basestring, basestring, Input, basestring, basestring],
'DownloadInfo' : [basestring, basestring, basestring, int, basestring, basestring],
diff --git a/module/remote/pyload.thrift b/module/remote/pyload.thrift
index 76e755de0..2aeb54091 100644
--- a/module/remote/pyload.thrift
+++ b/module/remote/pyload.thrift
@@ -250,7 +250,6 @@ struct ConfigHolder {
4: string long_description,
5: list<ConfigItem> items,
6: optional list<AddonInfo> info,
- 7: optional list<InteractionTask> handler, // if null plugin is not loaded
}
struct ConfigInfo {
diff --git a/module/remote/wsbackend/AsyncHandler.py b/module/remote/wsbackend/AsyncHandler.py
index b40f0ea4e..d9e302fbb 100644
--- a/module/remote/wsbackend/AsyncHandler.py
+++ b/module/remote/wsbackend/AsyncHandler.py
@@ -80,6 +80,7 @@ class AsyncHandler(AbstractHandler):
for req in self.clients:
# filter events that these user is no owner of
# TODO: events are security critical, this should be revised later
+ # TODO: permissions? interaction etc
if not req.api.user.isAdmin():
skip = False
for arg in args:
diff --git a/module/web/static/js/default.js b/module/web/static/js/default.js
index afe624ff9..44c8842fa 100644
--- a/module/web/static/js/default.js
+++ b/module/web/static/js/default.js
@@ -1,4 +1,4 @@
-define('default', ['require', 'jquery', 'app', 'views/headerView', 'views/dashboardView'],
+define('default', ['require', 'jquery', 'app', 'views/headerView', 'views/dashboard/dashboardView'],
function(require, $, App, HeaderView, DashboardView) {
App.init = function() {
diff --git a/module/web/static/js/views/abstract/modalView.js b/module/web/static/js/views/abstract/modalView.js
index d3ac34bd6..1e45e942b 100644
--- a/module/web/static/js/views/abstract/modalView.js
+++ b/module/web/static/js/views/abstract/modalView.js
@@ -31,47 +31,57 @@ define(['jquery', 'backbone', 'underscore', 'omniwindow'], function($, Backbone,
},
+ // TODO: whole modal stuff is not very elegant
render: function() {
this.$el.html(this.template(this.renderContent()));
- this.$el.addClass('modal hide');
- this.$el.css({opacity: 0, scale: 0.7});
- $("body").append(this.el);
-
- var self = this;
-
- this.dialog = this.$el.omniWindow({
- overlay: {
- selector: '#modal-overlay',
- hideClass: 'hide',
- animations: {
- hide: function(subjects, internalCallback) {
- subjects.overlay.transition({opacity: 'hide', delay: 100}, 300, function() {
+ this.onRender();
+
+ if (this.dialog === null) {
+ this.$el.addClass('modal hide');
+ this.$el.css({opacity: 0, scale: 0.7});
+
+ var self = this;
+ $("body").append(this.el);
+ this.dialog = this.$el.omniWindow({
+ overlay: {
+ selector: '#modal-overlay',
+ hideClass: 'hide',
+ animations: {
+ hide: function(subjects, internalCallback) {
+ subjects.overlay.transition({opacity: 'hide', delay: 100}, 300, function() {
+ internalCallback(subjects);
+ self.onHide();
+ if (self.onHideDestroy)
+ self.destroy();
+ });
+ },
+ show: function(subjects, internalCallback) {
+ subjects.overlay.fadeIn(300);
internalCallback(subjects);
- if (self.onHideDestroy)
- self.destroy();
- });
- },
- show: function(subjects, internalCallback) {
- subjects.overlay.fadeIn(300);
- internalCallback(subjects);
- }}},
- modal: {
- hideClass: 'hide',
- animations: {
- hide: function(subjects, internalCallback) {
- subjects.modal.transition({opacity: 'hide', scale: 0.7}, 300);
- internalCallback(subjects);
- },
-
- show: function(subjects, internalCallback) {
- subjects.modal.transition({opacity: 'show', scale: 1, delay: 100}, 300, function() {
+ }}},
+ modal: {
+ hideClass: 'hide',
+ animations: {
+ hide: function(subjects, internalCallback) {
+ subjects.modal.transition({opacity: 'hide', scale: 0.7}, 300);
internalCallback(subjects);
- });
- }}
- }});
+ },
+
+ show: function(subjects, internalCallback) {
+ subjects.modal.transition({opacity: 'show', scale: 1, delay: 100}, 300, function() {
+ internalCallback(subjects);
+ });
+ }}
+ }});
+ }
return this;
},
+
+ onRender: function() {
+
+ },
+
renderContent: function() {
return {content: $('<h1>Content!</h1>').html()};
},
@@ -91,7 +101,6 @@ define(['jquery', 'backbone', 'underscore', 'omniwindow'], function($, Backbone,
hide: function() {
this.dialog.trigger('hide');
- this.onHide();
},
onHide: function() {
diff --git a/module/web/static/js/views/dashboardView.js b/module/web/static/js/views/dashboard/dashboardView.js
index 58a50777c..c888214df 100644
--- a/module/web/static/js/views/dashboardView.js
+++ b/module/web/static/js/views/dashboard/dashboardView.js
@@ -1,5 +1,5 @@
define(['jquery', 'backbone', 'underscore', 'app', 'models/TreeCollection',
- 'views/packageView', 'views/fileView', 'views/selectionView', 'views/filterView', 'select2'],
+ './packageView', './fileView', './selectionView', './filterView', 'select2'],
function($, Backbone, _, App, TreeCollection, packageView, fileView, selectionView, filterView) {
// Renders whole dashboard
diff --git a/module/web/static/js/views/fileView.js b/module/web/static/js/views/dashboard/fileView.js
index c673041b5..c673041b5 100644
--- a/module/web/static/js/views/fileView.js
+++ b/module/web/static/js/views/dashboard/fileView.js
diff --git a/module/web/static/js/views/filterView.js b/module/web/static/js/views/dashboard/filterView.js
index 14968f2cc..14968f2cc 100644
--- a/module/web/static/js/views/filterView.js
+++ b/module/web/static/js/views/dashboard/filterView.js
diff --git a/module/web/static/js/views/packageView.js b/module/web/static/js/views/dashboard/packageView.js
index 547c1470d..547c1470d 100644
--- a/module/web/static/js/views/packageView.js
+++ b/module/web/static/js/views/dashboard/packageView.js
diff --git a/module/web/static/js/views/selectionView.js b/module/web/static/js/views/dashboard/selectionView.js
index 546cda847..546cda847 100644
--- a/module/web/static/js/views/selectionView.js
+++ b/module/web/static/js/views/dashboard/selectionView.js
diff --git a/module/web/static/js/views/input/inputLoader.js b/module/web/static/js/views/input/inputLoader.js
new file mode 100644
index 000000000..5ccf07695
--- /dev/null
+++ b/module/web/static/js/views/input/inputLoader.js
@@ -0,0 +1,7 @@
+define(['./textInput'], function(textInput) {
+
+ // selects appropriate input element
+ return function(input, value, default_value, description) {
+ return textInput;
+ };
+}); \ No newline at end of file
diff --git a/module/web/static/js/views/input/inputView.js b/module/web/static/js/views/input/inputView.js
new file mode 100644
index 000000000..15dc71aad
--- /dev/null
+++ b/module/web/static/js/views/input/inputView.js
@@ -0,0 +1,55 @@
+define(['jquery', 'backbone', 'underscore'], function($, Backbone, _) {
+
+ // Renders input elements
+ return Backbone.View.extend({
+
+ tagName: 'input',
+
+ model: null,
+ value: null,
+ default_value: null,
+ description: null,
+
+ initialize: function(model, value, default_value, description) {
+ this.model = model;
+ this.value = value;
+ this.default_value = default_value;
+ this.description = description;
+ },
+
+ render: function() {
+ return this;
+ },
+
+ destroy: function() {
+ this.undelegateEvents();
+ this.unbind();
+ if (this.onDestroy) {
+ this.onDestroy();
+ }
+ this.$el.removeData().unbind();
+ this.remove();
+ },
+
+ // focus the input element
+ focus: function() {
+ this.$el.focus();
+ },
+
+ // Clear the input
+ clear: function() {
+
+ },
+
+ // retrieve value of the input
+ getVal: function() {
+ return this.value;
+ },
+
+ // the child class must call this when the value changed
+ setVal: function(value) {
+ this.value = value;
+ this.trigger('change', value);
+ }
+ });
+}); \ No newline at end of file
diff --git a/module/web/static/js/views/input/textInput.js b/module/web/static/js/views/input/textInput.js
new file mode 100644
index 000000000..7252ce289
--- /dev/null
+++ b/module/web/static/js/views/input/textInput.js
@@ -0,0 +1,33 @@
+define(['jquery', 'backbone', 'underscore', './inputView'], function($, Backbone, _, inputView) {
+
+ return inputView.extend({
+
+ // TODO
+ tagName: 'input',
+ events: {
+ 'keypress': 'onChange'
+ },
+
+ render: function() {
+ this.$el.attr('type', 'text');
+ this.$el.attr('name', 'textInput');
+
+ if (this.default_value)
+ this.$el.attr('placeholder', this.default_value);
+
+ if (this.value)
+ this.$el.val(this.value);
+
+ return this;
+ },
+
+ clear: function() {
+ this.$el.val('');
+ },
+
+ onChange: function(e) {
+ this.setVal(this.$el.val());
+ }
+
+ });
+}); \ No newline at end of file
diff --git a/module/web/static/js/views/queryModal.js b/module/web/static/js/views/queryModal.js
index 5d1585a0d..86fd5b78b 100644
--- a/module/web/static/js/views/queryModal.js
+++ b/module/web/static/js/views/queryModal.js
@@ -1,15 +1,18 @@
-define(['jquery', 'underscore', 'app', 'views/abstract/modalView', 'text!tpl/default/queryDialog.html'],
- function($, _, App, modalView, template) {
+define(['jquery', 'underscore', 'app', 'views/abstract/modalView', './input/inputLoader', 'text!tpl/default/queryDialog.html'],
+ function($, _, App, modalView, load_input, template) {
return modalView.extend({
events: {
'click .btn-success': 'submit',
'submit form': 'submit'
},
+ template: _.compile(template),
- model: null,
+ // the notificationView
parent: null,
- template: _.compile(template),
+
+ model: null,
+ input: null,
initialize: function() {
// Inherit parent events
@@ -23,32 +26,42 @@ define(['jquery', 'underscore', 'app', 'views/abstract/modalView', 'text!tpl/def
description: this.model.get('description')
};
+ var input = this.model.get('input').data;
if (this.model.isCaptcha()) {
- var input = this.model.get('input').data;
data.captcha = input[0];
data.type = input[1];
}
-
return data;
},
+ onRender: function() {
+ // instantiate the input
+ var input = this.model.get('input');
+ var inputView = load_input(input);
+ this.input = new inputView(input);
+ // only renders after wards
+ this.$('#inputField').append(this.input.render().el);
+ },
+
submit: function(e) {
e.stopPropagation();
- // TODO: different input types
// TODO: load next task
- this.model.set('result', this.$('input').val());
+ this.model.set('result', this.input.getVal());
var self = this;
this.model.save({success: function() {
self.hide();
}});
- this.$('input').val('');
+ this.input.clear();
},
onShow: function() {
- this.$('input').focus();
- }
+ this.input.focus();
+ },
+ onHide: function() {
+ this.input.destroy();
+ }
});
}); \ No newline at end of file
diff --git a/module/web/templates/default/backbone/queryDialog.html b/module/web/templates/default/backbone/queryDialog.html
index a37ac6256..eb05c20e2 100755
--- a/module/web/templates/default/backbone/queryDialog.html
+++ b/module/web/templates/default/backbone/queryDialog.html
@@ -10,12 +10,16 @@
<legend><% description %></legend>
<div class="control-group">
<%= if captcha %>
- <label class="control-label" for="inputText"><img src="data:image/<% type %>;base64,<% captcha %>"></label>
- <div class="controls">
- <input type="text" id="inputText" name="captcha">
- </div>
+ <label class="control-label" for="inputField">
+ <img src="data:image/<% type %>;base64,<% captcha %>">
+ </label>
+ <% else %>
+ <label class="control-label" for="inputField">
+ <% content %>
+ </label>
<%/if%>
- <% content %>
+ <div class="controls" id="inputField">
+ </div>
</div>
</form>
{% endblock %}