From a6ea0c9629db59ee55ef23da3f791e024f6cb07e Mon Sep 17 00:00:00 2001 From: MaysWind Date: Tue, 31 May 2016 01:26:41 +0800 Subject: [PATCH] support start and pause task --- app/index.html | 22 +- app/langs/zh-CN.json | 6 + app/scripts/controllers/list.js | 23 +- app/scripts/controllers/main.js | 82 +++++- app/scripts/controllers/settings-aria2.js | 6 +- app/scripts/controllers/status.js | 4 +- app/scripts/controllers/task-detail.js | 14 +- app/scripts/core/config.js | 21 +- app/scripts/core/lang-default.js | 6 + app/scripts/core/utils.js | 24 ++ app/scripts/services/aria2RpcService.js | 288 ++++++++++++++++++---- 11 files changed, 413 insertions(+), 83 deletions(-) diff --git a/app/index.html b/app/index.html index 1acf0a8..d908aec 100644 --- a/app/index.html +++ b/app/index.html @@ -44,21 +44,33 @@
  • -
  • - +
  • +
  • -
  • - +
  • +
  • - + +
  • diff --git a/app/langs/zh-CN.json b/app/langs/zh-CN.json index 7359902..5cff9bb 100644 --- a/app/langs/zh-CN.json +++ b/app/langs/zh-CN.json @@ -15,6 +15,8 @@ "Display Order": "显示顺序", "Search": "搜索", "Default": "默认", + "Remove Task": "删除任务", + "Clear Finished Tasks": "清空已完成任务", "By File Name": "按文件名", "By File Size": "按文件大小", "By Completed Percent": "按进度", @@ -65,6 +67,10 @@ "Percent": "完成度", "Download / Upload Speed": "下载 / 上传速度", "No connected peers": "没有连接到其他节点", + "Confirm Remove": "确认删除", + "Are you sure you want to remove the selected task?": "您是否要删除选中的任务?", + "Confirm Clear": "确认清除", + "Are you sure you want to clear finished tasks?": "您是否要清除已完成的任务?", "Language": "语言", "Aria2 RPC Host": "Aria2 RPC 主机", "Aria2 RPC Port": "Aria2 RPC 端口", diff --git a/app/scripts/controllers/list.js b/app/scripts/controllers/list.js index c6fcb52..fd47c9c 100644 --- a/app/scripts/controllers/list.js +++ b/app/scripts/controllers/list.js @@ -8,37 +8,18 @@ var refreshDownloadTask = function () { var invokeMethod = null; - var params = []; - var requestParams = [ - 'gid', - 'totalLength', - 'completedLength', - 'uploadSpeed', - 'downloadSpeed', - 'connections', - 'numSeeders', - 'seeder' - ]; - - if (needRequestWholeInfo) { - requestParams.push('files'); - requestParams.push('bittorrent'); - } if (location == 'downloading') { invokeMethod = aria2RpcService.tellActive; - params = [requestParams]; } else if (location == 'waiting') { invokeMethod = aria2RpcService.tellWaiting; - params = [0, 1000, requestParams]; } else if (location == 'stopped') { invokeMethod = aria2RpcService.tellStopped; - params = [0, 1000, requestParams]; } if (invokeMethod) { return invokeMethod({ - params: params, + requestParams: needRequestWholeInfo ? aria2RpcService.getFullTaskParams() : aria2RpcService.getBasicTaskParams(), callback: function (result) { if (!utils.extendArray(result, $rootScope.taskContext.list, 'gid')) { if (needRequestWholeInfo) { @@ -61,7 +42,7 @@ } }; - $scope.loadPromise = refreshDownloadTask(); + $rootScope.loadPromise = refreshDownloadTask(); $scope.filterByTaskName = function (task) { if (!task || !angular.isString(task.taskName)) { diff --git a/app/scripts/controllers/main.js b/app/scripts/controllers/main.js index 0bbaf8a..4d704e4 100644 --- a/app/scripts/controllers/main.js +++ b/app/scripts/controllers/main.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - angular.module('ariaNg').controller('MainController', ['$rootScope', '$scope', '$interval', 'aria2RpcService', 'ariaNgSettingService', 'utils', function ($rootScope, $scope, $interval, aria2RpcService, ariaNgSettingService, utils) { + angular.module('ariaNg').controller('MainController', ['$rootScope', '$scope', '$route', '$interval', 'aria2RpcService', 'ariaNgSettingService', 'utils', function ($rootScope, $scope, $route, $interval, aria2RpcService, ariaNgSettingService, utils) { var globalStatRefreshPromise = null; var processStatResult = function (stat) { @@ -26,10 +26,90 @@ refreshGlobalStat(); + $scope.startTask = function () { + var gids = $rootScope.taskContext.getSelectedTaskIds(); + + if (!gids || gids.length < 1) { + return; + } + + $rootScope.loadPromise = aria2RpcService.unpauseMulti({ + gids: gids, + callback: function (result) { + $route.reload(); + } + }); + }; + + $scope.pauseTask = function () { + var gids = $rootScope.taskContext.getSelectedTaskIds(); + + if (!gids || gids.length < 1) { + return; + } + + $rootScope.loadPromise = aria2RpcService.forcePauseMulti({ + gids: gids, + callback: function (result) { + $route.reload(); + } + }); + }; + + $scope.removeTask = function () { + var gids = $rootScope.taskContext.getSelectedTaskIds(); + + if (!gids || gids.length < 1) { + return; + } + + utils.confirm('Confirm Remove', 'Are you sure you want to remove the selected task?', 'warning', function () { + + }); + }; + + $scope.clearFinishedTasks = function () { + utils.confirm('Confirm Clear', 'Are you sure you want to clear finished tasks?', 'warning', function () { + + }); + }; + $scope.isTaskSelected = function () { return $rootScope.taskContext.getSelectedTaskIds().length > 0; }; + $scope.isStartableTaskSelected = function () { + var selectedTasks = $rootScope.taskContext.getSelectedTasks(); + + if (selectedTasks.length < 1) { + return false; + } + + for (var i = 0; i < selectedTasks.length; i++) { + if (selectedTasks[i].status == 'paused') { + return true; + } + } + + return false; + }; + + $scope.isPausableTaskSelected = function () { + var selectedTasks = $rootScope.taskContext.getSelectedTasks(); + + if (selectedTasks.length < 1) { + return false; + } + + for (var i = 0; i < selectedTasks.length; i++) { + if (selectedTasks[i].status == 'active') { + return true; + } + } + + return false; + }; + $scope.selectAllTasks = function () { $rootScope.taskContext.selectAll(); }; diff --git a/app/scripts/controllers/settings-aria2.js b/app/scripts/controllers/settings-aria2.js index d30c961..2537052 100644 --- a/app/scripts/controllers/settings-aria2.js +++ b/app/scripts/controllers/settings-aria2.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - angular.module('ariaNg').controller('Aria2SettingsController', ['$scope', '$location', '$timeout', 'ariaNgConstants', 'aria2GlobalAvailableOptions', 'aria2RpcService', 'utils', function ($scope, $location, $timeout, ariaNgConstants, aria2GlobalAvailableOptions, aria2RpcService, utils) { + angular.module('ariaNg').controller('Aria2SettingsController', ['$rootScope', '$scope', '$location', '$timeout', 'ariaNgConstants', 'aria2GlobalAvailableOptions', 'aria2RpcService', 'utils', function ($rootScope, $scope, $location, $timeout, ariaNgConstants, aria2GlobalAvailableOptions, aria2RpcService, utils) { var location = $location.path().substring($location.path().lastIndexOf('/') + 1); var pendingSaveRequest = {}; @@ -53,7 +53,7 @@ $scope.optionStatus[key] = 'saving'; return aria2RpcService.changeGlobalOption({ - params: [data], + options: data, callback: function () { $scope.optionStatus[key] = 'saved'; } @@ -75,7 +75,7 @@ } }; - $scope.loadPromise = (function () { + $rootScope.loadPromise = (function () { return aria2RpcService.getGlobalOption({ callback: function (result) { $scope.globalOptions = result; diff --git a/app/scripts/controllers/status.js b/app/scripts/controllers/status.js index 4b4dcc0..c3586d8 100644 --- a/app/scripts/controllers/status.js +++ b/app/scripts/controllers/status.js @@ -1,8 +1,8 @@ (function () { 'use strict'; - angular.module('ariaNg').controller('Aria2StatusController', ['$scope', 'SweetAlert', 'aria2RpcService', 'ariaNgSettingService', function ($scope, SweetAlert, aria2RpcService, ariaNgSettingService) { - $scope.loadPromise = (function () { + angular.module('ariaNg').controller('Aria2StatusController', ['$rootScope', '$scope', 'aria2RpcService', function ($rootScope, $scope, aria2RpcService) { + $rootScope.loadPromise = (function () { return aria2RpcService.getVersion({ callback: function (result) { $scope.serverStatus = result; diff --git a/app/scripts/controllers/task-detail.js b/app/scripts/controllers/task-detail.js index b8bc4da..53f7a3d 100644 --- a/app/scripts/controllers/task-detail.js +++ b/app/scripts/controllers/task-detail.js @@ -13,7 +13,7 @@ var refreshPeers = function (task) { return aria2RpcService.getPeers({ - params: [task.gid], + gid: task.gid, callback: function (result) { if (!utils.extendArray(result, $scope.peers, 'peerId')) { $scope.peers = result; @@ -31,7 +31,7 @@ var refreshDownloadTask = function () { return aria2RpcService.tellStatus({ - params: [$routeParams.gid], + gid: $routeParams.gid, callback: function (result) { var task = utils.processDownloadTask(result); @@ -44,6 +44,10 @@ } $scope.task = utils.copyObjectTo(task, $scope.task); + + $rootScope.taskContext.list = [$scope.task]; + $rootScope.taskContext.selected = {}; + $rootScope.taskContext.selected[$scope.task.gid] = true; } }) }; @@ -71,8 +75,8 @@ }; $scope.loadTaskOption = function (task) { - $scope.loadPromise = aria2RpcService.getOption({ - params: [task.gid], + $rootScope.loadPromise = aria2RpcService.getOption({ + gid: task.gid, callback: function (result) { $scope.options = result; } @@ -101,7 +105,7 @@ return ariaNgSettingService.getFileListDisplayOrder(); }; - $scope.loadPromise = refreshDownloadTask(); + $rootScope.loadPromise = refreshDownloadTask(); if (ariaNgSettingService.getDownloadTaskRefreshInterval() > 0) { downloadTaskRefreshPromise = $interval(function () { diff --git a/app/scripts/core/config.js b/app/scripts/core/config.js index a24f1f7..8605234 100644 --- a/app/scripts/core/config.js +++ b/app/scripts/core/config.js @@ -78,6 +78,23 @@ return result; }, + getSelectedTasks: function () { + var result = []; + + if (!this.list || !this.selected || this.list.length < 1) { + return result; + } + + for (var i = 0; i < this.list.length; i++) { + var task = this.list[i]; + + if (this.selected[task.gid]) { + result.push(task); + } + } + + return result; + }, selectAll: function () { if (!this.list || !this.selected || this.list.length < 1) { return result; @@ -129,7 +146,9 @@ $rootScope.taskContext.list.length = 0; } - console.log($rootScope.taskContext.list); + if (angular.isObject($rootScope.taskContext.selected)) { + $rootScope.taskContext.selected = {}; + } SweetAlert.close(); }); diff --git a/app/scripts/core/lang-default.js b/app/scripts/core/lang-default.js index 75eeb70..e04988b 100644 --- a/app/scripts/core/lang-default.js +++ b/app/scripts/core/lang-default.js @@ -19,6 +19,8 @@ 'Display Order': 'Display Order', 'Search': 'Search', 'Default': 'Default', + 'Remove Task': 'Remove Task', + 'Clear Finished Tasks': 'Clear Finished Tasks', 'By File Name': 'By File Name', 'By File Size': 'By File Size', 'By Completed Percent': 'By Completed Percent', @@ -69,6 +71,10 @@ 'Percent': 'Percent', 'Download / Upload Speed': 'Download / Upload Speed', 'No connected peers': 'No connected peers', + 'Confirm Remove': 'Confirm Remove', + 'Are you sure you want to remove the selected task?': 'Are you sure you want to remove the selected task?', + 'Confirm Clear': 'Confirm Clear', + 'Are you sure you want to clear finished tasks?': 'Are you sure you want to clear finished tasks?', 'Language': 'Language', 'Aria2 RPC Host': 'Aria2 RPC Host', 'Aria2 RPC Port': 'Aria2 RPC Port', diff --git a/app/scripts/core/utils.js b/app/scripts/core/utils.js index 67b49f4..d1c12cb 100644 --- a/app/scripts/core/utils.js +++ b/app/scripts/core/utils.js @@ -27,6 +27,30 @@ }); }, 100); }, + confirm: function (title, text, type, callback) { + var options = { + title: $translate.instant(title), + text: $translate.instant(text), + type: type, + showCancelButton: true, + confirmButtonText: $translate.instant('OK'), + cancelButtonText: $translate.instant('Cancel') + }; + + if (type == 'warning') { + options.confirmButtonColor = '#F39C12'; + } + + SweetAlert.swal(options, function (isConfirm) { + if (!isConfirm) { + return; + } + + if (callback) { + callback(); + } + }); + }, extendArray: function (sourceArray, targetArray, keyProperty) { if (!targetArray || !sourceArray || sourceArray.length != targetArray.length) { return false; diff --git a/app/scripts/services/aria2RpcService.js b/app/scripts/services/aria2RpcService.js index 36e2d86..5690d09 100644 --- a/app/scripts/services/aria2RpcService.js +++ b/app/scripts/services/aria2RpcService.js @@ -1,14 +1,18 @@ (function () { 'use strict'; - angular.module('ariaNg').factory('aria2RpcService', ['aria2RpcConstants', 'ariaNgSettingService', 'aria2HttpRpcService', 'aria2WebSocketRpcService', 'utils', function (aria2RpcConstants, ariaNgSettingService, aria2HttpRpcService, aria2WebSocketRpcService, utils) { + angular.module('ariaNg').factory('aria2RpcService', ['$q', 'aria2RpcConstants', 'ariaNgSettingService', 'aria2HttpRpcService', 'aria2WebSocketRpcService', 'utils', function ($q, aria2RpcConstants, ariaNgSettingService, aria2HttpRpcService, aria2WebSocketRpcService, utils) { var protocol = ariaNgSettingService.getProtocol(); + var getAria2MethodFullName = function (methodName) { + return aria2RpcConstants.rpcServiceName + '.' + methodName; + }; + var invoke = function (method, context) { context.uniqueId = utils.generateUniqueId(); context.requestBody = { jsonrpc: aria2RpcConstants.rpcServiceVersion, - method: aria2RpcConstants.rpcServiceName + '.' + method, + method: (method.indexOf('system.') != 0 ? getAria2MethodFullName(method) : method), id: context.uniqueId, params: context.params }; @@ -20,111 +24,305 @@ } }; + var invokeMulti = function (methodFunc, contexts, keyProperty, callback) { + var promises = []; + var results = {}; + + for (var i = 0; i < contexts.length; i++) { + contexts[i].callback = function (result) { + var key = this[keyProperty]; + results[key] = result; + }; + + promises.push(methodFunc(contexts[i])); + } + + return $q.all(promises).then(function () { + if (callback) { + callback(results); + } + }); + }; + return { - addUri: function (context) { - return invoke('addUri', context); + getBasicTaskParams: function () { + return [ + 'gid', + 'totalLength', + 'completedLength', + 'uploadSpeed', + 'downloadSpeed', + 'connections', + 'numSeeders', + 'seeder', + 'status' + ]; }, - addTorrent: function (context) { - return invoke('addTorrent', context); - }, - addMetalink: function (context) { - return invoke('addMetalink', context); + getFullTaskParams: function () { + var requestParams = this.getBasicTaskParams(); + + requestParams.push('files'); + requestParams.push('bittorrent'); + + return requestParams; }, + // addUri: function (context) { + // return invoke('addUri', context); + // }, + // addTorrent: function (context) { + // return invoke('addTorrent', context); + // }, + // addMetalink: function (context) { + // return invoke('addMetalink', context); + // }, remove: function (context) { - return invoke('remove', context); + return invoke('remove', { + params: [context.gid], + callback: context.callback + }); }, forceRemove: function (context) { - return invoke('forceRemove', context); + return invoke('forceRemove', { + params: [context.gid], + callback: context.callback + }); + }, + forceRemoveMulti: function (context) { + var contexts = []; + + for (var i = 0; i < context.gids.length; i++) { + contexts.push({ + gid: context.gids[i] + }); + } + + return invokeMulti(this.forceRemove, contexts, 'gid', context.callback); }, pause: function (context) { - return invoke('pause', context); + return invoke('pause', { + params: [context.gid], + callback: context.callback + }); }, pauseAll: function (context) { - return invoke('pauseAll', context); + return invoke('pauseAll', { + callback: context.callback + }); }, forcePause: function (context) { - return invoke('forcePause', context); + return invoke('forcePause', { + params: [context.gid], + callback: context.callback + }); + }, + forcePauseMulti: function (context) { + var contexts = []; + + for (var i = 0; i < context.gids.length; i++) { + contexts.push({ + gid: context.gids[i] + }); + } + + return invokeMulti(this.forcePause, contexts, 'gid', context.callback); }, forcePauseAll: function (context) { - return invoke('forcePauseAll', context); + return invoke('forcePauseAll', { + callback: context.callback + }); }, unpause: function (context) { - return invoke('unpause', context); + return invoke('unpause', { + params: [context.gid], + callback: context.callback + }); + }, + unpauseMulti: function (context) { + var contexts = []; + + for (var i = 0; i < context.gids.length; i++) { + contexts.push({ + gid: context.gids[i] + }); + } + + return invokeMulti(this.unpause, contexts, 'gid', context.callback); }, unpauseAll: function (context) { - return invoke('unpauseAll', context); + return invoke('unpauseAll', { + callback: context.callback + }); }, tellStatus: function (context) { - return invoke('tellStatus', context); + return invoke('tellStatus', { + params: [context.gid], + callback: context.callback + }); }, getUris: function (context) { - return invoke('getUris', context); + return invoke('getUris', { + params: [context.gid], + callback: context.callback + }); }, getFiles: function (context) { - return invoke('getFiles', context); + return invoke('getFiles', { + params: [context.gid], + callback: context.callback + }); }, getPeers: function (context) { - return invoke('getPeers', context); + return invoke('getPeers', { + params: [context.gid], + callback: context.callback + }); }, getServers: function (context) { - return invoke('getServers', context); + return invoke('getServers', { + params: [context.gid], + callback: context.callback + }); }, tellActive: function (context) { - return invoke('tellActive', context); + var requestContext = { + callback: context.callback + }; + + if (context.requestParams) { + requestContext.params = [context.requestParams]; + } + + return invoke('tellActive', requestContext); }, tellWaiting: function (context) { - return invoke('tellWaiting', context); + var requestContext = { + params: [0, 1000], + callback: context.callback + }; + + if (!angular.isUndefined(context.offset)) { + requestContext.params[0] = context.offset; + } + + if (!angular.isUndefined(context.num)) { + requestContext.params[1] = context.num; + } + + if (context.requestParams) { + requestContext.params.push(context.requestParams); + } + + return invoke('tellWaiting', requestContext); }, tellStopped: function (context) { - return invoke('tellStopped', context); - }, - changePosition: function (context) { - return invoke('changePosition', context); - }, - changeUri: function (context) { - return invoke('changeUri', context); + var requestContext = { + params: [0, 1000], + callback: context.callback + }; + + if (!angular.isUndefined(context.offset)) { + requestContext.params[0] = context.offset; + } + + if (!angular.isUndefined(context.num)) { + requestContext.params[1] = context.num; + } + + if (context.requestParams) { + requestContext.params.push(context.requestParams); + } + + return invoke('tellStopped', requestContext); }, + // changePosition: function (context) { + // return invoke('changePosition', context); + // }, + // changeUri: function (context) { + // return invoke('changeUri', context); + // }, getOption: function (context) { - return invoke('getOption', context); + return invoke('getOption', { + params: [context.gid], + callback: context.callback + }); }, changeOption: function (context) { - return invoke('changeOption', context); + return invoke('changeOption', { + params: [context.gid, context.options], + callback: context.callback + }); }, getGlobalOption: function (context) { - return invoke('getGlobalOption', context); + return invoke('getGlobalOption', { + callback: context.callback + }); }, changeGlobalOption: function (context) { - return invoke('changeGlobalOption', context); + return invoke('changeGlobalOption', { + params: [context.options], + callback: context.callback + }); }, getGlobalStat: function (context) { - return invoke('getGlobalStat', context); + return invoke('getGlobalStat', { + callback: context.callback + }); }, purgeDownloadResult: function (context) { - return invoke('purgeDownloadResult', context); + return invoke('purgeDownloadResult', { + callback: context.callback + }); }, removeDownloadResult: function (context) { - return invoke('removeDownloadResult', context); + return invoke('removeDownloadResult', { + params: [context.gid], + callback: context.callback + }); }, getVersion: function (context) { - return invoke('getVersion', context); + return invoke('getVersion', { + callback: context.callback + }); }, getSessionInfo: function (context) { - return invoke('getSessionInfo', context); + return invoke('getSessionInfo', { + callback: context.callback + }); }, shutdown: function (context) { - return invoke('shutdown', context); + return invoke('shutdown', { + callback: context.callback + }); }, forceShutdown: function (context) { - return invoke('forceShutdown', context); + return invoke('forceShutdown', { + callback: context.callback + }); }, saveSession: function (context) { - return invoke('saveSession', context); + return invoke('saveSession', { + callback: context.callback + }); }, multicall: function (context) { - return invoke('multicall', context); + var requestContext = { + params: [], + callback: context.callback + }; + + if (angular.isArray(context.methods) && context.methods.length > 0) { + for (var i = 0; i < context.methods.length; i++) { + var method = context.methods[i]; + requestContext.params.push([method]); + } + } + + return invoke('system.multicall', requestContext); }, listMethods: function (context) { - return invoke('listMethods', context); + return invoke('system.listMethods', { + callback: context.callback + }); } }; }]);