diff --git a/index.html b/index.html
index 8b7a61b..4e9f5c9 100755
--- a/index.html
+++ b/index.html
@@ -22,6 +22,8 @@
+
+
diff --git a/js/connection.js b/js/connection.js
new file mode 100644
index 0000000..08a5196
--- /dev/null
+++ b/js/connection.js
@@ -0,0 +1,153 @@
+var JsonRPC = function(conf) {
+ if (!this instanceof JsonRPC)
+ return new JsonRPC();
+ this.avgTimeout = 1000;
+ this.serverConf = conf;
+};
+JsonRPC.prototype = {
+ encode: function(obj) {
+ return base64.btoa(JSON.stringify(obj));
+ },
+ ariaRequest: function(url, multicall, funcName, params, success, error) {
+ var startTime = new Date();
+ $.ajax({
+ url: url,
+ timeout: 1000,
+ data: {
+ jsonrpc: 2.0,
+ id: 'webui',
+ method: funcName.search(/\./g) == -1 ? 'aria2.' + funcName : funcName,
+ params: params.length ? this.encode(params) : undefined
+ },
+ success: function(data) {
+ this.avgTimeout = 3 * (new Date() - startTime);
+ return success(data)
+ },
+ error: error,
+ dataType: 'jsonp',
+ jsonp: 'jsoncallback'
+ });
+ },
+ invoke: function(opts) {
+ var rpc = this;
+ rpc.ariaRequest(
+ 'http://' + rpc.serverConf.host + ':' + rpc.serverConf.port + '/jsonrpc',
+ opts.multicall,
+ opts.func,
+ opts.params,
+ opts.success,
+ function() {
+ // check if authentication details are given, if yes then use a hack to support
+ // http authentication otherwise emit error
+ if (!rpc.serverConf.user.length) {
+ console.log("no user name and still error!!!");
+ return opts.error();
+ }
+
+ var authUrl = 'http://' +
+ rpc.serverConf.user + ":" +
+ rpc.serverConf.pass + "@" +
+ rpc.serverConf.host + ':' +
+ rpc.serverConf.port + '/jsonrpc';
+
+ // hack is to basically inject an image with same uri as the aria2 rpc url,
+ // most browsers will then cache the authentication details and we dont have
+ // to give them next time we make a request
+ var img = $('').attr("src", authUrl);
+ $('body').append(img);
+ img.remove();
+
+ // timeout to let the image load and then make a request,
+ setTimeout(function() {
+ rpc.ariaRequest(
+ authUrl,
+ opts.multicall,
+ opts.params,
+ opts.success,
+ opts.error
+ );
+ }, rpc.avgTimeout);
+ }
+ );
+ }
+};
+
+var SocketRPC = function(conf) {
+ if (!this instanceof SocketRPC)
+ return new SocketRPC();
+
+ var rpc = this;
+ rpc.serverConf = conf;
+ rpc.initialized = false;
+ rpc.handles = [];
+ rpc.sock = new WebSocket('ws://' + conf.host + ':' + conf.port + '/jsonrpc');
+ rpc.sock.onopen = function() {
+ rpc.initialized = true;
+ };
+ rpc.sock.onclose = rpc.sock.onerror = function() {
+ _.each(handles, function(h) { h.error() });
+ rpc.handles = [];
+ };
+ rpc.sock.onmessage = function(message) {
+ var data = JSON.parse(message.data);
+ for (var i = rpc.handles.length; i--; ) {
+ if (rpc.handles[i].id === data.id) {
+ if (data.error)
+ rpc.handles[i].error();
+ else
+ rpc.handles[i].success(data);
+ rpc.handles.splice(i, 1);
+ return;
+ }
+ }
+ };
+}
+SocketRPC.prototype = {
+ invoke: function(opts) {
+ var data = {
+ jsonrpc: 2.0,
+ id: 'webui_' + utils.randStr(),
+ method: opts.func.search(/\./g) == -1 ? 'aria2.' + opts.func : opts.func,
+ params: opts.params.length ? opts.params : undefined
+ };
+
+ this.handles.push({
+ success: opts.success,
+ error: opts.error,
+ id: data.id
+ });
+ this.sock.send(JSON.stringify(data));
+ },
+};
+var AriaConnection = function(conf) {
+ var conf = conf || {
+ host: 'localhost',
+ port: 6800,
+ user: '',
+ pass: ''
+ };
+ var jRPC = new JsonRPC(conf);
+ if (typeof WebSocket != "undefined") {
+ var sockRPC = new SocketRPC(conf);
+ }
+
+ return {
+ conf: conf,
+ invoke: function(opts) {
+ opts = utils.mixin(opts, {
+ success: function() {},
+ error: function() {},
+ params: [],
+ func: ''
+ });
+ var err = opts.error;
+ opts.error = function() { throw "cant run error!!!" };
+ if (!sockRPC || !sockRPC.initialized || true)
+ return jRPC.invoke(opts);
+ else
+ return sockRPC.invoke(opts);
+ }
+ };
+}
+
+
diff --git a/js/manager.js b/js/manager.js
new file mode 100644
index 0000000..e69de29
diff --git a/js/script.js b/js/script.js
index d8a3f40..a6cd53d 100755
--- a/js/script.js
+++ b/js/script.js
@@ -15,10 +15,6 @@ var modals = {
new_metalink_modal: undefined,
download_settings_modal: undefined
};
-var web_sock = undefined;
-var web_sock_queue = [];
-var web_sock_id = 0;
-var web_sock_support = typeof WebSocket != "undefined" ? 1 : 0;
var clear_dialogs = function() {
for(var i in modals) {
modals[i].modal('hide');
@@ -31,6 +27,7 @@ var server_conf = {
pass: ""
};
+var ariaConnection = new AriaConnection(server_conf);
var set_conf_cookie = function() {
setCookie('aria2_server_conf', JSON.stringify(server_conf), 30 * 12);
}
@@ -56,131 +53,15 @@ var update_server_conf = function() {
if(port.length !== 0) {
server_conf.port = port;
}
- web_sock = undefined;
set_conf_cookie();
+ ariaConnection = new AriaConnection(server_conf);
clear_dialogs();
update_ui();
};
-function param_encode(param) {
- if(param) {
- param = base64.btoa(JSON.stringify(param));
- }
- return param;
-}
-
-var web_sock_error = function() {
- for(var i = 0; i < web_sock_queue.length; i++) {
- web_sock_queue[i].error();
- web_sock_queue.splice(i, 1);
- }
-}
-var web_sock_message = function(message) {
- var data = JSON.parse(message.data);
- for(var i = 0; i < web_sock_queue.length; i++) {
- if(web_sock_queue[i].id === data.id) {
- if(data.error) {
- if(web_sock_queue[i].error)
- web_sock_queue[i].error();
- }
- else {
- web_sock_queue[i].success(data);
- }
- web_sock_queue.splice(i, 1);
- }
- }
-}
-var web_sock_send = function(conf, multicall) {
- var id = 'webui_' + (web_sock_id++).toString();
- var data = {
- jsonrpc: 2.0,
- id: id,
- method: multicall? conf.func:'aria2.' + conf.func,
- params: conf.params
- };
- web_sock_queue.push({
- success: conf.success,
- error: conf.error,
- id: id
- });
- web_sock.send(JSON.stringify(data));
-}
-var web_sock_init = function() {
- if(!web_sock) {
- var sock = new WebSocket('ws://' + server_conf.host + ':' + server_conf.port + '/jsonrpc');
- sock.onopen = function() {
- console.log('websocket connected!!!');
- web_sock = sock;
- };
- sock.onclose = function() {
- web_sock_error();
- web_sock = undefined;
- };
- sock.onerror = web_sock_error;
- sock.onmessage = web_sock_message;
- }
-}
-
-var jsonp_syscall = function(conf, multicall) {
- $.ajax({
- url: 'http://' + server_conf.host + ':' + server_conf.port + '/jsonrpc',
- timeout: 1000,
- data: {
- jsonrpc: 2.0,
- id: 'webui',
- method: multicall? conf.func:'aria2.' + conf.func,
- params: param_encode(conf.params)
- },
- success: conf.success,
- error: function() {
- if(server_conf.user.length) {
- var url = 'http://' +
- server_conf.user + ":" +
- server_conf.pass + "@" +
- server_conf.host + ':' +
- server_conf.port + '/jsonrpc';
-
- /* hack for http authentication */
- var img = $('').attr("src", url);
- $('body').append(img);
- img.remove();
-
- setTimeout(function() {
- $.ajax({
- url: url,
- timeout: 1000,
- data: {
- jsonrpc: 2.0,
- id: 'webui',
- method: multicall? conf.func:'aria2.' + conf.func,
- params: param_encode(conf.params)
- },
- success: conf.success,
- error: conf.error,
- dataType: 'jsonp',
- jsonp: 'jsoncallback'
- });
- }, 1000);
- }
- else if(conf.error) {
- conf.error();
- }
- },
- dataType: 'jsonp',
- jsonp: 'jsoncallback'
- });
-}
-var aria_syscall = function(conf, multicall) {
- if(!web_sock_support || server_conf.user.length || server_conf.pass.length) {
- jsonp_syscall(conf, multicall);
- }
- else if(web_sock) {
- web_sock_send(conf, multicall);
- }
- else {
- web_sock_init();
- jsonp_syscall(conf, multicall);
- }
+var aria_syscall = function(conf, multicall, old) {
+ conf.multicall = multicall;
+ ariaConnection.invoke(conf);
}
var update_ui = function() {
updateDownloads();
@@ -207,9 +88,6 @@ $(function() {
modals.new_torrent_modal = $('#new_torrent').modal(modal_conf);
modals.new_metalink_modal = $('#new_metalink').modal(modal_conf);
- if(web_sock_support)
- web_sock_init();
-
update_ui();
globalGraphData = {
downSpeed: [],
diff --git a/js/utils.js b/js/utils.js
new file mode 100644
index 0000000..622b858
--- /dev/null
+++ b/js/utils.js
@@ -0,0 +1,18 @@
+var utils = {
+ randStr: function() {
+ var str = [];
+ var hexDigits = "0123456789abcdef";
+ for (var i = 0; i < 36; i++) {
+ str[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
+ }
+ return str.join("");
+ },
+ mixin: function(fromObj, toObj) {
+ for (var key in toObj) {
+ if (toObj.hasOwnProperty(key) && fromObj[key]) {
+ toObj[key] = fromObj[key];
+ }
+ }
+ return toObj;
+ }
+};