refactor code
This commit is contained in:
parent
a6ea0c9629
commit
26e25830e8
|
@ -44,13 +44,13 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li ng-class="{'disabled': !isStartableTaskSelected()}">
|
<li ng-class="{'disabled': !isSpecifiedTaskSelected('paused')}">
|
||||||
<a class="toolbar" title="{{'Start' | translate}}" ng-click="startTask()">
|
<a class="toolbar" title="{{'Start' | translate}}" ng-click="changeTasksState('start')">
|
||||||
<i class="fa fa-play"></i>
|
<i class="fa fa-play"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li ng-class="{'disabled': !isPausableTaskSelected()}">
|
<li ng-class="{'disabled': !isSpecifiedTaskSelected('active')}">
|
||||||
<a class="toolbar" title="{{'Pause' | translate}}" ng-click="pauseTask()">
|
<a class="toolbar" title="{{'Pause' | translate}}" ng-click="changeTasksState('pause')">
|
||||||
<i class="fa fa-pause"></i>
|
<i class="fa fa-pause"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li ng-if="isTaskSelected()">
|
<li ng-if="isTaskSelected()">
|
||||||
<a class="pointer-cursor" ng-click="removeTask()">
|
<a class="pointer-cursor" ng-click="removeTasks()">
|
||||||
<span translate>Remove Task</span>
|
<span translate>Remove Task</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li ng-class="{'disabled': !taskContext.list || taskContext.list.length < 1}">
|
<li ng-class="{'disabled': !taskContext.enableSelectAll || !taskContext.list || taskContext.list.length < 1}">
|
||||||
<a class="toolbar" title="{{'Select All' | translate}}" ng-click="selectAllTasks()">
|
<a class="toolbar" title="{{'Select All' | translate}}" ng-click="selectAllTasks()">
|
||||||
<i class="fa fa-th-large"></i>
|
<i class="fa fa-th-large"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -259,31 +259,34 @@
|
||||||
<script src="scripts/core/__core.js"></script>
|
<script src="scripts/core/__core.js"></script>
|
||||||
<script src="scripts/core/__fix.js"></script>
|
<script src="scripts/core/__fix.js"></script>
|
||||||
<script src="scripts/core/app.js"></script>
|
<script src="scripts/core/app.js"></script>
|
||||||
<script src="scripts/core/aria2options.js"></script>
|
|
||||||
<script src="scripts/core/config.js"></script>
|
|
||||||
<script src="scripts/core/constants.js"></script>
|
|
||||||
<script src="scripts/core/lang-confs.js"></script>
|
|
||||||
<script src="scripts/core/lang-default.js"></script>
|
|
||||||
<script src="scripts/core/router.js"></script>
|
<script src="scripts/core/router.js"></script>
|
||||||
<script src="scripts/core/utils.js"></script>
|
<script src="scripts/core/root.js"></script>
|
||||||
<script src="scripts/controllers/list.js"></script>
|
<script src="scripts/config/constants.js"></script>
|
||||||
|
<script src="scripts/config/configuration.js"></script>
|
||||||
|
<script src="scripts/config/initiator.js"></script>
|
||||||
|
<script src="scripts/config/languages.js"></script>
|
||||||
|
<script src="scripts/config/language-default.js"></script>
|
||||||
|
<script src="scripts/config/aria2options.js"></script>
|
||||||
<script src="scripts/controllers/main.js"></script>
|
<script src="scripts/controllers/main.js"></script>
|
||||||
<script src="scripts/controllers/settings-aria2.js"></script>
|
<script src="scripts/controllers/list.js"></script>
|
||||||
<script src="scripts/controllers/settings-ariang.js"></script>
|
|
||||||
<script src="scripts/controllers/status.js"></script>
|
|
||||||
<script src="scripts/controllers/task-detail.js"></script>
|
<script src="scripts/controllers/task-detail.js"></script>
|
||||||
|
<script src="scripts/controllers/settings-ariang.js"></script>
|
||||||
|
<script src="scripts/controllers/settings-aria2.js"></script>
|
||||||
|
<script src="scripts/controllers/status.js"></script>
|
||||||
<script src="scripts/directives/placeholder.js"></script>
|
<script src="scripts/directives/placeholder.js"></script>
|
||||||
<script src="scripts/filters/dateDuration.js"></script>
|
<script src="scripts/filters/dateDuration.js"></script>
|
||||||
<script src="scripts/filters/filename.js"></script>
|
|
||||||
<script src="scripts/filters/fileOrderBy.js"></script>
|
<script src="scripts/filters/fileOrderBy.js"></script>
|
||||||
<script src="scripts/filters/percent.js"></script>
|
<script src="scripts/filters/percent.js"></script>
|
||||||
<script src="scripts/filters/taskOrderBy.js"></script>
|
<script src="scripts/filters/taskOrderBy.js"></script>
|
||||||
<script src="scripts/filters/taskStatus.js"></script>
|
<script src="scripts/filters/taskStatus.js"></script>
|
||||||
<script src="scripts/filters/volumn.js"></script>
|
<script src="scripts/filters/volumn.js"></script>
|
||||||
<script src="scripts/services/aria2HttpRpcService.js"></script>
|
<script src="scripts/services/ariaNgCommonService.js"></script>
|
||||||
<script src="scripts/services/aria2RpcService.js"></script>
|
|
||||||
<script src="scripts/services/aria2WebSocketRpcService.js"></script>
|
|
||||||
<script src="scripts/services/ariaNgSettingService.js"></script>
|
<script src="scripts/services/ariaNgSettingService.js"></script>
|
||||||
|
<script src="scripts/services/ariaNgTaskService.js"></script>
|
||||||
|
<script src="scripts/services/aria2SettingService.js"></script>
|
||||||
|
<script src="scripts/services/aria2RpcService.js"></script>
|
||||||
|
<script src="scripts/services/aria2HttpRpcService.js"></script>
|
||||||
|
<script src="scripts/services/aria2WebSocketRpcService.js"></script>
|
||||||
<!-- endbuild -->
|
<!-- endbuild -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
18
app/scripts/config/configuration.js
Normal file
18
app/scripts/config/configuration.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ariaNg').config(['$translateProvider', 'localStorageServiceProvider', 'ariaNgConstants', function ($translateProvider, localStorageServiceProvider, ariaNgConstants) {
|
||||||
|
localStorageServiceProvider
|
||||||
|
.setPrefix(ariaNgConstants.appPrefix)
|
||||||
|
.setStorageType('localStorage')
|
||||||
|
.setStorageCookie(365, '/');
|
||||||
|
|
||||||
|
$translateProvider.useStaticFilesLoader({
|
||||||
|
prefix: 'langs/',
|
||||||
|
suffix: '.json'
|
||||||
|
}).useLoaderCache(true)
|
||||||
|
.preferredLanguage('en-US')
|
||||||
|
.fallbackLanguage('en-US')
|
||||||
|
.useSanitizeValueStrategy('escape');
|
||||||
|
}]);
|
||||||
|
})();
|
|
@ -15,6 +15,7 @@
|
||||||
downloadTaskRefreshInterval: 1000
|
downloadTaskRefreshInterval: 1000
|
||||||
}).constant('aria2RpcConstants', {
|
}).constant('aria2RpcConstants', {
|
||||||
rpcServiceVersion: '2.0',
|
rpcServiceVersion: '2.0',
|
||||||
rpcServiceName: 'aria2'
|
rpcServiceName: 'aria2',
|
||||||
|
rpcSystemServiceName: 'system'
|
||||||
});
|
});
|
||||||
})();
|
})();
|
14
app/scripts/config/initiator.js
Normal file
14
app/scripts/config/initiator.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ariaNg').run(['amMoment', 'moment', 'ariaNgSettingService', function (amMoment, moment, ariaNgSettingService) {
|
||||||
|
var language = ariaNgSettingService.getLanguage();
|
||||||
|
|
||||||
|
moment.updateLocale('zh-cn', {
|
||||||
|
week: null
|
||||||
|
});
|
||||||
|
|
||||||
|
amMoment.changeLocale(language);
|
||||||
|
ariaNgSettingService.applyLanguage(language);
|
||||||
|
}]);
|
||||||
|
})();
|
|
@ -1,48 +1,30 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').controller('DownloadListController', ['$rootScope', '$scope', '$window', '$location', '$interval', 'aria2RpcService', 'ariaNgSettingService', 'utils', function ($rootScope, $scope, $window, $location, $interval, aria2RpcService, ariaNgSettingService, utils) {
|
angular.module('ariaNg').controller('DownloadListController', ['$rootScope', '$scope', '$window', '$location', '$interval', 'ariaNgCommonService', 'ariaNgSettingService', 'ariaNgTaskService', function ($rootScope, $scope, $window, $location, $interval, ariaNgCommonService, ariaNgSettingService, ariaNgTaskService) {
|
||||||
var location = $location.path().substring(1);
|
var location = $location.path().substring(1);
|
||||||
var downloadTaskRefreshPromise = null;
|
var downloadTaskRefreshPromise = null;
|
||||||
var needRequestWholeInfo = true;
|
var needRequestWholeInfo = true;
|
||||||
|
|
||||||
var refreshDownloadTask = function () {
|
var refreshDownloadTask = function () {
|
||||||
var invokeMethod = null;
|
return ariaNgTaskService.getTaskList(location, needRequestWholeInfo, function (result) {
|
||||||
|
if (!ariaNgCommonService.extendArray(result, $rootScope.taskContext.list, 'gid')) {
|
||||||
if (location == 'downloading') {
|
if (needRequestWholeInfo) {
|
||||||
invokeMethod = aria2RpcService.tellActive;
|
$rootScope.taskContext.list = result;
|
||||||
} else if (location == 'waiting') {
|
needRequestWholeInfo = false;
|
||||||
invokeMethod = aria2RpcService.tellWaiting;
|
} else {
|
||||||
} else if (location == 'stopped') {
|
needRequestWholeInfo = true;
|
||||||
invokeMethod = aria2RpcService.tellStopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (invokeMethod) {
|
|
||||||
return invokeMethod({
|
|
||||||
requestParams: needRequestWholeInfo ? aria2RpcService.getFullTaskParams() : aria2RpcService.getBasicTaskParams(),
|
|
||||||
callback: function (result) {
|
|
||||||
if (!utils.extendArray(result, $rootScope.taskContext.list, 'gid')) {
|
|
||||||
if (needRequestWholeInfo) {
|
|
||||||
$rootScope.taskContext.list = result;
|
|
||||||
needRequestWholeInfo = false;
|
|
||||||
} else {
|
|
||||||
needRequestWholeInfo = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
needRequestWholeInfo = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rootScope.taskContext.list && $rootScope.taskContext.list.length > 0) {
|
|
||||||
for (var i = 0; i < $rootScope.taskContext.list.length; i++) {
|
|
||||||
utils.processDownloadTask($rootScope.taskContext.list[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
}
|
needRequestWholeInfo = false;
|
||||||
};
|
}
|
||||||
|
|
||||||
$rootScope.loadPromise = refreshDownloadTask();
|
if ($rootScope.taskContext.list) {
|
||||||
|
ariaNgTaskService.processDownloadTasks($rootScope.taskContext.list);
|
||||||
|
$rootScope.taskContext.enableSelectAll = $rootScope.taskContext.list.length > 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
$scope.filterByTaskName = function (task) {
|
$scope.filterByTaskName = function (task) {
|
||||||
if (!task || !angular.isString(task.taskName)) {
|
if (!task || !angular.isString(task.taskName)) {
|
||||||
|
@ -71,5 +53,7 @@
|
||||||
$interval.cancel(downloadTaskRefreshPromise);
|
$interval.cancel(downloadTaskRefreshPromise);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$rootScope.loadPromise = refreshDownloadTask();
|
||||||
}]);
|
}]);
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,76 +1,12 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').controller('MainController', ['$rootScope', '$scope', '$route', '$interval', 'aria2RpcService', 'ariaNgSettingService', 'utils', function ($rootScope, $scope, $route, $interval, aria2RpcService, ariaNgSettingService, utils) {
|
angular.module('ariaNg').controller('MainController', ['$rootScope', '$scope', '$route', '$interval', 'aria2SettingService', 'ariaNgCommonService', 'ariaNgTaskService', 'ariaNgSettingService', function ($rootScope, $scope, $route, $interval, aria2SettingService, ariaNgCommonService, ariaNgTaskService, ariaNgSettingService) {
|
||||||
var globalStatRefreshPromise = null;
|
var globalStatRefreshPromise = null;
|
||||||
|
|
||||||
var processStatResult = function (stat) {
|
|
||||||
var activeCount = parseInt(stat.numActive);
|
|
||||||
var waitingCount = parseInt(stat.numWaiting);
|
|
||||||
var totalRunningCount = activeCount + waitingCount;
|
|
||||||
|
|
||||||
stat.totalRunningCount = totalRunningCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
var refreshGlobalStat = function () {
|
var refreshGlobalStat = function () {
|
||||||
aria2RpcService.getGlobalStat({
|
return aria2SettingService.getGlobalStat(function (result) {
|
||||||
callback: function (result) {
|
$scope.globalStat = result;
|
||||||
if (result) {
|
|
||||||
processStatResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.globalStat = result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
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 () {
|
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -78,7 +14,7 @@
|
||||||
return $rootScope.taskContext.getSelectedTaskIds().length > 0;
|
return $rootScope.taskContext.getSelectedTaskIds().length > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.isStartableTaskSelected = function () {
|
$scope.isSpecifiedTaskSelected = function (status) {
|
||||||
var selectedTasks = $rootScope.taskContext.getSelectedTasks();
|
var selectedTasks = $rootScope.taskContext.getSelectedTasks();
|
||||||
|
|
||||||
if (selectedTasks.length < 1) {
|
if (selectedTasks.length < 1) {
|
||||||
|
@ -86,7 +22,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < selectedTasks.length; i++) {
|
for (var i = 0; i < selectedTasks.length; i++) {
|
||||||
if (selectedTasks[i].status == 'paused') {
|
if (selectedTasks[i].status == status) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,20 +30,44 @@
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.isPausableTaskSelected = function () {
|
$scope.changeTasksState = function (state) {
|
||||||
var selectedTasks = $rootScope.taskContext.getSelectedTasks();
|
var gids = $rootScope.taskContext.getSelectedTaskIds();
|
||||||
|
|
||||||
if (selectedTasks.length < 1) {
|
if (!gids || gids.length < 1) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < selectedTasks.length; i++) {
|
var invoke = null;
|
||||||
if (selectedTasks[i].status == 'active') {
|
|
||||||
return true;
|
if (state == 'start') {
|
||||||
}
|
invoke = ariaNgTaskService.startTasks;
|
||||||
|
} else if (state == 'pause') {
|
||||||
|
invoke = ariaNgTaskService.pauseTasks;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
$rootScope.loadPromise = invoke(gids, function (result) {
|
||||||
|
$route.reload();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.removeTasks = function () {
|
||||||
|
var gids = $rootScope.taskContext.getSelectedTaskIds();
|
||||||
|
|
||||||
|
if (!gids || gids.length < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ariaNgCommonService.confirm('Confirm Remove', 'Are you sure you want to remove the selected task?', 'warning', function () {
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.clearFinishedTasks = function () {
|
||||||
|
ariaNgCommonService.confirm('Confirm Clear', 'Are you sure you want to clear finished tasks?', 'warning', function () {
|
||||||
|
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.selectAllTasks = function () {
|
$scope.selectAllTasks = function () {
|
||||||
|
@ -115,8 +75,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.changeDisplayOrder = function (type, autoSetReverse) {
|
$scope.changeDisplayOrder = function (type, autoSetReverse) {
|
||||||
var oldType = utils.parseOrderType(ariaNgSettingService.getDisplayOrder());
|
var oldType = ariaNgCommonService.parseOrderType(ariaNgSettingService.getDisplayOrder());
|
||||||
var newType = utils.parseOrderType(type);
|
var newType = ariaNgCommonService.parseOrderType(type);
|
||||||
|
|
||||||
if (autoSetReverse && newType.type == oldType.type) {
|
if (autoSetReverse && newType.type == oldType.type) {
|
||||||
newType.reverse = !oldType.reverse;
|
newType.reverse = !oldType.reverse;
|
||||||
|
@ -126,8 +86,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.isSetDisplayOrder = function (type) {
|
$scope.isSetDisplayOrder = function (type) {
|
||||||
var orderType = utils.parseOrderType(ariaNgSettingService.getDisplayOrder());
|
var orderType = ariaNgCommonService.parseOrderType(ariaNgSettingService.getDisplayOrder());
|
||||||
var targetType = utils.parseOrderType(type);
|
var targetType = ariaNgCommonService.parseOrderType(type);
|
||||||
|
|
||||||
return orderType.equals(targetType);
|
return orderType.equals(targetType);
|
||||||
};
|
};
|
||||||
|
@ -143,5 +103,7 @@
|
||||||
$interval.cancel(globalStatRefreshPromise);
|
$interval.cancel(globalStatRefreshPromise);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
refreshGlobalStat();
|
||||||
}]);
|
}]);
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,45 +1,24 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').controller('Aria2SettingsController', ['$rootScope', '$scope', '$location', '$timeout', 'ariaNgConstants', 'aria2GlobalAvailableOptions', 'aria2RpcService', 'utils', function ($rootScope, $scope, $location, $timeout, ariaNgConstants, aria2GlobalAvailableOptions, aria2RpcService, utils) {
|
angular.module('ariaNg').controller('Aria2SettingsController', ['$rootScope', '$scope', '$location', '$timeout', 'ariaNgConstants', 'ariaNgCommonService', 'aria2SettingService', function ($rootScope, $scope, $location, $timeout, ariaNgConstants, ariaNgCommonService, aria2SettingService) {
|
||||||
var location = $location.path().substring($location.path().lastIndexOf('/') + 1);
|
var location = $location.path().substring($location.path().lastIndexOf('/') + 1);
|
||||||
var pendingSaveRequest = {};
|
var pendingSaveRequests = {};
|
||||||
|
|
||||||
var getAvailableOptionsKeys = function (location) {
|
var getAvailableOptions = function (type) {
|
||||||
if (location == 'basic') {
|
var keys = aria2SettingService.getAvailableOptionsKeys(type);
|
||||||
return aria2GlobalAvailableOptions.basicOptions;
|
|
||||||
} else if (location == 'http-ftp-sftp') {
|
|
||||||
return aria2GlobalAvailableOptions.httpFtpSFtpOptions;
|
|
||||||
} else if (location == 'http') {
|
|
||||||
return aria2GlobalAvailableOptions.httpOptions;
|
|
||||||
} else if (location == 'ftp-sftp') {
|
|
||||||
return aria2GlobalAvailableOptions.ftpSFtpOptions;
|
|
||||||
} else if (location == 'bt') {
|
|
||||||
return aria2GlobalAvailableOptions.btOptions;
|
|
||||||
} else if (location == 'metalink') {
|
|
||||||
return aria2GlobalAvailableOptions.metalinkOptions;
|
|
||||||
} else if (location == 'rpc') {
|
|
||||||
return aria2GlobalAvailableOptions.rpcOptions;
|
|
||||||
} else if (location == 'advanced') {
|
|
||||||
return aria2GlobalAvailableOptions.advancedOptions;
|
|
||||||
} else {
|
|
||||||
utils.alert('Type is illegal!');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var getAvailableOptions = function (location) {
|
|
||||||
var keys = getAvailableOptionsKeys(location);
|
|
||||||
|
|
||||||
if (!keys) {
|
if (!keys) {
|
||||||
|
ariaNgCommonService.alert('Type is illegal!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.getOptions(keys);
|
return aria2SettingService.getSpecifiedOptions(keys);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.optionStatus = {};
|
$scope.optionStatus = {};
|
||||||
$scope.availableOptions = getAvailableOptions(location);
|
$scope.availableOptions = getAvailableOptions(location);
|
||||||
|
|
||||||
$scope.setGlobalOption = function (option, value, lazySave) {
|
$scope.setGlobalOption = function (option, value, lazySave) {
|
||||||
if (!option || !option.key || option.readonly) {
|
if (!option || !option.key || option.readonly) {
|
||||||
return;
|
return;
|
||||||
|
@ -47,27 +26,21 @@
|
||||||
|
|
||||||
var key = option.key;
|
var key = option.key;
|
||||||
var invoke = function () {
|
var invoke = function () {
|
||||||
var data = {};
|
|
||||||
data[key] = value;
|
|
||||||
|
|
||||||
$scope.optionStatus[key] = 'saving';
|
$scope.optionStatus[key] = 'saving';
|
||||||
|
|
||||||
return aria2RpcService.changeGlobalOption({
|
return aria2SettingService.setGlobalOption(key, value, function (result) {
|
||||||
options: data,
|
$scope.optionStatus[key] = 'saved';
|
||||||
callback: function () {
|
|
||||||
$scope.optionStatus[key] = 'saved';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
delete $scope.optionStatus[key];
|
delete $scope.optionStatus[key];
|
||||||
|
|
||||||
if (lazySave) {
|
if (lazySave) {
|
||||||
if (pendingSaveRequest[key]) {
|
if (pendingSaveRequests[key]) {
|
||||||
$timeout.cancel(pendingSaveRequest[key]);
|
$timeout.cancel(pendingSaveRequests[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingSaveRequest[key] = $timeout(function () {
|
pendingSaveRequests[key] = $timeout(function () {
|
||||||
invoke();
|
invoke();
|
||||||
}, ariaNgConstants.lazySaveTimeout);
|
}, ariaNgConstants.lazySaveTimeout);
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,10 +49,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$rootScope.loadPromise = (function () {
|
$rootScope.loadPromise = (function () {
|
||||||
return aria2RpcService.getGlobalOption({
|
return aria2SettingService.getGlobalOption(function (result) {
|
||||||
callback: function (result) {
|
$scope.globalOptions = result;
|
||||||
$scope.globalOptions = result;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').controller('Aria2StatusController', ['$rootScope', '$scope', 'aria2RpcService', function ($rootScope, $scope, aria2RpcService) {
|
angular.module('ariaNg').controller('Aria2StatusController', ['$rootScope', '$scope', 'aria2SettingService', function ($rootScope, $scope, aria2SettingService) {
|
||||||
$rootScope.loadPromise = (function () {
|
$rootScope.loadPromise = (function () {
|
||||||
return aria2RpcService.getVersion({
|
return aria2SettingService.getServerStatus(function (result) {
|
||||||
callback: function (result) {
|
$scope.serverStatus = result;
|
||||||
$scope.serverStatus = result;
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
})();
|
})();
|
||||||
}]);
|
}]);
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').controller('TaskDetailController', ['$rootScope', '$scope', '$routeParams', '$interval', 'aria2RpcService', 'ariaNgSettingService', 'utils', function ($rootScope, $scope, $routeParams, $interval, aria2RpcService, ariaNgSettingService, utils) {
|
angular.module('ariaNg').controller('TaskDetailController', ['$rootScope', '$scope', '$routeParams', '$interval', 'ariaNgCommonService', 'ariaNgSettingService', 'ariaNgTaskService', function ($rootScope, $scope, $routeParams, $interval, ariaNgCommonService, ariaNgSettingService, ariaNgTaskService) {
|
||||||
var tabOrders = ['overview', 'blocks', 'filelist', 'btpeers'];
|
var tabOrders = ['overview', 'blocks', 'filelist', 'btpeers'];
|
||||||
var downloadTaskRefreshPromise = null;
|
var downloadTaskRefreshPromise = null;
|
||||||
|
|
||||||
|
@ -11,45 +11,32 @@
|
||||||
|
|
||||||
$scope.healthPercent = 0;
|
$scope.healthPercent = 0;
|
||||||
|
|
||||||
var refreshPeers = function (task) {
|
var refreshBtPeers = function (task) {
|
||||||
return aria2RpcService.getPeers({
|
return ariaNgTaskService.getBtTaskPeers(task.gid, function (result) {
|
||||||
gid: task.gid,
|
if (!ariaNgCommonService.extendArray(result, $scope.peers, 'peerId')) {
|
||||||
callback: function (result) {
|
$scope.peers = result;
|
||||||
if (!utils.extendArray(result, $scope.peers, 'peerId')) {
|
|
||||||
$scope.peers = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < $scope.peers.length; i++) {
|
|
||||||
var peer = $scope.peers[i];
|
|
||||||
peer.completePercent = utils.estimateCompletedPercentFromBitField(peer.bitfield) * 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.healthPercent = utils.estimateHealthPercentFromPeers(task, $scope.peers);
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
$scope.healthPercent = ariaNgTaskService.estimateHealthPercentFromPeers(task, $scope.peers);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var refreshDownloadTask = function () {
|
var refreshDownloadTask = function () {
|
||||||
return aria2RpcService.tellStatus({
|
return ariaNgTaskService.getTaskStatus($routeParams.gid, function (result) {
|
||||||
gid: $routeParams.gid,
|
if (result.status == 'active' && result.bittorrent) {
|
||||||
callback: function (result) {
|
refreshBtPeers(result);
|
||||||
var task = utils.processDownloadTask(result);
|
} else {
|
||||||
|
if (tabOrders.indexOf('btpeers') >= 0) {
|
||||||
if (task.status == 'active' && task.bittorrent) {
|
tabOrders.splice(tabOrders.indexOf('btpeers'), 1);
|
||||||
refreshPeers(task);
|
|
||||||
} else {
|
|
||||||
if (tabOrders.indexOf('btpeers') >= 0) {
|
|
||||||
tabOrders.splice(tabOrders.indexOf('btpeers'), 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.task = utils.copyObjectTo(task, $scope.task);
|
|
||||||
|
|
||||||
$rootScope.taskContext.list = [$scope.task];
|
|
||||||
$rootScope.taskContext.selected = {};
|
|
||||||
$rootScope.taskContext.selected[$scope.task.gid] = true;
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
$scope.task = ariaNgCommonService.copyObjectTo(result, $scope.task);
|
||||||
|
|
||||||
|
$rootScope.taskContext.list = [$scope.task];
|
||||||
|
$rootScope.taskContext.selected = {};
|
||||||
|
$rootScope.taskContext.selected[$scope.task.gid] = true;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$rootScope.swipeActions.extentLeftSwipe = function () {
|
$rootScope.swipeActions.extentLeftSwipe = function () {
|
||||||
|
@ -75,17 +62,14 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.loadTaskOption = function (task) {
|
$scope.loadTaskOption = function (task) {
|
||||||
$rootScope.loadPromise = aria2RpcService.getOption({
|
$rootScope.loadPromise = ariaNgTaskService.getTaskOption(task.gid, function (result) {
|
||||||
gid: task.gid,
|
$scope.options = result;
|
||||||
callback: function (result) {
|
|
||||||
$scope.options = result;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.changeFileListDisplayOrder = function (type, autoSetReverse) {
|
$scope.changeFileListDisplayOrder = function (type, autoSetReverse) {
|
||||||
var oldType = utils.parseOrderType(ariaNgSettingService.getFileListDisplayOrder());
|
var oldType = ariaNgCommonService.parseOrderType(ariaNgSettingService.getFileListDisplayOrder());
|
||||||
var newType = utils.parseOrderType(type);
|
var newType = ariaNgCommonService.parseOrderType(type);
|
||||||
|
|
||||||
if (autoSetReverse && newType.type == oldType.type) {
|
if (autoSetReverse && newType.type == oldType.type) {
|
||||||
newType.reverse = !oldType.reverse;
|
newType.reverse = !oldType.reverse;
|
||||||
|
@ -95,8 +79,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.isSetFileListDisplayOrder = function (type) {
|
$scope.isSetFileListDisplayOrder = function (type) {
|
||||||
var orderType = utils.parseOrderType(ariaNgSettingService.getFileListDisplayOrder());
|
var orderType = ariaNgCommonService.parseOrderType(ariaNgSettingService.getFileListDisplayOrder());
|
||||||
var targetType = utils.parseOrderType(type);
|
var targetType = ariaNgCommonService.parseOrderType(type);
|
||||||
|
|
||||||
return orderType.equals(targetType);
|
return orderType.equals(targetType);
|
||||||
};
|
};
|
||||||
|
@ -105,8 +89,6 @@
|
||||||
return ariaNgSettingService.getFileListDisplayOrder();
|
return ariaNgSettingService.getFileListDisplayOrder();
|
||||||
};
|
};
|
||||||
|
|
||||||
$rootScope.loadPromise = refreshDownloadTask();
|
|
||||||
|
|
||||||
if (ariaNgSettingService.getDownloadTaskRefreshInterval() > 0) {
|
if (ariaNgSettingService.getDownloadTaskRefreshInterval() > 0) {
|
||||||
downloadTaskRefreshPromise = $interval(function () {
|
downloadTaskRefreshPromise = $interval(function () {
|
||||||
refreshDownloadTask();
|
refreshDownloadTask();
|
||||||
|
@ -118,5 +100,7 @@
|
||||||
$interval.cancel(downloadTaskRefreshPromise);
|
$interval.cancel(downloadTaskRefreshPromise);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$rootScope.loadPromise = refreshDownloadTask();
|
||||||
}]);
|
}]);
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,34 +1,33 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').config(['$translateProvider', 'localStorageServiceProvider', 'ariaNgConstants', function ($translateProvider, localStorageServiceProvider, ariaNgConstants) {
|
angular.module('ariaNg').run(['$rootScope', '$location', '$document', 'SweetAlert', function ($rootScope, $location, $document, SweetAlert) {
|
||||||
localStorageServiceProvider
|
var isUrlMatchUrl2 = function (url, url2) {
|
||||||
.setPrefix(ariaNgConstants.appPrefix)
|
if (url === url2) {
|
||||||
.setStorageType('localStorage')
|
return true;
|
||||||
.setStorageCookie(365, '/');
|
}
|
||||||
|
|
||||||
$translateProvider.useStaticFilesLoader({
|
var index = url2.indexOf(url);
|
||||||
prefix: 'langs/',
|
|
||||||
suffix: '.json'
|
|
||||||
}).useLoaderCache(true)
|
|
||||||
.preferredLanguage('en-US')
|
|
||||||
.fallbackLanguage('en-US')
|
|
||||||
.useSanitizeValueStrategy('escape');
|
|
||||||
}]).run(['$translate', 'amMoment', 'moment', 'ariaNgConstants', 'ariaNgSettingService', function ($translate, amMoment, moment, ariaNgConstants, ariaNgSettingService) {
|
|
||||||
ariaNgSettingService.applyLanguage(ariaNgSettingService.getLanguage());
|
|
||||||
|
|
||||||
moment.updateLocale('zh-cn', {
|
if (index !== 0) {
|
||||||
week: null
|
return false;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
var lastPart = url2.substring(url.length);
|
||||||
|
|
||||||
|
if (lastPart.indexOf('/') == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
amMoment.changeLocale(ariaNgSettingService.getLanguage());
|
|
||||||
}]).run(['$rootScope', '$location', '$document', 'SweetAlert', 'ariaNgConstants', 'utils', function ($rootScope, $location, $document, SweetAlert, ariaNgConstants, utils) {
|
|
||||||
var setNavbarSelected = function (location) {
|
var setNavbarSelected = function (location) {
|
||||||
angular.element('section.sidebar > ul li').removeClass('active');
|
angular.element('section.sidebar > ul li').removeClass('active');
|
||||||
angular.element('section.sidebar > ul > li[data-href-match]').each(function (index, element) {
|
angular.element('section.sidebar > ul > li[data-href-match]').each(function (index, element) {
|
||||||
var match = angular.element(element).attr('data-href-match');
|
var match = angular.element(element).attr('data-href-match');
|
||||||
|
|
||||||
if (utils.isUrlMatchUrl2(match, location)) {
|
if (isUrlMatchUrl2(match, location)) {
|
||||||
angular.element(element).addClass('active');
|
angular.element(element).addClass('active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -36,7 +35,7 @@
|
||||||
angular.element('section.sidebar > ul > li.treeview > ul.treeview-menu > li[data-href-match]').each(function (index, element) {
|
angular.element('section.sidebar > ul > li.treeview > ul.treeview-menu > li[data-href-match]').each(function (index, element) {
|
||||||
var match = angular.element(element).attr('data-href-match');
|
var match = angular.element(element).attr('data-href-match');
|
||||||
|
|
||||||
if (utils.isUrlMatchUrl2(match, location)) {
|
if (isUrlMatchUrl2(match, location)) {
|
||||||
angular.element(element).addClass('active').parent().parent().addClass('active');
|
angular.element(element).addClass('active').parent().parent().addClass('active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -61,6 +60,7 @@
|
||||||
$rootScope.taskContext = {
|
$rootScope.taskContext = {
|
||||||
list: [],
|
list: [],
|
||||||
selected: {},
|
selected: {},
|
||||||
|
enableSelectAll: false,
|
||||||
getSelectedTaskIds: function () {
|
getSelectedTaskIds: function () {
|
||||||
var result = [];
|
var result = [];
|
||||||
|
|
||||||
|
@ -150,6 +150,8 @@
|
||||||
$rootScope.taskContext.selected = {};
|
$rootScope.taskContext.selected = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$rootScope.taskContext.enableSelectAll = false;
|
||||||
|
|
||||||
SweetAlert.close();
|
SweetAlert.close();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,310 +0,0 @@
|
||||||
(function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module('ariaNg').factory('utils', ['$location', '$timeout', '$base64', 'SweetAlert', '$translate', 'ariaNgConstants', 'aria2AllOptions', function ($location, $timeout, $base64, SweetAlert, $translate, ariaNgConstants, aria2AllOptions) {
|
|
||||||
var calculateDownloadRemainTime = function (remainBytes, downloadSpeed) {
|
|
||||||
if (downloadSpeed == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return remainBytes / downloadSpeed;
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
generateUniqueId: function () {
|
|
||||||
var sourceId = ariaNgConstants.appPrefix + '_' + Math.round(new Date().getTime() / 1000) + '_' + Math.random();
|
|
||||||
var hashedId = $base64.encode(sourceId);
|
|
||||||
|
|
||||||
return hashedId;
|
|
||||||
},
|
|
||||||
alert: function (text) {
|
|
||||||
$timeout(function () {
|
|
||||||
SweetAlert.swal({
|
|
||||||
title: $translate.instant('Error'),
|
|
||||||
text: $translate.instant(text),
|
|
||||||
type: 'error',
|
|
||||||
confirmButtonText: $translate.instant('OK')
|
|
||||||
});
|
|
||||||
}, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < targetArray.length; i++) {
|
|
||||||
if (targetArray[i][keyProperty] == sourceArray[i][keyProperty]) {
|
|
||||||
angular.extend(targetArray[i], sourceArray[i]);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
copyObjectTo: function (from, to) {
|
|
||||||
if (!to) {
|
|
||||||
return from;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var name in from) {
|
|
||||||
if (!from.hasOwnProperty(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var fromValue = from[name];
|
|
||||||
var toValue = to[name];
|
|
||||||
|
|
||||||
if (angular.isObject(fromValue) || angular.isArray(fromValue)) {
|
|
||||||
to[name] = this.copyObjectTo(from[name], to[name]);
|
|
||||||
} else {
|
|
||||||
if (fromValue != toValue) {
|
|
||||||
to[name] = fromValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return to;
|
|
||||||
},
|
|
||||||
getFileNameFromPath: function (path) {
|
|
||||||
if (!path) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = path.lastIndexOf('/');
|
|
||||||
|
|
||||||
if (index <= 0 || index == path.length) {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.substring(index + 1);
|
|
||||||
},
|
|
||||||
isUrlMatchUrl2: function (url, url2) {
|
|
||||||
if (url === url2) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = url2.indexOf(url);
|
|
||||||
|
|
||||||
if (index !== 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lastPart = url2.substring(url.length);
|
|
||||||
|
|
||||||
if (lastPart.indexOf('/') == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
getOptions: function (keys) {
|
|
||||||
var options = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
var key = keys[i];
|
|
||||||
var option = aria2AllOptions[key];
|
|
||||||
|
|
||||||
if (!option) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
option = angular.extend({
|
|
||||||
key: key,
|
|
||||||
nameKey: 'options.' + key + '.name',
|
|
||||||
descriptionKey: 'options.' + key + '.description'
|
|
||||||
}, option);
|
|
||||||
|
|
||||||
options.push(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
},
|
|
||||||
getTaskName: function (task) {
|
|
||||||
var taskName = "";
|
|
||||||
|
|
||||||
if (task.bittorrent && task.bittorrent.info) {
|
|
||||||
taskName = task.bittorrent.info.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!taskName && task.files && task.files.length >= 1) {
|
|
||||||
taskName = this.getFileNameFromPath(task.files[0].path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!taskName && task.files && task.files.length >= 1 && task.files[0].uris && task.files[0].uris.length >= 1) {
|
|
||||||
taskName = this.getFileNameFromPath(task.files[0].uris[0].uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!taskName) {
|
|
||||||
taskName = $translate.instant('Unknown');
|
|
||||||
}
|
|
||||||
|
|
||||||
return taskName;
|
|
||||||
},
|
|
||||||
processDownloadTask: function (task) {
|
|
||||||
if (!task) {
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
task.totalLength = parseInt(task.totalLength);
|
|
||||||
task.completedLength = parseInt(task.completedLength);
|
|
||||||
task.uploadSpeed = parseInt(task.uploadSpeed);
|
|
||||||
task.downloadSpeed = parseInt(task.downloadSpeed);
|
|
||||||
task.completePercent = (task.totalLength > 0 ? task.completedLength / task.totalLength * 100 : 0);
|
|
||||||
task.remainPercent = 100 - task.completePercent;
|
|
||||||
task.taskName = this.getTaskName(task);
|
|
||||||
task.idle = task.downloadSpeed == 0;
|
|
||||||
|
|
||||||
var remainLength = task.totalLength - task.completedLength;
|
|
||||||
task.remainTime = calculateDownloadRemainTime(remainLength, task.downloadSpeed);
|
|
||||||
|
|
||||||
if (task.files) {
|
|
||||||
for (var i = 0; i < task.files.length; i++) {
|
|
||||||
var file = task.files[i];
|
|
||||||
file.fileName = this.getFileNameFromPath(file.path);
|
|
||||||
file.length = parseInt(file.length);
|
|
||||||
file.completedLength = parseInt(file.completedLength);
|
|
||||||
file.completePercent = (file.length > 0 ? file.completedLength / file.length * 100 : 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return task;
|
|
||||||
},
|
|
||||||
parseOrderType: function (value) {
|
|
||||||
var values = value.split(':');
|
|
||||||
|
|
||||||
var obj = {
|
|
||||||
type: values[0],
|
|
||||||
order: values[1],
|
|
||||||
equals: function (obj) {
|
|
||||||
if (angular.isUndefined(obj.order)) {
|
|
||||||
return this.type === obj.type;
|
|
||||||
} else {
|
|
||||||
return this.type === obj.type && this.order === obj.order;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getValue: function () {
|
|
||||||
return this.type + ":" + this.order;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.defineProperty(obj, 'reverse', {
|
|
||||||
get: function () {
|
|
||||||
return this.order === 'desc';
|
|
||||||
},
|
|
||||||
set: function (value) {
|
|
||||||
this.order = (value ? 'desc' : 'asc');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
},
|
|
||||||
estimateCompletedPercentFromBitField: function (bitfield) {
|
|
||||||
var totalLength = bitfield.length * 0xf;
|
|
||||||
var completedLength = 0;
|
|
||||||
|
|
||||||
if (totalLength == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < bitfield.length; i++) {
|
|
||||||
var num = parseInt(bitfield[i], 16);
|
|
||||||
completedLength += num;
|
|
||||||
}
|
|
||||||
|
|
||||||
return completedLength / totalLength;
|
|
||||||
},
|
|
||||||
estimateHealthPercentFromPeers: function (task, peers) {
|
|
||||||
if (peers.length < 1) {
|
|
||||||
return task.completePercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bitfieldCompletedArr = new Array(task.bitfield.length);
|
|
||||||
var bitfieldPieceArr = new Array(task.bitfield.length);
|
|
||||||
var totalLength = task.bitfield.length * 0xf;
|
|
||||||
var healthBitCount = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < task.bitfield.length; i++) {
|
|
||||||
var num = parseInt(task.bitfield[i], 16);
|
|
||||||
bitfieldCompletedArr[i] = 0;
|
|
||||||
bitfieldPieceArr[i] = 0;
|
|
||||||
|
|
||||||
if (num == 0xf) {
|
|
||||||
bitfieldCompletedArr[i] = num;
|
|
||||||
} else {
|
|
||||||
bitfieldPieceArr[i] = num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < peers.length; i++) {
|
|
||||||
var peer = peers[i];
|
|
||||||
var bitfield = peer.bitfield;
|
|
||||||
|
|
||||||
for (var j = 0; j < bitfield.length; j++) {
|
|
||||||
var num = parseInt(bitfield[j], 16);
|
|
||||||
|
|
||||||
if (num == 0xf) {
|
|
||||||
bitfieldCompletedArr[j] += num;
|
|
||||||
} else {
|
|
||||||
bitfieldPieceArr[j] = Math.max(bitfieldPieceArr[j], num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < bitfieldCompletedArr.length; i++) {
|
|
||||||
bitfieldCompletedArr[i] += bitfieldPieceArr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
var completed = true;
|
|
||||||
|
|
||||||
for (var i = 0; i < bitfieldCompletedArr.length; i++) {
|
|
||||||
var bitCount = Math.min(bitfieldCompletedArr[i], 0xf);
|
|
||||||
healthBitCount += bitCount;
|
|
||||||
bitfieldCompletedArr[i] -= bitCount;
|
|
||||||
|
|
||||||
if (bitCount < 0xf) {
|
|
||||||
completed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!completed) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var healthPercent = healthBitCount / totalLength * 100;
|
|
||||||
|
|
||||||
if (healthPercent < task.completePercent) {
|
|
||||||
healthPercent = task.completePercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return healthPercent;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}]);
|
|
||||||
})();
|
|
|
@ -1,13 +1,13 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module("ariaNg").filter('fileOrderBy', ['orderByFilter', 'utils', function (orderByFilter, utils) {
|
angular.module("ariaNg").filter('fileOrderBy', ['orderByFilter', 'ariaNgCommonService', function (orderByFilter, ariaNgCommonService) {
|
||||||
return function (array, type) {
|
return function (array, type) {
|
||||||
if (!angular.isArray(array)) {
|
if (!angular.isArray(array)) {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderType = utils.parseOrderType(type);
|
var orderType = ariaNgCommonService.parseOrderType(type);
|
||||||
|
|
||||||
if (orderType == null) {
|
if (orderType == null) {
|
||||||
return array;
|
return array;
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
(function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
angular.module("ariaNg").filter('filename', ['utils', function (utils) {
|
|
||||||
return function (path) {
|
|
||||||
return utils.getFileNameFromPath(path);
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
})();
|
|
|
@ -1,13 +1,13 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module("ariaNg").filter('taskOrderBy', ['orderByFilter', 'utils', function (orderByFilter, utils) {
|
angular.module("ariaNg").filter('taskOrderBy', ['orderByFilter', 'ariaNgCommonService', function (orderByFilter, ariaNgCommonService) {
|
||||||
return function (array, type) {
|
return function (array, type) {
|
||||||
if (!angular.isArray(array)) {
|
if (!angular.isArray(array)) {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
var orderType = utils.parseOrderType(type);
|
var orderType = ariaNgCommonService.parseOrderType(type);
|
||||||
|
|
||||||
if (orderType == null) {
|
if (orderType == null) {
|
||||||
return array;
|
return array;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ariaNg').factory('aria2RpcService', ['$q', 'aria2RpcConstants', 'ariaNgSettingService', 'aria2HttpRpcService', 'aria2WebSocketRpcService', 'utils', function ($q, aria2RpcConstants, ariaNgSettingService, aria2HttpRpcService, aria2WebSocketRpcService, utils) {
|
angular.module('ariaNg').factory('aria2RpcService', ['$q', 'aria2RpcConstants', 'ariaNgCommonService', 'ariaNgSettingService', 'aria2HttpRpcService', 'aria2WebSocketRpcService', function ($q, aria2RpcConstants, ariaNgCommonService, ariaNgSettingService, aria2HttpRpcService, aria2WebSocketRpcService) {
|
||||||
var protocol = ariaNgSettingService.getProtocol();
|
var protocol = ariaNgSettingService.getProtocol();
|
||||||
|
|
||||||
var getAria2MethodFullName = function (methodName) {
|
var getAria2MethodFullName = function (methodName) {
|
||||||
|
@ -9,10 +9,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var invoke = function (method, context) {
|
var invoke = function (method, context) {
|
||||||
context.uniqueId = utils.generateUniqueId();
|
context.uniqueId = ariaNgCommonService.generateUniqueId();
|
||||||
context.requestBody = {
|
context.requestBody = {
|
||||||
jsonrpc: aria2RpcConstants.rpcServiceVersion,
|
jsonrpc: aria2RpcConstants.rpcServiceVersion,
|
||||||
method: (method.indexOf('system.') != 0 ? getAria2MethodFullName(method) : method),
|
method: (method.indexOf(aria2RpcConstants.rpcSystemServiceName + '.') != 0 ? getAria2MethodFullName(method) : method),
|
||||||
id: context.uniqueId,
|
id: context.uniqueId,
|
||||||
params: context.params
|
params: context.params
|
||||||
};
|
};
|
||||||
|
|
96
app/scripts/services/aria2SettingService.js
Normal file
96
app/scripts/services/aria2SettingService.js
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ariaNg').factory('aria2SettingService', ['aria2AllOptions', 'aria2GlobalAvailableOptions', 'aria2RpcService', function (aria2AllOptions, aria2GlobalAvailableOptions, aria2RpcService) {
|
||||||
|
var processStatResult = function (stat) {
|
||||||
|
if (!stat) {
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeCount = parseInt(stat.numActive);
|
||||||
|
var waitingCount = parseInt(stat.numWaiting);
|
||||||
|
var totalRunningCount = activeCount + waitingCount;
|
||||||
|
|
||||||
|
stat.totalRunningCount = totalRunningCount;
|
||||||
|
|
||||||
|
return stat;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
getAvailableOptionsKeys: function (type) {
|
||||||
|
if (type == 'basic') {
|
||||||
|
return aria2GlobalAvailableOptions.basicOptions;
|
||||||
|
} else if (type == 'http-ftp-sftp') {
|
||||||
|
return aria2GlobalAvailableOptions.httpFtpSFtpOptions;
|
||||||
|
} else if (type == 'http') {
|
||||||
|
return aria2GlobalAvailableOptions.httpOptions;
|
||||||
|
} else if (type == 'ftp-sftp') {
|
||||||
|
return aria2GlobalAvailableOptions.ftpSFtpOptions;
|
||||||
|
} else if (type == 'bt') {
|
||||||
|
return aria2GlobalAvailableOptions.btOptions;
|
||||||
|
} else if (type == 'metalink') {
|
||||||
|
return aria2GlobalAvailableOptions.metalinkOptions;
|
||||||
|
} else if (type == 'rpc') {
|
||||||
|
return aria2GlobalAvailableOptions.rpcOptions;
|
||||||
|
} else if (type == 'advanced') {
|
||||||
|
return aria2GlobalAvailableOptions.advancedOptions;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getSpecifiedOptions: function (keys) {
|
||||||
|
var options = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < keys.length; i++) {
|
||||||
|
var key = keys[i];
|
||||||
|
var option = aria2AllOptions[key];
|
||||||
|
|
||||||
|
if (!option) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
option = angular.extend({
|
||||||
|
key: key,
|
||||||
|
nameKey: 'options.' + key + '.name',
|
||||||
|
descriptionKey: 'options.' + key + '.description'
|
||||||
|
}, option);
|
||||||
|
|
||||||
|
options.push(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
getGlobalOption: function (callback) {
|
||||||
|
return aria2RpcService.getGlobalOption({
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setGlobalOption: function (key, value, callback) {
|
||||||
|
var data = {};
|
||||||
|
data[key] = value;
|
||||||
|
|
||||||
|
return aria2RpcService.changeGlobalOption({
|
||||||
|
options: data,
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getServerStatus: function (callback) {
|
||||||
|
return aria2RpcService.getVersion({
|
||||||
|
callback: callback
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getGlobalStat: function (callback) {
|
||||||
|
return aria2RpcService.getGlobalStat({
|
||||||
|
callback: function (result) {
|
||||||
|
if (!callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stat = processStatResult(result);
|
||||||
|
callback(stat);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
})();
|
116
app/scripts/services/ariaNgCommonService.js
Normal file
116
app/scripts/services/ariaNgCommonService.js
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ariaNg').factory('ariaNgCommonService', ['$location', '$timeout', '$base64', 'SweetAlert', '$translate', 'ariaNgConstants', function ($location, $timeout, $base64, SweetAlert, $translate, ariaNgConstants) {
|
||||||
|
return {
|
||||||
|
generateUniqueId: function () {
|
||||||
|
var sourceId = ariaNgConstants.appPrefix + '_' + Math.round(new Date().getTime() / 1000) + '_' + Math.random();
|
||||||
|
var hashedId = $base64.encode(sourceId);
|
||||||
|
|
||||||
|
return hashedId;
|
||||||
|
},
|
||||||
|
alert: function (text) {
|
||||||
|
$timeout(function () {
|
||||||
|
SweetAlert.swal({
|
||||||
|
title: $translate.instant('Error'),
|
||||||
|
text: $translate.instant(text),
|
||||||
|
type: 'error',
|
||||||
|
confirmButtonText: $translate.instant('OK')
|
||||||
|
});
|
||||||
|
}, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < targetArray.length; i++) {
|
||||||
|
if (targetArray[i][keyProperty] == sourceArray[i][keyProperty]) {
|
||||||
|
angular.extend(targetArray[i], sourceArray[i]);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
copyObjectTo: function (from, to) {
|
||||||
|
if (!to) {
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var name in from) {
|
||||||
|
if (!from.hasOwnProperty(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fromValue = from[name];
|
||||||
|
var toValue = to[name];
|
||||||
|
|
||||||
|
if (angular.isObject(fromValue) || angular.isArray(fromValue)) {
|
||||||
|
to[name] = this.copyObjectTo(from[name], to[name]);
|
||||||
|
} else {
|
||||||
|
if (fromValue != toValue) {
|
||||||
|
to[name] = fromValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return to;
|
||||||
|
},
|
||||||
|
parseOrderType: function (value) {
|
||||||
|
var values = value.split(':');
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
type: values[0],
|
||||||
|
order: values[1],
|
||||||
|
equals: function (obj) {
|
||||||
|
if (angular.isUndefined(obj.order)) {
|
||||||
|
return this.type === obj.type;
|
||||||
|
} else {
|
||||||
|
return this.type === obj.type && this.order === obj.order;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getValue: function () {
|
||||||
|
return this.type + ":" + this.order;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(obj, 'reverse', {
|
||||||
|
get: function () {
|
||||||
|
return this.order === 'desc';
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
this.order = (value ? 'desc' : 'asc');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
})();
|
248
app/scripts/services/ariaNgTaskService.js
Normal file
248
app/scripts/services/ariaNgTaskService.js
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ariaNg').factory('ariaNgTaskService', ['$translate', 'aria2RpcService', function ($translate, aria2RpcService) {
|
||||||
|
var getFileNameFromPath = function (path) {
|
||||||
|
if (!path) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = path.lastIndexOf('/');
|
||||||
|
|
||||||
|
if (index <= 0 || index == path.length) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.substring(index + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
var calculateDownloadRemainTime = function (remainBytes, downloadSpeed) {
|
||||||
|
if (downloadSpeed == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainBytes / downloadSpeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getTaskName = function (task) {
|
||||||
|
var taskName = "";
|
||||||
|
|
||||||
|
if (task.bittorrent && task.bittorrent.info) {
|
||||||
|
taskName = task.bittorrent.info.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!taskName && task.files && task.files.length >= 1) {
|
||||||
|
taskName = getFileNameFromPath(task.files[0].path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!taskName && task.files && task.files.length >= 1 && task.files[0].uris && task.files[0].uris.length >= 1) {
|
||||||
|
taskName = getFileNameFromPath(task.files[0].uris[0].uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!taskName) {
|
||||||
|
taskName = $translate.instant('Unknown');
|
||||||
|
}
|
||||||
|
|
||||||
|
return taskName;
|
||||||
|
};
|
||||||
|
|
||||||
|
var processDownloadTask = function (task) {
|
||||||
|
if (!task) {
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
task.totalLength = parseInt(task.totalLength);
|
||||||
|
task.completedLength = parseInt(task.completedLength);
|
||||||
|
task.uploadSpeed = parseInt(task.uploadSpeed);
|
||||||
|
task.downloadSpeed = parseInt(task.downloadSpeed);
|
||||||
|
task.completePercent = (task.totalLength > 0 ? task.completedLength / task.totalLength * 100 : 0);
|
||||||
|
task.remainPercent = 100 - task.completePercent;
|
||||||
|
task.taskName = getTaskName(task);
|
||||||
|
task.idle = task.downloadSpeed == 0;
|
||||||
|
|
||||||
|
var remainLength = task.totalLength - task.completedLength;
|
||||||
|
task.remainTime = calculateDownloadRemainTime(remainLength, task.downloadSpeed);
|
||||||
|
|
||||||
|
if (task.files) {
|
||||||
|
for (var i = 0; i < task.files.length; i++) {
|
||||||
|
var file = task.files[i];
|
||||||
|
file.fileName = getFileNameFromPath(file.path);
|
||||||
|
file.length = parseInt(file.length);
|
||||||
|
file.completedLength = parseInt(file.completedLength);
|
||||||
|
file.completePercent = (file.length > 0 ? file.completedLength / file.length * 100 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return task;
|
||||||
|
};
|
||||||
|
|
||||||
|
var estimateCompletedPercentFromBitField = function (bitfield) {
|
||||||
|
var totalLength = bitfield.length * 0xf;
|
||||||
|
var completedLength = 0;
|
||||||
|
|
||||||
|
if (totalLength == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < bitfield.length; i++) {
|
||||||
|
var num = parseInt(bitfield[i], 16);
|
||||||
|
completedLength += num;
|
||||||
|
}
|
||||||
|
|
||||||
|
return completedLength / totalLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
getTaskList: function (type, full, callback) {
|
||||||
|
var invokeMethod = null;
|
||||||
|
|
||||||
|
if (type == 'downloading') {
|
||||||
|
invokeMethod = aria2RpcService.tellActive;
|
||||||
|
} else if (type == 'waiting') {
|
||||||
|
invokeMethod = aria2RpcService.tellWaiting;
|
||||||
|
} else if (type == 'stopped') {
|
||||||
|
invokeMethod = aria2RpcService.tellStopped;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return invokeMethod({
|
||||||
|
requestParams: full ? aria2RpcService.getFullTaskParams() : aria2RpcService.getBasicTaskParams(),
|
||||||
|
callback: function (result) {
|
||||||
|
if (!callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getTaskStatus: function (gid, callback) {
|
||||||
|
return aria2RpcService.tellStatus({
|
||||||
|
gid: gid,
|
||||||
|
callback: function (result) {
|
||||||
|
if (!callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var task = processDownloadTask(result);
|
||||||
|
callback(task);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getTaskOption: function (gid, callback) {
|
||||||
|
return aria2RpcService.getOption({
|
||||||
|
gid: gid,
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getBtTaskPeers: function (gid, callback) {
|
||||||
|
return aria2RpcService.getPeers({
|
||||||
|
gid: gid,
|
||||||
|
callback: function (result) {
|
||||||
|
if (!callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
var peer = result[i];
|
||||||
|
peer.completePercent = estimateCompletedPercentFromBitField(peer.bitfield) * 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
startTasks: function (gids, callback) {
|
||||||
|
return aria2RpcService.unpauseMulti({
|
||||||
|
gids: gids,
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pauseTasks: function (gids, callback) {
|
||||||
|
return aria2RpcService.forcePauseMulti({
|
||||||
|
gids: gids,
|
||||||
|
callback: callback
|
||||||
|
});
|
||||||
|
},
|
||||||
|
processDownloadTasks: function (tasks) {
|
||||||
|
if (!angular.isArray(tasks)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tasks.length; i++) {
|
||||||
|
processDownloadTask(tasks[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
estimateHealthPercentFromPeers: function (task, peers) {
|
||||||
|
if (peers.length < 1) {
|
||||||
|
return task.completePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bitfieldCompletedArr = new Array(task.bitfield.length);
|
||||||
|
var bitfieldPieceArr = new Array(task.bitfield.length);
|
||||||
|
var totalLength = task.bitfield.length * 0xf;
|
||||||
|
var healthBitCount = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < task.bitfield.length; i++) {
|
||||||
|
var num = parseInt(task.bitfield[i], 16);
|
||||||
|
bitfieldCompletedArr[i] = 0;
|
||||||
|
bitfieldPieceArr[i] = 0;
|
||||||
|
|
||||||
|
if (num == 0xf) {
|
||||||
|
bitfieldCompletedArr[i] = num;
|
||||||
|
} else {
|
||||||
|
bitfieldPieceArr[i] = num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < peers.length; i++) {
|
||||||
|
var peer = peers[i];
|
||||||
|
var bitfield = peer.bitfield;
|
||||||
|
|
||||||
|
for (var j = 0; j < bitfield.length; j++) {
|
||||||
|
var num = parseInt(bitfield[j], 16);
|
||||||
|
|
||||||
|
if (num == 0xf) {
|
||||||
|
bitfieldCompletedArr[j] += num;
|
||||||
|
} else {
|
||||||
|
bitfieldPieceArr[j] = Math.max(bitfieldPieceArr[j], num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < bitfieldCompletedArr.length; i++) {
|
||||||
|
bitfieldCompletedArr[i] += bitfieldPieceArr[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var completed = true;
|
||||||
|
|
||||||
|
for (var i = 0; i < bitfieldCompletedArr.length; i++) {
|
||||||
|
var bitCount = Math.min(bitfieldCompletedArr[i], 0xf);
|
||||||
|
healthBitCount += bitCount;
|
||||||
|
bitfieldCompletedArr[i] -= bitCount;
|
||||||
|
|
||||||
|
if (bitCount < 0xf) {
|
||||||
|
completed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!completed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var healthPercent = healthBitCount / totalLength * 100;
|
||||||
|
|
||||||
|
if (healthPercent < task.completePercent) {
|
||||||
|
healthPercent = task.completePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return healthPercent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
||||||
|
})();
|
|
@ -31,7 +31,7 @@
|
||||||
<span ng-bind="task.taskName"></span>
|
<span ng-bind="task.taskName"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" ng-if="task">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>File Size</span>
|
<span translate>File Size</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<span ng-bind="'(' + task.files.length + ' ' + ('Files' | translate) + ')'"></span>
|
<span ng-bind="'(' + task.files.length + ' ' + ('Files' | translate) + ')'"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" ng-if="task">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Task Status</span>
|
<span translate>Task Status</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
<span ng-bind="task | taskStatus"></span>
|
<span ng-bind="task | taskStatus"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-if="task.status == 'error' && task.errorMessage">
|
<div class="row" ng-if="task && task.status == 'error' && task.errorMessage">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Error Description</span>
|
<span translate>Error Description</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
<span ng-bind="task.errorMessage"></span>
|
<span ng-bind="task.errorMessage"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" ng-if="task">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span ng-bind="('Completed Percent' | translate) + (task.status == 'active' && task.bittorrent ? ' (' + ('Health Percent' | translate) + ')' : '')"></span>
|
<span ng-bind="('Completed Percent' | translate) + (task.status == 'active' && task.bittorrent ? ' (' + ('Health Percent' | translate) + ')' : '')"></span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
<span ng-bind="(task.completePercent | percent: 2) + '%' + (task.status == 'active' && task.bittorrent ? ' (' + (healthPercent | percent: 2) + '%' + ')' : '')"></span>
|
<span ng-bind="(task.completePercent | percent: 2) + '%' + (task.status == 'active' && task.bittorrent ? ' (' + (healthPercent | percent: 2) + '%' + ')' : '')"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" ng-if="task">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Download</span>
|
<span translate>Download</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
<span ng-bind="(task.completedLength | readableVolumn) + (task.status == 'active' ? ' @ ' + (task.downloadSpeed | readableVolumn) + '/s' : '')"></span>
|
<span ng-bind="(task.completedLength | readableVolumn) + (task.status == 'active' ? ' @ ' + (task.downloadSpeed | readableVolumn) + '/s' : '')"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-if="task.bittorrent">
|
<div class="row" ng-if="task && task.bittorrent">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Upload</span>
|
<span translate>Upload</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
<span ng-bind="(task.uploadLength | readableVolumn) + (task.status == 'active' ? ' @ ' + (task.uploadSpeed | readableVolumn) + '/s' : '')"></span>
|
<span ng-bind="(task.uploadLength | readableVolumn) + (task.status == 'active' ? ' @ ' + (task.uploadSpeed | readableVolumn) + '/s' : '')"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-if="task.status == 'active' && task.completedLength < task.totalLength">
|
<div class="row" ng-if="task && task.status == 'active' && task.completedLength < task.totalLength">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Remain Time</span>
|
<span translate>Remain Time</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
<span ng-bind="0 <= task.remainTime && task.remainTime < 86400? (task.remainTime | dateDuration: 'second': 'HH:mm:ss') : ('More Than One Day' | translate)"></span>
|
<span ng-bind="0 <= task.remainTime && task.remainTime < 86400? (task.remainTime | dateDuration: 'second': 'HH:mm:ss') : ('More Than One Day' | translate)"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-if="task.infoHash">
|
<div class="row" ng-if="task && task.infoHash">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Info Hash</span>
|
<span translate>Info Hash</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
<span ng-bind="task.infoHash"></span>
|
<span ng-bind="task.infoHash"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-if="task.status == 'active'">
|
<div class="row" ng-if="task && task.status == 'active'">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span ng-bind="(task.bittorrent ? ('Seeders' | translate) + ' / ' : '') + ('Connections' | translate)">Connections</span>
|
<span ng-bind="(task.bittorrent ? ('Seeders' | translate) + ' / ' : '') + ('Connections' | translate)">Connections</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
<span ng-bind="(task.numSeeders ? (task.numSeeders + ' / ') : '') + task.connections"></span>
|
<span ng-bind="(task.numSeeders ? (task.numSeeders + ' / ') : '') + task.connections"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" ng-if="task">
|
||||||
<div class="setting-key col-sm-4">
|
<div class="setting-key col-sm-4">
|
||||||
<span translate>Download Dir</span>
|
<span translate>Download Dir</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in a new issue