Initial core the new overhauled ui in angular.html with fixes for ui in the old index.html
This commit is contained in:
parent
e7c9e4d0cc
commit
571eaf8257
|
@ -12,13 +12,11 @@ Then download the webui, you can either do that by downloading this repository a
|
|||
|
||||
Status
|
||||
===========
|
||||
Usable but some bugs here and there. A lot more to features to come so stay tuned.
|
||||
Usable but some bugs here and there. A complete overhaul is underway in the angular.html but its completely broken currently and once it is completed then it would replace the old index.html
|
||||
|
||||
TODO
|
||||
-----------
|
||||
* More advance options for new download
|
||||
* More specialized info for special download types like bit torrent and metalink
|
||||
* Adding URIs to existing downloads
|
||||
* Implement all features of the old version into the new architecture in angular.html
|
||||
|
||||
|
||||
Dependencies
|
||||
|
|
208
angular.html
Normal file
208
angular.html
Normal file
|
@ -0,0 +1,208 @@
|
|||
<!doctype>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="icon" href="favicon.ico" />
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>aria2 web client</title>
|
||||
|
||||
<link rel="stylesheet" href="css/bootstrap.css">
|
||||
<link rel="stylesheet" href="css/font-awesome.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
|
||||
|
||||
<!-- external javascript dependencies -->
|
||||
<script src="js/libs/jquery-1.8.3.js"></script>
|
||||
<script src="js/libs/underscore.js"></script>
|
||||
|
||||
<script src="js/libs/bootstrap.js"></script>
|
||||
|
||||
<script src="js/libs/angular.js"></script>
|
||||
|
||||
<script src="js/libs/jquery.flot.js"></script>
|
||||
<script src="js/libs/jquery.flot.resize.js"></script>
|
||||
|
||||
<!-- webui core -->
|
||||
<script src="js/app.js"></script>
|
||||
|
||||
<script src="js/services/deps.js"></script>
|
||||
<script src="js/services/base64.js"></script>
|
||||
<script src="js/services/utils.js"></script>
|
||||
|
||||
<script src="js/services/rpc/jsoncall.js"></script>
|
||||
<script src="js/services/rpc/sockcall.js"></script>
|
||||
<script src="js/services/rpc/syscall.js"></script>
|
||||
<script src="js/services/rpc/rpc.js"></script>
|
||||
|
||||
|
||||
<script src="js/ctrls/nav.js"></script>
|
||||
<script src="js/ctrls/modal.js"></script>
|
||||
<script src="js/ctrls/download.js"></script>
|
||||
|
||||
<script src="js/init.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top" ng-controller="NavCtrl">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
|
||||
<a class="btn btn-navbar"
|
||||
data-toggle="collapse"
|
||||
data-target=".nav-collapse">
|
||||
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
|
||||
<a class="brand">{{ name }}</a>
|
||||
|
||||
<div class="nav-collapse">
|
||||
<ul class="nav">
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
Add <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="#"><i class="icon-download"></i> Add Download URL</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><i class="icon-file"></i> Add Metalink</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#"><i class="icon-file"></i> Add Torrent</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="dropdown" id="stop_downloads">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
Manage <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#"><i class="icon-pause"></i> Pause All</a></li>
|
||||
<li><a href="#"><i class="icon-play"></i> Resume Paused</a></li>
|
||||
<li><a href="#"><i class="icon-remove"></i> Purge Completed</a></li>
|
||||
<li><a href="#"><i class="icon-fire"></i> Remove All</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<ul class="nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
Settings <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">
|
||||
<i class="icon-wrench"></i> Connection Settings</a>
|
||||
</li>
|
||||
<li><a href="#">
|
||||
<i class="icon-wrench"></i> Global Settings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav pull-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
About <b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">
|
||||
<i class="icon-list-alt"></i> Global Statistics</a></li>
|
||||
<li><a href="#">
|
||||
<i class="icon-info-sign"></i> About</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div role="main" class="container" ng-controller="DownloadCtrl">
|
||||
|
||||
<div id="active_downloads">
|
||||
<table class="active-download" ng-repeat="download in getDownloads()">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-toggle="collapse" data-target=".download-detail .collapse" class="download-overview">
|
||||
<b class="download-name">{{name}}</b>
|
||||
|
||||
<ul class="stats hidden-phone pull-right">
|
||||
<li class="label label-success">Time left: <span class="download-eta">{{eta}}</span></li>
|
||||
<li class="label label-success">Download Speed: <span class="download-down_speed">{{down_speed}}</span></li>
|
||||
<li class="label label-success">Progress: <span class="download-down_speed">{{percentage}}%</span></li>
|
||||
</ul>
|
||||
<div class="progress full-progress progress-striped active" style="width: 100%; margin: 0; padding: 0;">
|
||||
<div class="bar" style="width: 90%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="download-controls">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-mini download_pause"><i class="icon-pause"></i></button>
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li><a><i class="icon-cog"></i> Settings</a></li>
|
||||
<li><a><i class="icon-list-alt"></i> Peers</a></li>
|
||||
<li><a data-toggle="collapse" data-target=".download-detail .collapse"><i class="icon-info-sign"></i> More Info</a></li>
|
||||
<li><a href="#"><i class="icon-remove"></i> Remove</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-toggle="collapse" data-target=".download-detail .collapse" class="download-detail">
|
||||
<td colspan="2">
|
||||
<div class="collapse more_info">
|
||||
<canvas class="progress chunk-canvas" width="1400" style="width: 100%;"></canvas>
|
||||
<ul class="stats">
|
||||
<li class="label">Status: <span class="download-status">{{status}}</span></li>
|
||||
<li class="label">GID: <span class="download-gid">{{gid}}</span></li>
|
||||
<li class="label">Dir: <span class="download-dir">{{dir}}</span></li>
|
||||
<li class="label">Size: <span class="download-size">{{size}}</span></li>
|
||||
<li class="label">Downloaded: <span class="download-downloaded">{{downloaded}}</span></li>
|
||||
<li class="label">Num of Pieces: <span class="download-numPieces">{{numPieces}}</span></li>
|
||||
<li class="label">Piece Length: <span class="download-pieceLength">{{pieceLength}}</span></li>
|
||||
<li class="label">ETA: <span class="download-eta">{{eta}}</span></li>
|
||||
<li class="label">Down Speed: <span class="download-down_speed">{{down_speed}}</span></li>
|
||||
<li class="label">Upload Speed: <span class="download-upload_speed">{{upload_speed}}</span></li>
|
||||
<li class="label">Upload Length: <span class="download-uploadLength">{{uploadLength}}</span></li>
|
||||
<li class="label">Connections: <span class="download-connections">{{connections}}</span></li>
|
||||
</ul>
|
||||
|
||||
<h4 class="hidden-phone">Download Files</h4>
|
||||
<ul class="download-files hidden-phone">
|
||||
<li class="label">{{path}} ({{size}})</li>
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<div class="download-graph"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="waiting_downloads"></div>
|
||||
|
||||
<div id="stopped_downloads"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
87
css/style.css
Normal file
87
css/style.css
Normal file
|
@ -0,0 +1,87 @@
|
|||
.download-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
.active-download {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.waiting-download {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.stopped-download {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.stats {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.stats li {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.download-controls {
|
||||
width: 60px;
|
||||
}
|
||||
.download-controls .btn-group {
|
||||
height: 70px;
|
||||
width: 100%;
|
||||
float: right;
|
||||
}
|
||||
.download-controls .btn-group .btn:nth-child(1) {
|
||||
width: 70%;
|
||||
}
|
||||
.download-controls .btn-group .btn:nth-child(2) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.download-controls .btn-group .btn {
|
||||
height: 100%;
|
||||
}
|
||||
.download-controls .btn-group .btn i {
|
||||
height: 100%;
|
||||
font-size: 28px;
|
||||
color: gray;
|
||||
}
|
||||
.download-overview {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.download-detail {
|
||||
cursor: pointer;
|
||||
}
|
||||
.download-detail .stats li {
|
||||
width: 150px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.download-detail h4 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.download-files {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.download-files li {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
@media all and (min-width: 980px) {
|
||||
body {
|
||||
padding-top: 60px;
|
||||
}
|
||||
}
|
423
index.html
423
index.html
|
@ -12,13 +12,14 @@
|
|||
|
||||
<link rel="stylesheet" href="css/bootstrap.css">
|
||||
<link rel="stylesheet" href="css/font-awesome.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
|
||||
|
||||
<!-- external javascript dependencies -->
|
||||
<script src="js/libs/jquery-1.8.3.js"></script>
|
||||
<script src="js/libs/jquery.flot.js"></script>
|
||||
<script src="js/libs/jquery.flot.resize.js"></script>
|
||||
<script src="js/libs/lodash.underscore.min.js"></script>
|
||||
<script src="js/libs/underscore.js"></script>
|
||||
<script src="js/libs/bootstrap.js"></script>
|
||||
<script src="js/libs/mustache.js"></script>
|
||||
<script src="js/libs/piecon.js"></script>
|
||||
|
@ -66,229 +67,197 @@
|
|||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.active-download {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: rgb(245, 245, 245);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.stats {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
.stats li {
|
||||
width: 145px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.download-controls {
|
||||
width: 60px;
|
||||
}
|
||||
.download-controls .btn-group {
|
||||
height: 70px;
|
||||
width: 100%;
|
||||
float: right;
|
||||
}
|
||||
.download-controls .btn-group .btn:nth-child(1) {
|
||||
width: 70%;
|
||||
}
|
||||
.download-controls .btn-group .btn:nth-child(2) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.download-controls .btn-group .btn {
|
||||
height: 100%;
|
||||
}
|
||||
.download-controls .btn-group .btn i {
|
||||
height: 100%;
|
||||
font-size: 28px;
|
||||
color: gray;
|
||||
}
|
||||
.download-overview {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.download-detail {
|
||||
cursor: pointer;
|
||||
}
|
||||
.download-detail .stats li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.download-detail h4 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.download-files {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.download-files li {
|
||||
padding: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
@media all and (min-width: 980px) {
|
||||
body {
|
||||
padding-top: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- }}} -->
|
||||
|
||||
<!--{{{ active downloads template -->
|
||||
<script type="text/mustache" id="download_active_template">
|
||||
<div class="row download_item download_active_item" data-gid="{{gid}}" data-settingsName={{sett_name}}>
|
||||
<div class="span2 download_name">
|
||||
<b style="font-size: 12px;" class="tmp_name">{{name}}</b>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<div class="pull-right">
|
||||
<span class="label label-success">Remaining: <span class="tmp_remaining">{{remaining}}</span></span> |
|
||||
<span class="label label-success">Progress: <span class="tmp_percentage">{{percentage}}</span>%</span> |
|
||||
<span class="label label-success">Speed: <span class="tmp_down_speed">{{down_speed}}</span></span> |
|
||||
<span class="label label-success">Time left: <span class="tmp_eta">{{eta}}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<div class="button_set">
|
||||
<button class="btn btn-mini download_pause"><i class="icon-pause"></i>Pause</button>
|
||||
<button class="btn btn-mini btn-info" data-toggle="collapse" data-target="[data-gid={{gid}}] .more_info" onclick="$(this).button('toggle');"><i class="icon-info-sign"></i> More Info</button>
|
||||
<button class="btn btn-mini btn-danger download_remove"><i class="icon-remove"></i> Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="span11 progress full-progress progress-striped active">
|
||||
<table class="active-download" data-gid="{{gid}}" data-settingsName={{sett_name}}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse" class="download-overview">
|
||||
<b class="download-name">{{name}}</b>
|
||||
|
||||
<ul class="stats hidden-phone pull-right">
|
||||
<li class="label label-success">Time left: <span class="download-eta">{{eta}}</span></li>
|
||||
<li class="label label-success">Download Speed: <span class="download-down_speed">{{down_speed}}</span></li>
|
||||
<li class="label label-success">Progress: <span class="download-down_speed">{{percentage}}%</span></li>
|
||||
</ul>
|
||||
<div class="progress full-progress progress-striped active" style="width: 100%; margin: 0; padding: 0;">
|
||||
<div class="bar" style="width: {{percentage}}%;"></div>
|
||||
</div>
|
||||
<div class="span11 more_info collapse">
|
||||
<canvas class="span10 progress chunk-canvas" width="1400"></canvas>
|
||||
<b class="span2 label active_settings">Status: <span class="tmp_status">{{status}}</span></b>
|
||||
<b class="span2 label active_settings">GID: <span class="tmp_gid">{{gid}}</span></b>
|
||||
<b class="span2 label active_settings">Dir: <span class="tmp_dir">{{dir}}</span></b>
|
||||
<b class="span2 label active_settings">Size: <span class="tmp_size">{{size}}</span></b>
|
||||
<b class="span2 label active_settings">Downloaded: <span class="tmp_downloaded">{{downloaded}}</span></b>
|
||||
<b class="span2 label active_settings">Num of Pieces: <span class="tmp_numPieces">{{numPieces}}</span></b>
|
||||
<b class="span2 label active_settings">Piece Length: <span class="tmp_pieceLength">{{pieceLength}}</span></b>
|
||||
<b class="span2 label active_settings">ETA: <span class="tmp_eta">{{eta}}</span></b>
|
||||
<b class="span2 label active_settings">Down Speed: <span class="tmp_down_speed">{{down_speed}}</span></b>
|
||||
<b class="span2 label active_settings">Upload Speed: <span class="tmp_upload_speed">{{upload_speed}}</span></b>
|
||||
<b class="span2 label active_settings">Upload Length: <span class="tmp_uploadLength">{{uploadLength}}</span></b>
|
||||
<b class="span2 label active_settings">Connections: <span class="tmp_connections">{{connections}}</span></b>
|
||||
<div class="span12">
|
||||
<h3>Files</h3>
|
||||
<ul>
|
||||
{{#files}}
|
||||
<li><b>{{path}} <span class="label">{{size}}</span></b></li>
|
||||
{{/files}}
|
||||
</td>
|
||||
<td class="download-controls">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-mini download_pause"><i class="icon-pause"></i></button>
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li><a href="#" class="download_settings"><i class="icon-cog"></i> Settings</a></li>
|
||||
{{#bittorrent}}
|
||||
<li><a href="#" class="torrent_info"><i class="icon-list-alt"></i> Peers</a></li>
|
||||
{{/bittorrent}}
|
||||
<li><a href="#" data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse"><i class="icon-info-sign"></i> More Info</a></li>
|
||||
<li><a href="#" class="download_remove"><i class="icon-remove"></i> Remove</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pull-right" style="margin-right: 5px;">
|
||||
<button class="btn btn-mini download_settings"><i class="icon-cog"></i> Download Settings for {{sett_name}}</button>{{#bittorrent}}<button class="btn btn-mini torrent_info"><i class="icon-list-alt"></i> Peers</button>{{/bittorrent}}
|
||||
</div>
|
||||
<div class="span11">
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse" class="download-detail">
|
||||
<td colspan="2">
|
||||
<div class="collapse more_info">
|
||||
<canvas class="progress chunk-canvas" width="1400" style="width: 100%;"></canvas>
|
||||
<ul class="stats">
|
||||
<li class="label">Status: <span class="download-status">{{status}}</span></li>
|
||||
<li class="label">GID: <span class="download-gid">{{gid}}</span></li>
|
||||
<li class="label">Dir: <span class="download-dir">{{dir}}</span></li>
|
||||
<li class="label">Size: <span class="download-size">{{size}}</span></li>
|
||||
<li class="label">Downloaded: <span class="download-downloaded">{{downloaded}}</span></li>
|
||||
<li class="label">Num of Pieces: <span class="download-numPieces">{{numPieces}}</span></li>
|
||||
<li class="label">Piece Length: <span class="download-pieceLength">{{pieceLength}}</span></li>
|
||||
<li class="label">ETA: <span class="download-eta">{{eta}}</span></li>
|
||||
<li class="label">Down Speed: <span class="download-down_speed">{{down_speed}}</span></li>
|
||||
<li class="label">Upload Speed: <span class="download-upload_speed">{{upload_speed}}</span></li>
|
||||
<li class="label">Upload Length: <span class="download-uploadLength">{{uploadLength}}</span></li>
|
||||
<li class="label">Connections: <span class="download-connections">{{connections}}</span></li>
|
||||
</ul>
|
||||
|
||||
<h4 class="hidden-phone">Download Files</h4>
|
||||
<ul class="download-files hidden-phone">
|
||||
{{#files}}
|
||||
<li class="label">{{path}} ({{size}})</li>
|
||||
{{/files}}
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<div class="active_graph"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
<!-- active downloads template end }}}-->
|
||||
|
||||
<!--{{{ waiting downloads template-->
|
||||
<script type="text/mustache" id="download_waiting_template">
|
||||
<div class="row download_item download_waiting_item" data-gid="{{gid}}" data-settingsName={{sett_name}}>
|
||||
<div class="span2 download_name">
|
||||
<b style="font-size: 12px;" class="tmp_name">{{name}}</b>
|
||||
</div>
|
||||
<div class="span6">
|
||||
<span class="badge badge-warning">Status: <span class="tmp_status">{{status}}</span></span>
|
||||
<div class="pull-right">
|
||||
<span class="label label-warning">Size: <span class="tmp_size">{{size}}</span></span> |
|
||||
<span class="label label-warning">Remaining: <span class="tmp_remaining">{{remaining}}</span></span> |
|
||||
<span class="label label-warning">Progress: <span class="tmp_percentage">{{percentage}}</span>%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<div class="button_set">
|
||||
<button class="btn btn-mini download_play"><i class="icon-play"></i> Resume</button>
|
||||
<button class="btn btn-mini btn-info" data-toggle="collapse" data-target="[data-gid={{gid}}] .more_info" onclick="$(this).button('toggle');"><i class="icon-info-sign"></i> More Info</button>
|
||||
<button class="btn btn-mini btn-danger download_remove"><i class="icon-fire"></i> Purge</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="span11 full-progress progress progress-striped">
|
||||
<div class="bar" style="width: {{percentage}}%; background-color:#FBB450"></div>
|
||||
</div>
|
||||
<div class="span12 more_info collapse">
|
||||
<b class="span2 label active_settings">Status: <span class="tmp_status">{{status}}</span></b>
|
||||
<b class="span2 label active_settings">GID: <span class="tmp_gid">{{gid}}</span></b>
|
||||
<b class="span2 label active_settings">Dir: <span class="tmp_dir">{{dir}}</span></b>
|
||||
<b class="span2 label active_settings">Size: <span class="tmp_size">{{size}}</span></b>
|
||||
<b class="span2 label active_settings">Downloaded: <span class="tmp_downloaded">{{downloaded}}</span></b>
|
||||
<b class="span2 label active_settings">Num of Pieces: <span class="tmp_numPieces">{{numPieces}}</span></b>
|
||||
<b class="span2 label active_settings">Piece Length: <span class="tmp_pieceLength">{{pieceLength}}</span></b>
|
||||
<b class="span2 label active_settings">Upload Length: <span class="tmp_uploadLength">{{uploadLength}}</span></b>
|
||||
<div class="pull-right" style="margin-right: 5px;">
|
||||
<button class="btn btn-mini download_settings"><i class="icon-cog"></i> Download Settings for {{sett_name}}</button>
|
||||
<table class="waiting-download" data-gid="{{gid}}" data-settingsName={{sett_name}}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse" class="download-overview">
|
||||
<b class="download-name">{{name}}</b>
|
||||
|
||||
<ul class="stats hidden-phone pull-right">
|
||||
<li class="label label-success">Size: <span class="download-size">{{size}}</span></li>
|
||||
<li class="label label-success">Downloaded: <span class="download-downloaded">{{downloaded}}</span></li>
|
||||
<li class="label label-success">Path: <span class="download-dir">{{dir}}</span></li>
|
||||
</ul>
|
||||
<div class="progress full-progress progress-striped active" style="width: 100%; margin: 0; padding: 0;">
|
||||
<div class="bar" style="width: {{percentage}}%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="download-controls">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-mini download_play"><i class="icon-play"></i></button>
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li><a href="#" class="download_settings"><i class="icon-cog"></i> Settings</a></li>
|
||||
<li><a href="#" data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse"><i class="icon-info-sign"></i> More Info</a></li>
|
||||
<li><a href="#" class="download_remove"><i class="icon-remove"></i> Remove</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse" class="download-detail">
|
||||
<td colspan="2">
|
||||
<div class="collapse more_info">
|
||||
<ul class="stats">
|
||||
<li class="label">Status: <span class="download-status">{{status}}</span></li>
|
||||
<li class="label">GID: <span class="download-gid">{{gid}}</span></li>
|
||||
<li class="label">Dir: <span class="download-dir">{{dir}}</span></li>
|
||||
<li class="label">Size: <span class="download-size">{{size}}</span></li>
|
||||
<li class="label">Downloaded: <span class="download-downloaded">{{downloaded}}</span></li>
|
||||
<li class="label">Num of Pieces: <span class="download-numPieces">{{numPieces}}</span></li>
|
||||
<li class="label">Piece Length: <span class="download-pieceLength">{{pieceLength}}</span></li>
|
||||
<li class="label">ETA: <span class="download-eta">{{eta}}</span></li>
|
||||
<li class="label">Down Speed: <span class="download-down_speed">{{down_speed}}</span></li>
|
||||
<li class="label">Upload Speed: <span class="download-upload_speed">{{upload_speed}}</span></li>
|
||||
<li class="label">Upload Length: <span class="download-uploadLength">{{uploadLength}}</span></li>
|
||||
<li class="label">Connections: <span class="download-connections">{{connections}}</span></li>
|
||||
</ul>
|
||||
|
||||
<h4 class="hidden-phone">Download Files</h4>
|
||||
<ul class="download-files hidden-phone">
|
||||
{{#files}}
|
||||
<li class="label">{{path}} ({{size}})</li>
|
||||
{{/files}}
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
<!-- waiting downloads template end }}}-->
|
||||
|
||||
<!--{{{ stopped downloads template-->
|
||||
<script type="text/mustache" id="download_stopped_template">
|
||||
<div class="row download_item download_stopped_item" data-gid="{{gid}}">
|
||||
<div class="span2 download_name">
|
||||
<b style="font-size: 12px;" class="tmp_name">{{name}}</b>
|
||||
<table class="stopped-download" data-gid="{{gid}}">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse" class="download-overview">
|
||||
<b class="download-name">{{name}}</b>
|
||||
|
||||
<ul class="stats hidden-phone pull-right">
|
||||
<li class="label label-success">Path: <span class="download-dir">{{dir}}</span></li>
|
||||
</ul>
|
||||
<div class="progress full-progress progress-striped active" style="width: 100%; margin: 0; padding: 0;">
|
||||
<div class="bar" style="width: {{percentage}}%;"></div>
|
||||
</div>
|
||||
<div class="span6">
|
||||
{{#booleans.is_error}}
|
||||
<span class="badge badge-important">Status: <span class="tmp_status">{{status}}</span></span>
|
||||
<div class="pull-right">
|
||||
<span class="label label-important">Size: <span class="tmp_size">{{size}}</span></span> |
|
||||
<span class="label label-important">Downloaded: <span class="tmp_downloaded">{{downloaded}}</span></span> |
|
||||
<span class="label label-important">Progress: <span class="tmp_percentage">{{percentage}}</span>%</span>
|
||||
</div>
|
||||
{{/booleans.is_error}}
|
||||
{{^booleans.is_error}}
|
||||
<span class="badge badge-info">Status: <span class="tmp_status">{{status}}</span></span>
|
||||
<div class="pull-right">
|
||||
<span class="label label-info">Size: <span class="tmp_size">{{size}}</span></span> |
|
||||
<span class="label label-info">Downloaded: <span class="tmp_downloaded">{{downloaded}}</span></span> |
|
||||
<span class="label label-info">Progress: <span class="tmp_percentage">{{percentage}}</span>%</span>
|
||||
</div>
|
||||
{{/booleans.is_error}}
|
||||
</div>
|
||||
<div class="span3">
|
||||
<div class="button_set">
|
||||
<button class="btn btn-mini download_restart"><i class="icon-repeat"></i> Restart</button>
|
||||
<button class="btn btn-mini btn-info" data-toggle="collapse" data-target="[data-gid={{gid}}] .more_info" onclick="$(this).button('toggle');"><i class="icon-info-sign"></i> More Info</button>
|
||||
<button class="btn btn-mini btn-danger download_remove"><i class="icon-fire"></i> Purge</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="span11 full-progress progress progress-striped">
|
||||
{{#booleans.is_error}}
|
||||
<div class="bar" style="width: {{percentage}}%; background-color:rgb(185, 74, 72)"></div>
|
||||
{{/booleans.is_error}}
|
||||
{{^booleans.is_error}}
|
||||
<div class="bar" style="width: {{percentage}}%; background-color:#3A87AD"></div>
|
||||
{{/booleans.is_error}}
|
||||
</div>
|
||||
<div class="span12 more_info collapse">
|
||||
<b class="span2 label active_settings">Status: <span class="tmp_status">{{status}}</span></b>
|
||||
<b class="span2 label active_settings">GID: <span class="tmp_gid">{{gid}}</span></b>
|
||||
<b class="span2 label active_settings">Dir: <span class="tmp_dir">{{dir}}</span></b>
|
||||
<b class="span2 label active_settings">Size: <span class="tmp_size">{{size}}</span></b>
|
||||
<b class="span2 label active_settings">Downloaded: <span class="tmp_downloaded">{{downloaded}}</span></b>
|
||||
<b class="span2 label active_settings">Num of Pieces: <span class="tmp_numPieces">{{numPieces}}</span></b>
|
||||
<b class="span2 label active_settings">Piece Length: <span class="tmp_pieceLength">{{pieceLength}}</span></b>
|
||||
<b class="span2 label active_settings">Upload Length: <span class="tmp_uploadLength">{{uploadLength}}</span></b>
|
||||
</td>
|
||||
<td class="download-controls">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-mini download_restart"><i class="icon-repeat"></i></button>
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
|
||||
<li><a href="#" data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse"><i class="icon-info-sign"></i> More Info</a></li>
|
||||
<li><a href="#" class="download_remove"><i class="icon-remove"></i> Remove</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-toggle="collapse" data-target="[data-gid={{gid}}] .download-detail .collapse" class="download-detail">
|
||||
<td colspan="2">
|
||||
<div class="collapse more_info">
|
||||
<ul class="stats">
|
||||
<li class="label">Status: <span class="download-status">{{status}}</span></li>
|
||||
<li class="label">GID: <span class="download-gid">{{gid}}</span></li>
|
||||
<li class="label">Dir: <span class="download-dir">{{dir}}</span></li>
|
||||
<li class="label">Size: <span class="download-size">{{size}}</span></li>
|
||||
<li class="label">Downloaded: <span class="download-downloaded">{{downloaded}}</span></li>
|
||||
<li class="label">Num of Pieces: <span class="download-numPieces">{{numPieces}}</span></li>
|
||||
<li class="label">Piece Length: <span class="download-pieceLength">{{pieceLength}}</span></li>
|
||||
<li class="label">ETA: <span class="download-eta">{{eta}}</span></li>
|
||||
<li class="label">Down Speed: <span class="download-down_speed">{{down_speed}}</span></li>
|
||||
<li class="label">Upload Speed: <span class="download-upload_speed">{{upload_speed}}</span></li>
|
||||
<li class="label">Upload Length: <span class="download-uploadLength">{{uploadLength}}</span></li>
|
||||
<li class="label">Connections: <span class="download-connections">{{connections}}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
<!-- stopped downloads template end }}}-->
|
||||
|
||||
|
@ -388,7 +357,7 @@
|
|||
</script>
|
||||
<!-- }}} -->
|
||||
|
||||
<!--{{{ download settings template start -->
|
||||
<!--{{{ download settings template -->
|
||||
<script type="text/mustache" id="download_settings_template">
|
||||
|
||||
<div class="modal-header">
|
||||
|
@ -456,7 +425,7 @@
|
|||
<button id="save_download_settings" class="btn btn-success">Save</button>
|
||||
</div>
|
||||
</script>
|
||||
<!-- download settings template end }}}-->
|
||||
<!-- download settings template }}}-->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
@ -535,66 +504,6 @@
|
|||
|
||||
<div role="main" class="container">
|
||||
<!-- Download items here -->
|
||||
<table class="active-download">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-toggle="collapse" data-target=".download-detail .collapse" class="download-overview">
|
||||
<b style="font-size: 12px;" class="tmp_name">Sample</b>
|
||||
|
||||
<ul class="stats pull-right">
|
||||
<li class="label label-success">Time left: <span class="tmp_eta">{{eta}}</span></li>
|
||||
</ul>
|
||||
<div class="progress full-progress progress-striped active" style="width: 100%; margin: 0; padding: 0;">
|
||||
<div class="bar" style="width: 100%;"></div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="download-controls">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-mini"><i class="icon-pause"></i></button>
|
||||
<button class="btn dropdown-toggle" data-toggle="dropdown">
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Remove</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr data-toggle="collapse" data-target=".download-detail .collapse" class="download-detail">
|
||||
<td colspan="2">
|
||||
<div class="collapse">
|
||||
<canvas class="progress chunk-canvas" width="1400" class="width: 100%;"></canvas>
|
||||
<ul class="stats">
|
||||
<li class="label">Status: <span class="tmp_status">{{status}}</span></li>
|
||||
<li class="label">GID: <span class="tmp_gid">{{gid}}</span></li>
|
||||
<li class="label">Dir: <span class="tmp_dir">{{dir}}</span></li>
|
||||
<li class="label">Size: <span class="tmp_size">{{size}}</span></li>
|
||||
<li class="label">Downloaded: <span class="tmp_downloaded">{{downloaded}}</span></li>
|
||||
<li class="label">Num of Pieces: <span class="tmp_numPieces">{{numPieces}}</span></li>
|
||||
<li class="label">Piece Length: <span class="tmp_pieceLength">{{pieceLength}}</span></li>
|
||||
<li class="label">ETA: <span class="tmp_eta">{{eta}}</span></li>
|
||||
<li class="label">Down Speed: <span class="tmp_down_speed">{{down_speed}}</span></li>
|
||||
<li class="label">Upload Speed: <span class="tmp_upload_speed">{{upload_speed}}</span></li>
|
||||
<li class="label">Upload Length: <span class="tmp_uploadLength">{{uploadLength}}</span></li>
|
||||
<li class="label">Connections: <span class="tmp_connections">{{connections}}</span></li>
|
||||
</ul>
|
||||
|
||||
<h4>Download Files</h4>
|
||||
<ul class="download-files">
|
||||
<li class="label">sample file (200 MB)</li>
|
||||
<li class="label">sample file (200 MB)</li>
|
||||
<li class="label">sample file (200 MB)</li>
|
||||
<li class="label">sample file (200 MB)</li>
|
||||
</ul>
|
||||
|
||||
<div style="background: black; width: 100%;">
|
||||
<div class="active_graph">h</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="active_downloads"></div>
|
||||
|
||||
|
|
40
js/ctrls/download.js
Normal file
40
js/ctrls/download.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
app.controller('DownloadCtrl', [ '$scope', '$rpc',
|
||||
function(scope, rpc) {
|
||||
rpc.configure({
|
||||
host: 'localhost',
|
||||
port: 6800
|
||||
});
|
||||
|
||||
scope.active = scope.waiting = scope.stopped = [];
|
||||
|
||||
|
||||
rpc.subscribe('tellActive', [], function(data) {
|
||||
scope.$apply(function() {
|
||||
scope.active = data[0];
|
||||
});
|
||||
});
|
||||
|
||||
rpc.subscribe('tellWaiting', [0, 100], function(data) {
|
||||
scope.$apply(function() {
|
||||
scope.waiting = data[0];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
rpc.subscribe('tellStopped', [0, 100], function(data) {
|
||||
scope.$apply(function() {
|
||||
scope.stopped = data[0];
|
||||
});
|
||||
});
|
||||
|
||||
scope.getDownloads = function() {
|
||||
var rets = scope.active
|
||||
.concat(scope.waiting).concat(scope.stopped);
|
||||
return rets;
|
||||
}
|
||||
|
||||
scope.normalize = function(d) {
|
||||
return "hello";
|
||||
}
|
||||
|
||||
}]);
|
3
js/ctrls/modal.js
Normal file
3
js/ctrls/modal.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
app.controller('ModalCtrl', ['$scope', function(scope) {
|
||||
|
||||
}]);
|
4
js/ctrls/nav.js
Normal file
4
js/ctrls/nav.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
app.controller('NavCtrl', ['$scope', '$name', function(scope, name) {
|
||||
scope.name = name;
|
||||
}]);
|
3
js/init.js
Normal file
3
js/init.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
$(function() {
|
||||
angular.bootstrap(document, ['app'])
|
||||
});
|
14531
js/libs/angular.js
vendored
Executable file
14531
js/libs/angular.js
vendored
Executable file
File diff suppressed because it is too large
Load Diff
60
js/script.js
60
js/script.js
|
@ -398,10 +398,24 @@ function getTemplateCtx(data) {
|
|||
}
|
||||
function updateDownloadTemplates(elem, ctx) {
|
||||
elem = $(elem);
|
||||
|
||||
// update spans
|
||||
for(var i in ctx) {
|
||||
elem.find('.tmp_' + i).text(ctx[i]);
|
||||
elem.find('.download-' + i).text(ctx[i]);
|
||||
}
|
||||
|
||||
// update files
|
||||
var html = '';
|
||||
for (var i = 0; i < ctx.files.length; i++) {
|
||||
html += '<li class="label">' + ctx.files[i].path + ' (' + ctx.files[i].size + ')</li>';
|
||||
}
|
||||
elem.find('.download-files').html(html);
|
||||
console.log(html);
|
||||
|
||||
// update progress bar
|
||||
elem.find('.full-progress .bar').css('width', ctx.percentage + '%');
|
||||
|
||||
// update the chunks bar
|
||||
var chunks = ctx.chunks;
|
||||
if (!chunks || !chunks.length) {
|
||||
return;
|
||||
|
@ -457,7 +471,7 @@ function refreshDownloadTemplates(top_elem, data) {
|
|||
deleteDownloadTemplates($top_elem, data);
|
||||
for(var i = 0; i < data.length; i++) {
|
||||
var ctx = getTemplateCtx(data[i]);
|
||||
var elem = $top_elem.find('div.download_item[data-gid=' + ctx.gid + ']');
|
||||
var elem = $top_elem.find('[data-gid=' + ctx.gid + ']');
|
||||
if(elem.length) {
|
||||
updateDownloadTemplates(elem, ctx);
|
||||
} else {
|
||||
|
@ -635,9 +649,9 @@ function updateActiveDownloads(data) {
|
|||
refreshDownloadTemplates('active', data);
|
||||
updateGraphData(data);
|
||||
empty_download_set('#active_downloads');
|
||||
$('.download_active_item .download_settings').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_active_item').attr('data-gid');
|
||||
var settings_name = $(this).parents('.download_active_item').attr('data-settingsName');
|
||||
$('.active-download .download_settings').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.active-download').attr('data-gid');
|
||||
var settings_name = $(this).parents('.active-download').attr('data-settingsName');
|
||||
var gen = function(name) {
|
||||
return { name: name, values: [] };
|
||||
};
|
||||
|
@ -694,8 +708,8 @@ function updateActiveDownloads(data) {
|
|||
});
|
||||
});
|
||||
});
|
||||
$('.download_active_item .download_pause').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_active_item').attr('data-gid');
|
||||
$('.active-download .download_pause').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.active-download').attr('data-gid');
|
||||
aria_syscall({
|
||||
func: 'forcePause',
|
||||
params: [gid],
|
||||
|
@ -708,9 +722,9 @@ function updateActiveDownloads(data) {
|
|||
}
|
||||
});
|
||||
});
|
||||
$('.download_active_item .torrent_info').unbind('click').click(function() {
|
||||
var info_name = $(this).parents('.download_active_item').attr('data-settingsName');
|
||||
var gid = $(this).parents('.download_active_item').attr('data-gid');
|
||||
$('.active-download .torrent_info').unbind('click').click(function() {
|
||||
var info_name = $(this).parents('.active-download').attr('data-settingsName');
|
||||
var gid = $(this).parents('.active-download').attr('data-gid');
|
||||
aria_syscall({
|
||||
func: 'getPeers',
|
||||
params: [gid],
|
||||
|
@ -740,8 +754,8 @@ function updateActiveDownloads(data) {
|
|||
}
|
||||
});
|
||||
});
|
||||
$('.download_active_item .download_remove').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_active_item').attr('data-gid');
|
||||
$('.active-download .download_remove').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.active-download').attr('data-gid');
|
||||
aria_syscall({
|
||||
func: 'remove',
|
||||
params: [gid],
|
||||
|
@ -757,9 +771,9 @@ function updateActiveDownloads(data) {
|
|||
}
|
||||
function updateWaitingDownloads(data) {
|
||||
refreshDownloadTemplates('waiting', data);
|
||||
$('.download_waiting_item .download_settings').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_waiting_item').attr('data-gid');
|
||||
var settings_name = $(this).parents('.download_waiting_item').attr('data-settingsName');
|
||||
$('.waiting-download .download_settings').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.waiting-download').attr('data-gid');
|
||||
var settings_name = $(this).parents('.waiting-download').attr('data-settingsName');
|
||||
var gen = function(name) {
|
||||
return { name: name, values: [] };
|
||||
};
|
||||
|
@ -830,8 +844,8 @@ function updateWaitingDownloads(data) {
|
|||
});
|
||||
});
|
||||
});
|
||||
$('.download_waiting_item .download_play').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_waiting_item').attr('data-gid');
|
||||
$('.waiting-download .download_play').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.waiting-download').attr('data-gid');
|
||||
aria_syscall({
|
||||
func: 'unpause',
|
||||
params: [gid],
|
||||
|
@ -844,8 +858,8 @@ function updateWaitingDownloads(data) {
|
|||
}
|
||||
});
|
||||
});
|
||||
$('.download_waiting_item .download_remove').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_waiting_item').attr('data-gid');
|
||||
$('.waiting-download .download_remove').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.waiting-download').attr('data-gid');
|
||||
aria_syscall({
|
||||
func: 'remove',
|
||||
params: [gid],
|
||||
|
@ -862,8 +876,8 @@ function updateWaitingDownloads(data) {
|
|||
|
||||
function updateStoppedDownloads(data) {
|
||||
refreshDownloadTemplates('stopped', data);
|
||||
$('.download_stopped_item .download_remove').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_stopped_item').attr('data-gid');
|
||||
$('.stopped-download .download_remove').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.stopped-download').attr('data-gid');
|
||||
aria_syscall({
|
||||
func: 'removeDownloadResult',
|
||||
params: [gid],
|
||||
|
@ -876,8 +890,8 @@ function updateStoppedDownloads(data) {
|
|||
}
|
||||
});
|
||||
});
|
||||
$('.download_stopped_item .download_restart').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.download_stopped_item').attr('data-gid');
|
||||
$('.stopped-download .download_restart').unbind('click').click(function() {
|
||||
var gid = $(this).parents('.stopped-download').attr('data-gid');
|
||||
var files;
|
||||
var uris = [];
|
||||
for(var i = 0; i < d_files.stopped.length; i++) {
|
||||
|
|
56
js/services/base64.js
Normal file
56
js/services/base64.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
app.factory('$base64', [function() {
|
||||
var obj = {};
|
||||
var a64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||||
a256 = {
|
||||
indexOf: function (c) {
|
||||
return c.charCodeAt(0);
|
||||
},
|
||||
charAt: String.fromCharCode
|
||||
};
|
||||
|
||||
function code(s, discard, alpha, beta, w1, w2) {
|
||||
s = String(s);
|
||||
var b = 0, x = '', i, c, bs = 1, sb = 1, length = s.length, tmp;
|
||||
for (i = 0; i < length || (!discard && sb > 1); i += 1) {
|
||||
b *= w1;
|
||||
bs *= w1;
|
||||
if (i < length) {
|
||||
c = alpha.indexOf(s.charAt(i));
|
||||
if (c <= -1 || c >= w1) {
|
||||
throw new RangeError();
|
||||
}
|
||||
sb *= w1;
|
||||
b += c;
|
||||
}
|
||||
while (bs >= w2) {
|
||||
bs /= w2;
|
||||
if (sb > 1) {
|
||||
tmp = b;
|
||||
b %= bs;
|
||||
x += beta.charAt((tmp - b) / bs);
|
||||
sb /= w2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
obj.btoa = function (s) {
|
||||
s = code(s, false, a256, a64, 256, 64);
|
||||
return s + '===='.slice((s.length % 4) || 4);
|
||||
};
|
||||
|
||||
obj.atob = function (s) {
|
||||
var i;
|
||||
s = String(s).split('=');
|
||||
for (i = s.length - 1; i >= 0; i -= 1) {
|
||||
if (s[i].length % 4 === 1) {
|
||||
throw new RangeError();
|
||||
}
|
||||
s[i] = code(s[i], true, a64, a256, 64, 256);
|
||||
}
|
||||
return s.join('');
|
||||
};
|
||||
|
||||
return obj;
|
||||
}]);
|
6
js/services/deps.js
Normal file
6
js/services/deps.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
app.constant('$name', 'webui-aria2');
|
||||
app.constant('$globalTimeout', 1000);
|
||||
|
||||
app.value('$', $);
|
||||
app.value('$_', _);
|
||||
app.value('$json', JSON);
|
73
js/services/rpc/jsoncall.js
Normal file
73
js/services/rpc/jsoncall.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
app.factory('$jsoncall', ['$', '$json', '$base64', function($, JSON, base64) {
|
||||
return {
|
||||
init: function(conf) {
|
||||
this.avgTimeout = 2000;
|
||||
this.serverConf = conf;
|
||||
},
|
||||
encode: function(obj) {
|
||||
return base64.btoa( JSON.stringify(obj) );
|
||||
},
|
||||
ariaRequest: function(url, funcName, params, success, error) {
|
||||
var startTime = new Date();
|
||||
var conn = this;
|
||||
$.ajax({
|
||||
url: url,
|
||||
timeout: this.avgTimeout,
|
||||
data: {
|
||||
jsonrpc: 2.0,
|
||||
id: 'webui',
|
||||
method: funcName,
|
||||
params: params && params.length ? this.encode(params) : undefined
|
||||
},
|
||||
success: function(data) {
|
||||
conn.avgTimeout = 3 * (new Date() - startTime);
|
||||
return success(data)
|
||||
},
|
||||
error: error,
|
||||
dataType: 'jsonp',
|
||||
jsonp: 'jsoncallback'
|
||||
});
|
||||
},
|
||||
invoke: function(opts) {
|
||||
var rpc = this;
|
||||
var scheme = rpc.serverConf.encryption ? 'https' : 'http';
|
||||
rpc.ariaRequest(
|
||||
scheme + '://' + rpc.serverConf.host + ':' + rpc.serverConf.port + '/jsonrpc',
|
||||
opts.name,
|
||||
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.auth) {
|
||||
console.log("no user name and still error!!!");
|
||||
return opts.error();
|
||||
}
|
||||
|
||||
var authUrl = scheme + '://' +
|
||||
rpc.serverConf.auth.user + ":" +
|
||||
rpc.serverConf.auth.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 = $('<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.params,
|
||||
opts.success,
|
||||
opts.error
|
||||
);
|
||||
}, rpc.avgTimeout);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}]);
|
111
js/services/rpc/rpc.js
Normal file
111
js/services/rpc/rpc.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
app.factory('$rpc', ['$syscall', '$globalTimeout', function(syscall, time) {
|
||||
var subscriptions = [],
|
||||
timeout = null,
|
||||
forceNextUpdate = false;
|
||||
|
||||
syscall.init({
|
||||
host: 'localhost',
|
||||
port: 6800
|
||||
});
|
||||
|
||||
// update is implemented such that
|
||||
// only one syscall at max is ongoing
|
||||
// (i.e. serially) so should be private
|
||||
// to maintain that invariant
|
||||
var update = function() {
|
||||
if (!subscriptions.length) return;
|
||||
|
||||
subscriptions = _.filter(subscriptions, function(e) { return !!e });
|
||||
var params = _.map(subscriptions, function(s) {
|
||||
return {
|
||||
methodName: s.name,
|
||||
params: s.params && s.params.length ? s.params : undefined
|
||||
};
|
||||
});
|
||||
|
||||
syscall.invoke({
|
||||
name: 'system.multicall',
|
||||
params: [params],
|
||||
success: function(data) {
|
||||
_.each(data.result, function(d, i) {
|
||||
var handle = subscriptions[i];
|
||||
if (handle) {
|
||||
handle.cb(d);
|
||||
if (handle.once) {
|
||||
subscriptions[i] = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (forceNextUpdate) {
|
||||
forceNextUpdate = false;
|
||||
return update();
|
||||
}
|
||||
timeout = setTimeout(update, time);
|
||||
},
|
||||
error: function() {
|
||||
// TODO: implement a retry error handler
|
||||
// which would also look for other suitable
|
||||
// connection configurations for the connection
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
// change the connection configuration,
|
||||
// for all options read rpc/syscall.js
|
||||
configure: function(conf) {
|
||||
syscall.init(conf);
|
||||
},
|
||||
// syscall is done only once
|
||||
once: function(name, params, cb) {
|
||||
subscriptions.push({
|
||||
once: true,
|
||||
name: 'aria2.' + name,
|
||||
params: params,
|
||||
cb: cb
|
||||
});
|
||||
|
||||
this.forceUpdate();
|
||||
},
|
||||
|
||||
// callback is called each time with updated syscall data
|
||||
// after the global timeout
|
||||
subscribe: function(name, params, cb) {
|
||||
var handle = {
|
||||
once: false,
|
||||
name: 'aria2.' + name,
|
||||
params: params,
|
||||
cb: cb
|
||||
};
|
||||
subscriptions.push(handle);
|
||||
|
||||
this.forceUpdate();
|
||||
|
||||
return handle;
|
||||
},
|
||||
|
||||
// remove the subscribed callback by passing
|
||||
// the returned handle bysubscribe
|
||||
unsubscribe: function(handle) {
|
||||
var ind = subscriptions.indexOf(handle);
|
||||
subscriptions[ind] = null;
|
||||
},
|
||||
|
||||
// force the global syscall update
|
||||
forceUpdate: function() {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
update();
|
||||
}
|
||||
else if (subscriptions.length) {
|
||||
update();
|
||||
}
|
||||
else {
|
||||
// a batch call is already in progress,
|
||||
// wait till it returns and force the next one
|
||||
forceNextUpdate = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
}]);
|
88
js/services/rpc/sockcall.js
Normal file
88
js/services/rpc/sockcall.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
app.factory('$sockcall', ['$_', '$json', '$name', '$utils', function(_, JSON, name, utils) {
|
||||
return {
|
||||
// true when sockrpc is ready to be used,
|
||||
// false when either initializing
|
||||
// or no support for web sockets
|
||||
initialized: false,
|
||||
|
||||
// ongoing connection handles containing connection id and callbacks
|
||||
handles: [],
|
||||
|
||||
// websocket connection socket used for all connections
|
||||
sock: null,
|
||||
|
||||
// connection configuration
|
||||
conf: null,
|
||||
|
||||
// socket connection scheme, default to unencrypted connection
|
||||
scheme: 'ws',
|
||||
|
||||
// called when a connection error occurs
|
||||
onerror: function() {
|
||||
_.each(this.handles, function(h) { h.error() });
|
||||
this.handles = [];
|
||||
},
|
||||
|
||||
// when connection opens
|
||||
onopen: function() {
|
||||
this.initialized = true;
|
||||
},
|
||||
|
||||
|
||||
// when message is recieved
|
||||
onmessage: function(message) {
|
||||
var data = JSON.parse(message.data);
|
||||
|
||||
// reverse loop because we are deleting elements
|
||||
// while looping over the old items
|
||||
for (var i = this.handles.length - 1; i >= 0; i--) {
|
||||
if (this.handles[i].id === data.id) {
|
||||
this.handles[i].success(data);
|
||||
this.handles.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// call to use the rpc
|
||||
invoke: function(opts) {
|
||||
var data = {
|
||||
jsonrpc: 2.0,
|
||||
id: name + '_' + utils.randStr(),
|
||||
method: opts.func,
|
||||
params: opts.params && opts.params.length ? opts.params : undefined
|
||||
};
|
||||
|
||||
if (data.params && !data.params.length) data.params = undefined;
|
||||
|
||||
this.handles.push({
|
||||
success: opts.success || angular.noop,
|
||||
error: opts.error || angular.noop,
|
||||
id: data.id
|
||||
});
|
||||
this.sock.send( JSON.stringify(data) );
|
||||
},
|
||||
|
||||
// should be called initially to start using the sock rpc
|
||||
init: function(conf) {
|
||||
if (typeof WebSocket == "undefined") {
|
||||
return;
|
||||
}
|
||||
this.conf = conf || this.conf;
|
||||
this.initialized = false;
|
||||
|
||||
this.scheme = this.conf.encryption ? 'wss' : 'ws';
|
||||
|
||||
if (this.sock) {
|
||||
this.onopen = this.sock.onmessage = this.sock.onerror = this.sock.onclose = null;
|
||||
this.onerror();
|
||||
}
|
||||
|
||||
this.sock = new WebSocket(this.scheme + '://' + conf.host + ':' + conf.port + '/jsonrpc');
|
||||
this.sock.onopen = this.onopen;
|
||||
this.sock.onclose = this.sock.onerror = this.onerror;
|
||||
this.sock.onmessage = this.onmessage;
|
||||
},
|
||||
};
|
||||
}]);
|
||||
|
43
js/services/rpc/syscall.js
Normal file
43
js/services/rpc/syscall.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
app.factory('$syscall', ['$log', '$jsoncall', '$sockcall', function(log, jsonRPC, sockRPC) {
|
||||
return {
|
||||
// called to initialize the rpc interface, call everytime configuration changes
|
||||
// conf has the following structure:
|
||||
// {
|
||||
// host (string): host for the aria2 server
|
||||
// port (number): port number for the aria2 server
|
||||
// encryption (boolean, optional): true if encryption is enabled in the aria2 server
|
||||
// auth (optional): {
|
||||
// user (string): username for http authentication if enabled
|
||||
// pass (string): password for the http authentication if enabled
|
||||
// }
|
||||
init: function(conf) {
|
||||
conf = conf || {
|
||||
host: 'localhost',
|
||||
port: 6800
|
||||
};
|
||||
conf.encryption = conf.encryption || false;
|
||||
|
||||
jsonRPC.init(conf);
|
||||
sockRPC.init(conf);
|
||||
},
|
||||
|
||||
// call this to start an rpc call, opts has the following structure:
|
||||
// {
|
||||
// name (string): name of the actual aria2 syscall
|
||||
// success (function): callback called with (parsed) data if rpc is successfull
|
||||
// error (function): callback called when an error occurs
|
||||
// params (array, optional): the params for some syscall (like multicall) and is optional for others
|
||||
// }
|
||||
invoke: function(opts) {
|
||||
opts.success = opts.success || angular.noop;
|
||||
opts.error = opts.error || angular.noop;
|
||||
|
||||
if (sockRPC.initialized)
|
||||
return sockRPC.invoke(opts);
|
||||
else
|
||||
return jsonRPC.invoke(opts);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
|
20
js/services/utils.js
Normal file
20
js/services/utils.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
app.factory('$utils', function() {
|
||||
return {
|
||||
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;
|
||||
}
|
||||
};
|
||||
});
|
Loading…
Reference in New Issue
Block a user