├── .gitignore ├── CNAME ├── README.md ├── archiver ├── aria2.conf └── aria2.zip ├── css ├── bootstrap-responsive.min.css ├── bootstrap.min.css └── main.css ├── favicon.ico ├── img ├── glyphicons-halflings-white.png └── glyphicons-halflings.png ├── index.html ├── js ├── aria2.js ├── bootstrap.min.js ├── jquery-1.7.2.min.js ├── jquery.Storage.min.js ├── jquery.base64.min.js ├── jquery.jsonrpc.js ├── jquery.jsonrpc.min.js ├── mustache.min.js ├── peerid.js ├── peerid.min.js └── yaaw.js ├── offline.appcache └── usage.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmp.* 2 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | aria2c.com -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | YAAW-zh-Hans 2 | ---- 3 | 4 | 汉化过的 [YAAW](https://github.com/binux/yaaw) 并修复了一些小BUG 5 | 6 | 访问地址 [aria2c.com](http://aria2c.com/) 7 | 8 | latest commit 26cb28c0c85920f102154b425633e256169abb17 9 | -------------------------------------------------------------------------------- /archiver/aria2.conf: -------------------------------------------------------------------------------- 1 | ## '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ## 2 | ## 被注释的选项填写的是默认值, 建议在需要修改时再取消注释 ## 3 | 4 | ## 文件保存相关 ## 5 | 6 | # 文件的保存路径(可使用绝对路径或相对路径), 默认: 当前启动位置 7 | dir=~/downloads 8 | # 启用磁盘缓存, 0为禁用缓存, 需1.16以上版本, 默认:16M 9 | #disk-cache=32M 10 | # 文件预分配方式, 能有效降低磁盘碎片, 默认:prealloc 11 | # 预分配所需时间: none < falloc ? trunc < prealloc 12 | # falloc和trunc则需要文件系统和内核支持 13 | # NTFS建议使用falloc, EXT3/4建议trunc, MAC 下需要注释此项 14 | #file-allocation=none 15 | # 断点续传 16 | continue=true 17 | 18 | ## 下载连接相关 ## 19 | 20 | # 最大同时下载任务数, 运行时可修改, 默认:5 21 | #max-concurrent-downloads=5 22 | # 同一服务器连接数, 添加时可指定, 默认:1 23 | max-connection-per-server=5 24 | # 最小文件分片大小, 添加时可指定, 取值范围1M -1024M, 默认:20M 25 | # 假定size=10M, 文件为20MiB 则使用两个来源下载; 文件为15MiB 则使用一个来源下载 26 | min-split-size=10M 27 | # 单个任务最大线程数, 添加时可指定, 默认:5 28 | #split=5 29 | # 整体下载速度限制, 运行时可修改, 默认:0 30 | #max-overall-download-limit=0 31 | # 单个任务下载速度限制, 默认:0 32 | #max-download-limit=0 33 | # 整体上传速度限制, 运行时可修改, 默认:0 34 | #max-overall-upload-limit=0 35 | # 单个任务上传速度限制, 默认:0 36 | #max-upload-limit=0 37 | # 禁用IPv6, 默认:false 38 | #disable-ipv6=true 39 | # 连接超时时间, 默认:60 40 | #timeout=60 41 | # 最大重试次数, 设置为0表示不限制重试次数, 默认:5 42 | #max-tries=5 43 | # 设置重试等待的秒数, 默认:0 44 | #retry-wait=0 45 | 46 | ## 进度保存相关 ## 47 | 48 | # 从会话文件中读取下载任务 49 | input-file=/etc/aria2/aria2.session 50 | # 在Aria2退出时保存`错误/未完成`的下载任务到会话文件 51 | save-session=/etc/aria2/aria2.session 52 | # 定时保存会话, 0为退出时才保存, 需1.16.1以上版本, 默认:0 53 | #save-session-interval=60 54 | 55 | ## RPC相关设置 ## 56 | 57 | # 启用RPC, 默认:false 58 | enable-rpc=true 59 | # 允许所有来源, 默认:false 60 | rpc-allow-origin-all=true 61 | # 允许非外部访问, 默认:false 62 | rpc-listen-all=true 63 | # 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同 64 | #event-poll=select 65 | # RPC监听端口, 端口被占用时可以修改, 默认:6800 66 | #rpc-listen-port=6800 67 | # 设置的RPC授权令牌, v1.18.4新增功能, 取代 --rpc-user 和 --rpc-passwd 选项 68 | #rpc-secret= 69 | # 设置的RPC访问用户名, 此选项新版已废弃, 建议改用 --rpc-secret 选项 70 | #rpc-user= 71 | # 设置的RPC访问密码, 此选项新版已废弃, 建议改用 --rpc-secret 选项 72 | #rpc-passwd= 73 | # 是否启用 RPC 服务的 SSL/TLS 加密, 74 | # 启用加密后 RPC 服务需要使用 https 或者 wss 协议连接 75 | #rpc-secure=true 76 | # 在 RPC 服务中启用 SSL/TLS 加密时的证书文件, 77 | # 使用 PEM 格式时,您必须通过 --rpc-private-key 指定私钥 78 | #rpc-certificate=/path/to/certificate.pem 79 | # 在 RPC 服务中启用 SSL/TLS 加密时的私钥文件 80 | #rpc-private-key=/path/to/certificate.key 81 | 82 | ## BT/PT下载相关 ## 83 | 84 | # 当下载的是一个种子(以.torrent结尾)时, 自动开始BT任务, 默认:true 85 | #follow-torrent=true 86 | # BT监听端口, 当端口被屏蔽时使用, 默认:6881-6999 87 | listen-port=51413 88 | # 单个种子最大连接数, 默认:55 89 | #bt-max-peers=55 90 | # 打开DHT功能, PT需要禁用, 默认:true 91 | enable-dht=false 92 | # 打开IPv6 DHT功能, PT需要禁用 93 | #enable-dht6=false 94 | # DHT网络监听端口, 默认:6881-6999 95 | #dht-listen-port=6881-6999 96 | # 本地节点查找, PT需要禁用, 默认:false 97 | #bt-enable-lpd=false 98 | # 种子交换, PT需要禁用, 默认:true 99 | enable-peer-exchange=false 100 | # 每个种子限速, 对少种的PT很有用, 默认:50K 101 | #bt-request-peer-speed-limit=50K 102 | # 客户端伪装, PT需要 103 | peer-id-prefix=-TR2770- 104 | user-agent=Transmission/2.77 105 | peer-agent=Transmission/2.77 106 | # 当种子的分享率达到这个数时, 自动停止做种, 0为一直做种, 默认:1.0 107 | seed-ratio=0 108 | # 强制保存会话, 即使任务已经完成, 默认:false 109 | # 较新的版本开启后会在任务完成后依然保留.aria2文件 110 | #force-save=false 111 | # BT校验相关, 默认:true 112 | #bt-hash-check-seed=true 113 | # 继续之前的BT任务时, 无需再次校验, 默认:false 114 | bt-seed-unverified=true 115 | # 保存磁力链接元数据为种子文件(.torrent文件), 默认:false 116 | bt-save-metadata=true 117 | -------------------------------------------------------------------------------- /archiver/aria2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aa65535/yaaw-zh-hans/502914c66ffccec68f9d510973ea156055d9ad6c/archiver/aria2.zip -------------------------------------------------------------------------------- /css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.0.3 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}@media(max-width:767px){.visible-phone{display:inherit!important}.hidden-phone{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(min-width:768px) and (max-width:979px){.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:18px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-group>label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.modal{position:absolute;top:10px;right:10px;left:10px;width:auto;margin:0}.modal.fade.in{top:auto}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:auto;margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:20px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.762430939%;*margin-left:2.709239449638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:99.999999993%;*width:99.9468085036383%}.row-fluid .span11{width:91.436464082%;*width:91.38327259263829%}.row-fluid .span10{width:82.87292817100001%;*width:82.8197366816383%}.row-fluid .span9{width:74.30939226%;*width:74.25620077063829%}.row-fluid .span8{width:65.74585634900001%;*width:65.6926648596383%}.row-fluid .span7{width:57.182320438000005%;*width:57.129128948638304%}.row-fluid .span6{width:48.618784527%;*width:48.5655930376383%}.row-fluid .span5{width:40.055248616%;*width:40.0020571266383%}.row-fluid .span4{width:31.491712705%;*width:31.4385212156383%}.row-fluid .span3{width:22.928176794%;*width:22.874985304638297%}.row-fluid .span2{width:14.364640883%;*width:14.311449393638298%}.row-fluid .span1{width:5.801104972%;*width:5.747913482638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:714px}input.span11,textarea.span11,.uneditable-input.span11{width:652px}input.span10,textarea.span10,.uneditable-input.span10{width:590px}input.span9,textarea.span9,.uneditable-input.span9{width:528px}input.span8,textarea.span8,.uneditable-input.span8{width:466px}input.span7,textarea.span7,.uneditable-input.span7{width:404px}input.span6,textarea.span6,.uneditable-input.span6{width:342px}input.span5,textarea.span5,.uneditable-input.span5{width:280px}input.span4,textarea.span4,.uneditable-input.span4{width:218px}input.span3,textarea.span3,.uneditable-input.span3{width:156px}input.span2,textarea.span2,.uneditable-input.span2{width:94px}input.span1,textarea.span1,.uneditable-input.span1{width:32px}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;content:""}.row:after{clear:both}[class*="span"]{float:left;margin-left:30px}.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:28px;margin-left:2.564102564%;*margin-left:2.510911074638298%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145300001%;*width:91.3997999636383%}.row-fluid .span10{width:82.905982906%;*width:82.8527914166383%}.row-fluid .span9{width:74.358974359%;*width:74.30578286963829%}.row-fluid .span8{width:65.81196581200001%;*width:65.7587743226383%}.row-fluid .span7{width:57.264957265%;*width:57.2117657756383%}.row-fluid .span6{width:48.717948718%;*width:48.6647572286383%}.row-fluid .span5{width:40.170940171000005%;*width:40.117748681638304%}.row-fluid .span4{width:31.623931624%;*width:31.5707401346383%}.row-fluid .span3{width:23.076923077%;*width:23.0237315876383%}.row-fluid .span2{width:14.529914530000001%;*width:14.4767230406383%}.row-fluid .span1{width:5.982905983%;*width:5.929714493638298%}input,textarea,.uneditable-input{margin-left:0}input.span12,textarea.span12,.uneditable-input.span12{width:1160px}input.span11,textarea.span11,.uneditable-input.span11{width:1060px}input.span10,textarea.span10,.uneditable-input.span10{width:960px}input.span9,textarea.span9,.uneditable-input.span9{width:860px}input.span8,textarea.span8,.uneditable-input.span8{width:760px}input.span7,textarea.span7,.uneditable-input.span7{width:660px}input.span6,textarea.span6,.uneditable-input.span6{width:560px}input.span5,textarea.span5,.uneditable-input.span5{width:460px}input.span4,textarea.span4,.uneditable-input.span4{width:360px}input.span3,textarea.span3,.uneditable-input.span3{width:260px}input.span2,textarea.span2,.uneditable-input.span2{width:160px}input.span1,textarea.span1,.uneditable-input.span1{width:60px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top{position:static;margin-bottom:18px}.navbar-fixed-top .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 9px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#999;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:6px 15px;font-weight:bold;color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#222}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:block;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:9px 15px;margin:9px 0;border-top:1px solid #222;border-bottom:1px solid #222;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Binux 3 | * 4 | * This file is part of YAAW (https://github.com/binux/yaaw). 5 | * 6 | * YAAW is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation, either version 3 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * YAAW is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You may get a copy of the GNU Lesser General Public License 17 | * from http://www.gnu.org/licenses/lgpl.txt 18 | * 19 | */ 20 | 21 | .select-box { 22 | cursor: pointer; 23 | user-select: none; 24 | -moz-user-select: none; 25 | } 26 | .btn-inline { 27 | /* fix for MAC/chrome */ 28 | display: inline !important; 29 | } 30 | .btn-inline:before, .btn-inline:after { 31 | /* fix for IE8 */ 32 | content: none !important; 33 | display: none !important; 34 | } 35 | 36 | /* header */ 37 | .main-head { 38 | position: relative; 39 | } 40 | .main-head h1 { 41 | display: inline-block; 42 | } 43 | 44 | #main-alert { 45 | position: absolute; 46 | left: 0; 47 | width: 100%; 48 | text-align: center; 49 | } 50 | #main-alert-inline { 51 | display: inline-block; 52 | text-align: left; 53 | position: relative; 54 | top: -10px; 55 | z-index: 99; 56 | } 57 | 58 | #global-info { 59 | position: absolute; 60 | bottom: 0; 61 | right: 0; 62 | } 63 | #global-version { 64 | text-align: right; 65 | } 66 | 67 | /* main-control */ 68 | #main-control { 69 | margin-top: 10px; 70 | } 71 | 72 | #select-btn { 73 | margin-right: 30px; 74 | } 75 | .select-box { 76 | display: inline-block; 77 | vertical-align: text-top; 78 | border: 1px solid #C6C6C6; 79 | border: 1px solid rgba(155, 155, 155, .57); 80 | width: 14px; 81 | height: 14px; 82 | line-height: 14px; 83 | } 84 | 85 | #do-all-btn { 86 | position: relative; 87 | margin-left: 10px; 88 | } 89 | 90 | #info-btn { 91 | margin-left: 10px; 92 | } 93 | 94 | #other-grp { 95 | } 96 | 97 | /* active-tasks */ 98 | #active-tasks { 99 | margin-top: 40px; 100 | } 101 | .empty-tasks { 102 | text-align: center; 103 | padding: 8px; 104 | } 105 | .section-header { 106 | font-size: 16px; 107 | } 108 | .section-header i { 109 | margin-right: 5px; 110 | vertical-align: baseline; 111 | } 112 | 113 | /* other-tasks */ 114 | #other-tasks { 115 | margin-top: 40px; 116 | } 117 | #waiting-tasks-table { 118 | margin-bottom: 0; 119 | } 120 | #stopped-tasks-table { 121 | border-top: 0; 122 | margin-top: 0; 123 | } 124 | 125 | /* tasks */ 126 | .tasks-table { 127 | margin: 0; 128 | margin-top: 10px; 129 | } 130 | 131 | .task.selected { 132 | background-color: #F9F9F9; 133 | } 134 | .tasks-table > li { 135 | display: block; 136 | position: relative; 137 | margin-top: -1px; 138 | border-top: 1px solid #DDD; 139 | border-bottom: 1px solid #DDD; 140 | line-height: 18px; 141 | text-align: left; 142 | vertical-align: top; 143 | } 144 | .tasks-table > li:hover { 145 | background-color: #f5f5f5; 146 | } 147 | 148 | .left-area { 149 | position: relative; 150 | padding: 8px; 151 | } 152 | .right-area { 153 | position: absolute; 154 | top: 0; 155 | right: 0; 156 | padding: 8px; 157 | } 158 | 159 | .task .task-name { 160 | cursor: pointer; 161 | overflow: hidden; 162 | text-overflow: ellipsis; 163 | white-space: nowrap; 164 | } 165 | .task .task-name span { 166 | word-break: break-all; 167 | margin-left: 3px; 168 | font-size: 14px; 169 | font-weight: bold; 170 | } 171 | 172 | .task .task-name .select-box { 173 | vertical-align: -15%; 174 | } 175 | .task:hover .select-box { 176 | border-color: #666; 177 | } 178 | 179 | .task .task-info span { 180 | margin-right: 8px; 181 | } 182 | 183 | .task .task-info, 184 | .task .progress-info { 185 | margin-top: 4px; 186 | } 187 | .task .progress { 188 | margin: 1px 0; 189 | } 190 | 191 | .task .download-speed, 192 | .task .upload-speed, 193 | .task .seeders { 194 | margin-right: 5px; 195 | } 196 | 197 | #other-tasks .task-info { 198 | margin: 0; 199 | overflow: hidden; 200 | white-space: nowrap; 201 | } 202 | 203 | @media (max-height: 600px) { 204 | .modal.fade.in { 205 | position: absolute; 206 | top: 260px; 207 | } 208 | } 209 | 210 | @media (max-width: 550px) { 211 | .modal.fade.in { 212 | top: 60px; 213 | } 214 | .modal-body { 215 | max-height: none; 216 | } 217 | 218 | #main-alert { 219 | top: 25px; 220 | } 221 | 222 | #offline-cached { 223 | display: none; 224 | } 225 | 226 | #select-btn { 227 | margin-right: 10px; 228 | } 229 | #not-selected-grp { 230 | float: right; 231 | } 232 | #selected-grp { 233 | float: right; 234 | } 235 | #other-grp { 236 | clear: both; 237 | margin-top: 5px; 238 | } 239 | 240 | #active-tasks { 241 | margin-top: 20px; 242 | } 243 | #active-tasks .left-area { 244 | padding-bottom: 0; 245 | margin-right: 0; 246 | } 247 | .task .task-name { 248 | margin-right: 0; 249 | overflow: visible; 250 | white-space: normal; 251 | } 252 | #active-tasks .right-area { 253 | padding-top: 0; 254 | position: relative; 255 | width: auto; 256 | } 257 | #other-tasks .left-area { 258 | margin-right: 0; 259 | } 260 | #other-tasks .right-area { 261 | position: relative; 262 | padding-top: 0; 263 | } 264 | #other-tasks .right-area .task-info { 265 | position: absolute; 266 | top: 0; 267 | left: 0; 268 | } 269 | #other-tasks .right-area .pull-right { 270 | width: 100%; 271 | } 272 | #other-tasks .right-area .pull-right .progress { 273 | margin-left: 110px; 274 | } 275 | } 276 | @media (min-width: 551px) and (max-width: 980px) { 277 | #active-tasks .left-area { 278 | margin-right: 186px; 279 | } 280 | #active-tasks .right-area { 281 | width: 170px; 282 | } 283 | 284 | #other-tasks .left-area { 285 | margin-right: 246px; 286 | } 287 | #other-tasks .right-area { 288 | width: 230px; 289 | } 290 | #other-tasks .task-info { 291 | width: 120px; 292 | } 293 | #other-tasks .progress { 294 | width: 100px; 295 | } 296 | } 297 | @media (min-width: 980px) { 298 | #active-tasks .left-area { 299 | margin-right: 296px; 300 | } 301 | #active-tasks .right-area { 302 | width: 280px; 303 | } 304 | 305 | #other-tasks .left-area { 306 | margin-right: 416px; 307 | } 308 | #other-tasks .right-area { 309 | width: 400px; 310 | } 311 | #other-tasks .task-info { 312 | width: 190px; 313 | } 314 | #other-tasks .progress { 315 | width: 200px; 316 | } 317 | } 318 | 319 | /* task infobox */ 320 | .info-open { 321 | background-color: #F9F9F9; 322 | } 323 | .info-box { 324 | } 325 | .info-box .tab-content { 326 | height: 300px; 327 | overflow-y: auto; 328 | } 329 | .info-box .nav { 330 | margin-top: -1px; 331 | margin-bottom: 0; 332 | height: 300px; 333 | } 334 | #ib-status, 335 | #ib-options, 336 | #ib-peers { 337 | position: relative; 338 | margin: 18px 0; 339 | } 340 | #ib-files .file-list { 341 | margin-left: -25px; 342 | } 343 | #ib-files ul, 344 | #ib-options ul { 345 | margin-top: 5px; 346 | } 347 | #ib-files li { 348 | display: block; 349 | cursor: pointer; 350 | line-height: 14px; 351 | padding-bottom: 6px; 352 | vertical-align: top; 353 | border-bottom: 1px solid #FFF; 354 | white-space: nowrap; 355 | } 356 | #ib-files .ib-file-title:hover { 357 | border-bottom: 1px solid #666; 358 | } 359 | #ib-file-btn, 360 | #ib-options-btn { 361 | margin: 0 0 5px 5px; 362 | } 363 | @media (max-width: 980px) { 364 | #ib-file-btn, #ib-options-btn { 365 | margin-bottom: 5px; 366 | } 367 | } 368 | .ib-file-title { 369 | margin-left: 5px; 370 | } 371 | .ib-file-size { 372 | margin-left: 20px; 373 | } 374 | #ib-options li { 375 | display: block; 376 | padding-bottom: 6px; 377 | white-space: nowrap; 378 | } 379 | #ib-options li span { 380 | display: block; 381 | text-align: right; 382 | padding-right: 12px; 383 | width: 75px; 384 | line-height: 24px; 385 | } 386 | #ib-options li > span { 387 | float: left; 388 | } 389 | #ib-peers .ip_port { 390 | display: inline-block; 391 | width: 250px; 392 | } 393 | #ib-options-btn div { 394 | width: 303px; 395 | } 396 | #ib-options-save { 397 | float: right; 398 | } 399 | 400 | /* task-contextmenu */ 401 | 402 | #task-contextmenu { 403 | position: fixed; 404 | z-index: 99; 405 | } 406 | #task-contextmenu li > a { 407 | user-select: none; 408 | -moz-user-select: none; 409 | } 410 | 411 | /* add task modal */ 412 | #add-task-modal { 413 | overflow-x: hidden; 414 | } 415 | #add-task-modal .modal-body.hover { 416 | padding: 13px; 417 | border: 2px solid #666; 418 | } 419 | 420 | #add-task-uri { 421 | text-align: center; 422 | white-space: nowrap; 423 | padding: 10px 19px; 424 | margin: 0; 425 | overflow: hidden; 426 | } 427 | #add-task-uri div { 428 | padding-right: 118px; 429 | } 430 | #uri-input { 431 | width: 100%; 432 | } 433 | #uri-textarea { 434 | box-sizing: border-box; 435 | -moz-box-sizing: border-box; 436 | width: 100%; 437 | margin: 0; 438 | } 439 | 440 | #uri-more { 441 | font-size: 7px; 442 | text-align: center; 443 | height: 10px; 444 | margin: 0 20px 20px; 445 | line-height: 10px; 446 | color: #DDD; 447 | background-color: whiteSmoke; 448 | cursor: pointer; 449 | } 450 | #uri-more:hover { 451 | background-color: #DDD; 452 | color: #999; 453 | } 454 | 455 | #torrent-up-input { 456 | position: absolute; 457 | top: 0; 458 | left: 0; 459 | text-align: right; 460 | height: 100%; 461 | width: 100%; 462 | -moz-opacity: 0; 463 | filter: alpha(opacity: 0); 464 | opacity: 0; 465 | z-index: 2; 466 | cursor: pointer; 467 | } 468 | #torrent-up-btn { 469 | position: relative; 470 | } 471 | 472 | #add-task-alert { 473 | position: relative; 474 | top: 5px; 475 | } 476 | 477 | #add-task-option { 478 | padding: 0 50px 0 20px; 479 | } 480 | @media (max-width: 480px) { 481 | #add-task-option { 482 | padding: 0 10px 0 20px; 483 | } 484 | } 485 | #add-task-option .controls { 486 | padding-right: 10px; 487 | } 488 | #add-task-option .input-xlarge { 489 | width: 100%; 490 | } 491 | #add-task-option .half { 492 | float: left; 493 | width: 220px; 494 | } 495 | #add-task-option .control-label { 496 | width: 70px; 497 | } 498 | #add-task-option .controls { 499 | margin-left: 85px; 500 | } 501 | 502 | /* aria2 global setting */ 503 | #copyright { 504 | margin-top: 10px; 505 | float: left; 506 | } 507 | #setting-form .rpc-path-group .controls { 508 | padding-right: 70px; 509 | } 510 | @media (max-width: 480px) { 511 | #setting-form .rpc-path-group .controls { 512 | padding-right: 35px; 513 | } 514 | } 515 | #setting-form .rpc-path-wrap { 516 | padding-right: 34px; 517 | width: 100%; 518 | } 519 | #setting-form .rpc-path-wrap .add-on { 520 | position: absolute; 521 | right: 1px; 522 | } 523 | #rpc-path { 524 | width: 100%; 525 | height: 28px; 526 | float: left; 527 | box-sizing: border-box; 528 | -moz-box-sizing: border-box; 529 | } 530 | #aria2-gs-form { 531 | margin-right: 30px; 532 | } 533 | @media (max-width: 480px) { 534 | #aria2-gs-form { 535 | margin-right: 0; 536 | } 537 | } 538 | #aria2-gs-form .controls { 539 | padding-right: 10px; 540 | } 541 | #aria2-gs-form .input-xlarge { 542 | width: 100%; 543 | } 544 | #aria2-gs-form .half { 545 | float: left; 546 | width: 240px; 547 | margin-left: 10px; 548 | } 549 | #aria2-gs-form .half .control-label { 550 | width: 110px; 551 | } 552 | #aria2-gs-form .half .controls { 553 | margin-left: 130px; 554 | padding-right: 0; 555 | } 556 | td, th { 557 | padding: 0 1em 0 0; 558 | text-align: left; 559 | } 560 | /* vim: set et sw=4 ts=4 sts=4 fdm=marker ff=unix fenc=utf8: */ 561 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aa65535/yaaw-zh-hans/502914c66ffccec68f9d510973ea156055d9ad6c/favicon.ico -------------------------------------------------------------------------------- /img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aa65535/yaaw-zh-hans/502914c66ffccec68f9d510973ea156055d9ad6c/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aa65535/yaaw-zh-hans/502914c66ffccec68f9d510973ea156055d9ad6c/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | 23 | Aria2 Web 控制台 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 |
41 | 49 | 50 |
51 |
52 |
53 | × 54 | 加载中 55 |
56 |
57 | 58 | 75 | 76 |
77 | 82 | 93 |
94 | 95 |
96 | 107 | 108 | 109 | 110 |
111 | 112 |
113 | 121 |
122 |
123 | 124 |
125 |
126 | 下载中的任务 127 |
128 |
    129 |
  • 130 |
    131 | 没有正在下载的任务 132 |
    133 |
  • 134 |
135 |
136 | 137 |
138 |
139 | 其他任务 140 |
141 |
    142 |
  • 143 |
    144 | 没有任务 145 |
    146 |
  • 147 |
148 |
149 |
150 |
151 | 152 | 163 | 164 | 189 | 190 | 252 | 253 | 258 | 259 | 298 | 299 | 325 | 326 | 349 | 350 | 364 | 365 | 372 | 373 | 385 | 386 | 397 | 398 | 405 | 406 | 475 | 476 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | -------------------------------------------------------------------------------- /js/aria2.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Binux 3 | * 4 | * This file is part of YAAW (https://github.com/binux/yaaw). 5 | * 6 | * YAAW is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as 8 | * published by the Free Software Foundation, either version 3 of 9 | * the License, or (at your option) any later version. 10 | * 11 | * YAAW is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You may get a copy of the GNU Lesser General Public License 17 | * from http://www.gnu.org/licenses/lgpl.txt 18 | * 19 | */ 20 | 21 | if (typeof ARIA2 == "undefined" || !ARIA2) var ARIA2 = (function() { 22 | var jsonrpc_interface, jsonrpc_protocol, jsonrpc_ws, interval_id, rpc_secret = null, 23 | unique_id = 0, ws_callback = {}; 24 | var active_tasks_snapshot="", finished_tasks_list=undefined, tasks_cnt_snapshot="", select_lock=false, need_refresh=false; 25 | var auto_refresh = false; 26 | 27 | function get_error(result) { 28 | if (typeof result == "string") 29 | return result; 30 | else if (typeof result.error == "string") 31 | return result.error; 32 | else if (result.error && result.error.message) 33 | return result.error.message; 34 | } 35 | 36 | function default_error(result) { 37 | // console.debug(result); 38 | var error_msg = get_error(result); 39 | 40 | $("#main-alert .alert").attr("class", "alert alert-error"); 41 | $("#main-alert .alert-msg").html("错误: "+error_msg); 42 | $("#main-alert").show(); 43 | } 44 | 45 | function main_alert(_class, msg, timeout) { 46 | var msg_id = (new Date()).getTime(); 47 | $("#main-alert .alert").attr("class", "alert "+_class); 48 | $("#main-alert .alert-msg").html(msg); 49 | $("#main-alert").data("msg_id", msg_id).show(); 50 | if (timeout) { 51 | window.setTimeout(function() { 52 | if($("#main-alert").data("msg_id") == msg_id) { 53 | $("#main-alert").fadeOut(); 54 | } 55 | }, timeout); 56 | } 57 | return msg_id; 58 | } 59 | 60 | function bind_event(dom) { 61 | dom.find("[rel=tooltip]").tooltip({"placement": "bottom", "trigger" : "hover"}); 62 | } 63 | 64 | function get_title(result) { 65 | var dir = result.dir; 66 | var title = "Unknown"; 67 | if (result.bittorrent && result.bittorrent.info && result.bittorrent.info.name) 68 | title = result.bittorrent.info.name; 69 | else if (result.files[0].path && result.files[0].path.replace( 70 | new RegExp("^"+dir.replace(/\\/g, "/").replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')+"/?"), "").split("/").length) { 71 | title = result.files[0].path.replace(new RegExp("^"+dir.replace(/\\/g, "/").replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')+"/?"), "").split("/"); 72 | if (result.bittorrent) 73 | title = title[0]; 74 | else 75 | title = title[title.length-1]; 76 | } else if (result.files.length && result.files[0].uris.length && result.files[0].uris[0].uri) 77 | title = result.files[0].uris[0].uri; 78 | 79 | if (result.files.length > 1) { 80 | var cnt = 0; 81 | for (var i=0; i 1) 86 | title += " ("+cnt+ " files..)" 87 | } 88 | return title; 89 | } 90 | 91 | function request_auth(url) { 92 | return url.match(/^(?:(?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(?:\/\/)?(?:([^:@]*(?::[^:@]*)?)?@)?/)[1]; 93 | } 94 | 95 | function remove_auth(url) { 96 | return url.replace(/^((?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(\/\/)?(?:(?:[^:@]*(?::[^:@]*)?)?@)?(.*)/, '$1$2$3'); 97 | } 98 | 99 | return { 100 | init: function(path, onready) { 101 | var connect_msg_id = main_alert("alert-info", "正在连接..."); 102 | $("#add-task-option-wrap").empty().append(YAAW.tpl.add_task_option({})); 103 | $("#aria2-gsetting").empty().append(YAAW.tpl.aria2_global_setting({})); 104 | 105 | jsonrpc_interface = path || "http://localhost:6800/jsonrpc"; 106 | var auth_str = request_auth(jsonrpc_interface); 107 | if (auth_str && auth_str.indexOf('token:') == 0) { 108 | rpc_secret = auth_str; 109 | jsonrpc_interface = remove_auth(jsonrpc_interface); 110 | } 111 | 112 | if (jsonrpc_interface.indexOf("http") == 0) { 113 | jsonrpc_protocol = "http"; 114 | $.jsonRPC.setup({endPoint: jsonrpc_interface, namespace: 'aria2'}); 115 | ARIA2.request = ARIA2.request_http; 116 | ARIA2.batch_request = ARIA2.batch_request_http; 117 | if (onready) onready(); 118 | if ($("#main-alert").data("msg_id") == connect_msg_id) { 119 | $("#main-alert").fadeOut(); 120 | } 121 | } else if (jsonrpc_interface.indexOf("ws") == 0 && WebSocket) { 122 | jsonrpc_protocol = "ws" 123 | jsonrpc_ws = new WebSocket(jsonrpc_interface); 124 | jsonrpc_ws.onmessage = function(event) { 125 | var data = JSON.parse(event.data); 126 | // console.debug(data); 127 | if ($.isArray(data) && data.length) { 128 | var id = data[0].id; 129 | if (ws_callback[id]) { 130 | ws_callback[id].success(data); 131 | delete ws_callback[id]; 132 | } 133 | } else { 134 | if (ws_callback[data.id]) { 135 | if (data.error) 136 | ws_callback[data.id].error(data); 137 | else 138 | ws_callback[data.id].success(data); 139 | delete ws_callback[data.id]; 140 | }; 141 | }; 142 | }; 143 | jsonrpc_ws.onerror = function(event) { 144 | // console.warn("error", event); 145 | main_alert("alert-error", "WebSocket 连接错误. 你可能需要刷新此页面."); 146 | ws_callback = {}; 147 | }; 148 | jsonrpc_ws.onopen = function() { 149 | ARIA2.request = ARIA2.request_ws; 150 | ARIA2.batch_request = ARIA2.batch_request_ws; 151 | if (onready) onready(); 152 | if ($("#main-alert").data("msg_id") == connect_msg_id) { 153 | $("#main-alert").fadeOut(); 154 | } 155 | }; 156 | } else { 157 | main_alert("alert-error", "JSON-RPC Path错误, 只支持HTTP和WS协议"); 158 | }; 159 | }, 160 | 161 | request: function(){}, 162 | batch_request: function(){}, 163 | 164 | request_http: function(method, params, success, error) { 165 | if (error == undefined) 166 | error = default_error; 167 | if (rpc_secret) { 168 | params = params || []; 169 | if (!$.isArray(params)) params = [params]; 170 | params.unshift(rpc_secret); 171 | } 172 | $.jsonRPC.request(method, {params:params, success:success, error:error}); 173 | }, 174 | 175 | batch_request_http: function(method, params, success, error) { 176 | if (error == undefined) 177 | error = default_error; 178 | var commands = new Array(); 179 | $.each(params, function(i, n) { 180 | n = n || []; 181 | if (!$.isArray(n)) n = [n]; 182 | if (rpc_secret) { 183 | n.unshift(rpc_secret); 184 | } 185 | commands.push({method: method, params: n}); 186 | }); 187 | $.jsonRPC.batchRequest(commands, {success:success, error:error}); 188 | }, 189 | 190 | _request_data: function(method, params, id) { 191 | var dataObj = { 192 | jsonrpc: '2.0', 193 | method: 'aria2.'+method, 194 | id: id 195 | } 196 | if(typeof(params) !== 'undefined') { 197 | dataObj.params = params; 198 | } 199 | return dataObj; 200 | }, 201 | 202 | _get_unique_id: function() { 203 | ++unique_id; 204 | return unique_id; 205 | }, 206 | 207 | request_ws: function(method, params, success, error) { 208 | var id = ARIA2._get_unique_id(); 209 | ws_callback[id] = { 210 | 'success': success || function(){}, 211 | 'error': error || default_error, 212 | }; 213 | if (rpc_secret) { 214 | params = params || []; 215 | if (!$.isArray(params)) params = [params]; 216 | params.unshift(rpc_secret); 217 | } 218 | jsonrpc_ws.send(JSON.stringify(ARIA2._request_data(method, params, id))); 219 | }, 220 | 221 | batch_request_ws: function(method, params, success, error) { 222 | var data = []; 223 | var id = ARIA2._get_unique_id(); 224 | ws_callback[id] = { 225 | 'success': success || function(){}, 226 | 'error': error || default_error, 227 | }; 228 | for (var i = 0, l = params.length; i < l; i++) { 229 | var n = params[i]; 230 | n = n || []; 231 | if (!$.isArray(n)) n = [n]; 232 | if (rpc_secret) { 233 | n.unshift(rpc_secret); 234 | } 235 | data.push(ARIA2._request_data(method, n, id)) 236 | }; 237 | jsonrpc_ws.send(JSON.stringify(data)); 238 | }, 239 | 240 | main_alert: main_alert, 241 | 242 | add_task: function(uri, options) { 243 | if (!uri) return false; 244 | if (!options) options = {}; 245 | if (/^[0-9a-z]{40}$/i.test(uri)) { 246 | // console.debug('(add_task)Info Hash:' + uri); 247 | uri = 'magnet:?xt=urn:btih:' + uri; 248 | } 249 | ARIA2.request("addUri", [[uri], options], 250 | function(result) { 251 | // console.debug(result); 252 | ARIA2.refresh(); 253 | $("#add-task-modal").modal('hide'); 254 | YAAW.add_task.clean(); 255 | }, 256 | function(result) { 257 | // console.debug(result); 258 | var error_msg = get_error(result); 259 | 260 | $("#add-task-alert .alert-msg").text(error_msg); 261 | $("#add-task-alert").show(); 262 | // console.warn("添加任务错误: "+error_msg); 263 | } 264 | ); 265 | }, 266 | 267 | madd_task: function(uris, options) { 268 | if (!$.isArray(uris)) uris = [uris]; 269 | var params = []; 270 | for (var i=0; i"); 294 | $("#add-task-alert .alert-msg").html(error_msg); 295 | $("#add-task-alert").show(); 296 | // console.warn("添加任务错误: "+error_msg); 297 | } 298 | } 299 | ); 300 | }, 301 | 302 | add_torrent: function(torrent, options) { 303 | if (!torrent) return false; 304 | if (!options) options = {}; 305 | ARIA2.request("addTorrent", [torrent, [], options], 306 | function(result) { 307 | // console.debug(result); 308 | ARIA2.refresh(); 309 | $("#add-task-modal").modal('hide'); 310 | YAAW.add_task.clean(); 311 | }, 312 | function(result) { 313 | // console.debug(result); 314 | var error_msg = get_error(result); 315 | 316 | $("#add-task-alert .alert-msg").text(error_msg); 317 | $("#add-task-alert").show(); 318 | // console.warn("添加任务错误: "+error_msg); 319 | } 320 | ); 321 | }, 322 | 323 | add_metalink: function(metalink, options) { 324 | if (!metalink) return false; 325 | if (!options) options = {}; 326 | ARIA2.request("addMetalink", [metalink, [], options], 327 | function(result) { 328 | // console.debug(result); 329 | ARIA2.refresh(); 330 | $("#add-task-modal").modal('hide'); 331 | YAAW.add_task.clean(); 332 | }, 333 | function(result) { 334 | // console.debug(result); 335 | var error_msg = get_error(result); 336 | $("#add-task-alert .alert-msg").text(error_msg); 337 | $("#add-task-alert").show(); 338 | // console.warn("添加任务错误: "+error_msg); 339 | } 340 | ); 341 | }, 342 | 343 | restart_task: function(gids) { 344 | if (!$.isArray(gids)) 345 | gids = [gids]; 346 | $.each(gids, function(n, gid) { 347 | var result = $("#task-gid-"+gid).data("raw"); 348 | var uris = []; 349 | $.each(result.files, function(n, e) { 350 | if (e.uris.length) 351 | uris.push(e.uris[0].uri); 352 | }); 353 | if (result.bittorrent) { 354 | var magnet_link = "magnet:?xt=urn:btih:" + result.infoHash; 355 | if (result.bittorrent.info.name) 356 | magnet_link += "&dn=" + result.bittorrent.info.name; 357 | if (result.bittorrent.announceList.length) 358 | magnet_link += "&tr=" + result.bittorrent.announceList.join("&tr="); 359 | uris.push(magnet_link); 360 | } 361 | if (uris.length > 0) { 362 | ARIA2.request("getOption", [gid], function(result) { 363 | var options = result.result; 364 | ARIA2.madd_task(uris, options); 365 | }); 366 | } 367 | }); 368 | }, 369 | 370 | tell_active: function(keys) { 371 | if (select_lock) return; 372 | ARIA2.request("tellActive", keys, 373 | function(result) { 374 | // console.debug(result); 375 | if (select_lock) return; 376 | if (!result.result) { 377 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 378 | } 379 | 380 | var snapshot = new Array(); 381 | $.each(result.result, function(i, e) { 382 | snapshot.push(e.gid); 383 | }); 384 | if (snapshot.sort().join(",") != active_tasks_snapshot) { 385 | active_tasks_snapshot = snapshot.sort().join(","); 386 | need_refresh = true; 387 | if (auto_refresh && !select_lock) 388 | ARIA2.refresh(); 389 | } 390 | 391 | result = ARIA2.status_fix(result.result); 392 | $("#active-tasks-table").empty().append(YAAW.tpl.active_task({"tasks": result})); 393 | $.each(result, function(n, e) { 394 | $("#task-gid-"+e.gid).data("raw", e); 395 | }); 396 | bind_event($("#active-tasks-table")) 397 | } 398 | ); 399 | }, 400 | 401 | check_active_list: function() { 402 | ARIA2.request("tellActive", [["gid"]], 403 | function(result) { 404 | // console.debug(result); 405 | if (!result.result) { 406 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 407 | } 408 | 409 | var snapshot = new Array(); 410 | $.each(result.result, function(i, e) { 411 | snapshot.push(e.gid); 412 | }); 413 | if (snapshot.sort().join(",") != active_tasks_snapshot) { 414 | active_tasks_snapshot = snapshot.sort().join(","); 415 | need_refresh = true; 416 | if (auto_refresh && !select_lock) 417 | ARIA2.refresh(); 418 | } 419 | } 420 | ); 421 | }, 422 | 423 | tell_waiting: function(keys) { 424 | if (select_lock) return; 425 | var params = [0, 1000]; 426 | if (keys) params.push(keys); 427 | ARIA2.request("tellWaiting", params, 428 | function(result) { 429 | if (select_lock) 430 | return; 431 | if (!result.result) { 432 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 433 | } 434 | 435 | result = ARIA2.status_fix(result.result); 436 | $("#waiting-tasks-table").empty().append(YAAW.tpl.other_task({"tasks": result})); 437 | $.each(result, function(n, e) { 438 | $("#task-gid-"+e.gid).data("raw", e); 439 | }); 440 | bind_event($("#waiting-tasks-table")) 441 | 442 | if ($("#other-tasks .task").length == 0) 443 | $("#waiting-tasks-table").append($("#other-task-empty").text()) 444 | } 445 | ); 446 | }, 447 | 448 | tell_stopped: function(keys) { 449 | if (select_lock) return; 450 | var params = [0, 1000]; 451 | if (keys) params.push(keys); 452 | ARIA2.request("tellStopped", params, 453 | function(result) { 454 | // console.debug(result); 455 | if (select_lock) return; 456 | if (!result.result) { 457 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 458 | } 459 | 460 | result = ARIA2.status_fix(result.result); 461 | 462 | if (finished_tasks_list === undefined) { 463 | finished_tasks_list = new Array(); 464 | $.each(result, function(i, e) { 465 | if (e.status != "complete") 466 | return; 467 | finished_tasks_list.push(e.gid); 468 | }); 469 | } else { 470 | $.each(result, function(i, e) { 471 | if (e.status != "complete") 472 | return; 473 | if (finished_tasks_list.indexOf(e.gid) != -1) 474 | return; 475 | if (ARIA2.finish_notification) { 476 | YAAW.notification("Aria2 Web 控制台通知", e.title + " 已完成"); 477 | } 478 | finished_tasks_list.push(e.gid); 479 | }); 480 | } 481 | 482 | $("#stopped-tasks-table").empty().append(YAAW.tpl.other_task({"tasks": result.reverse()})); 483 | $.each(result, function(n, e) { 484 | $("#task-gid-"+e.gid).data("raw", e); 485 | }); 486 | bind_event($("#stopped-tasks-table")) 487 | 488 | if ($("#waiting-tasks-table .empty-tasks").length > 0 && 489 | $("#stopped-tasks-table .task").length > 0) { 490 | $("#waiting-tasks-table").empty(); 491 | } 492 | } 493 | ); 494 | }, 495 | 496 | status_fix: function(results) { 497 | for (var i=0; i"), 3000); 562 | } 563 | } 564 | ); 565 | }, 566 | 567 | unpause: function(gids) { 568 | if (!$.isArray(gids)) gids = [gids]; 569 | ARIA2.batch_request("unpause", gids, 570 | function(result) { 571 | // console.debug(result); 572 | var error = new Array(); 573 | $.each(result, function(i, n) { 574 | var error_msg = get_error(n); 575 | if (error_msg) error.push(error_msg); 576 | }); 577 | 578 | if (error.length == 0) { 579 | main_alert("alert-info", "已开始", 1000); 580 | ARIA2.refresh(); 581 | } else { 582 | main_alert("alert-error", error.join("
"), 3000); 583 | } 584 | } 585 | ); 586 | }, 587 | 588 | remove: function(gids) { 589 | if (!$.isArray(gids)) gids = [gids]; 590 | ARIA2.batch_request("remove", gids, 591 | function(result) { 592 | // console.debug(result); 593 | var error = new Array(); 594 | $.each(result, function(i, n) { 595 | var error_msg = get_error(n); 596 | if (error_msg) error.push(error_msg); 597 | }); 598 | 599 | if (error.length == 0) { 600 | main_alert("alert-info", "已删除", 1000); 601 | ARIA2.refresh(); 602 | } else { 603 | main_alert("alert-error", error.join("
"), 3000); 604 | } 605 | } 606 | ); 607 | }, 608 | 609 | remove_result: function(gids) { 610 | if (!$.isArray(gids)) gids = [gids]; 611 | ARIA2.batch_request("removeDownloadResult", gids, 612 | function(result) { 613 | // console.debug(result); 614 | var error = new Array(); 615 | $.each(result, function(i, n) { 616 | var error_msg = get_error(n); 617 | if (error_msg) error.push(error_msg); 618 | }); 619 | 620 | if (error.length == 0) { 621 | main_alert("alert-info", "已删除", 1000); 622 | ARIA2.tell_stopped(); 623 | } else { 624 | main_alert("alert-error", error.join("
"), 3000); 625 | } 626 | } 627 | ); 628 | }, 629 | 630 | get_options: function(gid) { 631 | ARIA2.request("getOption", [gid], 632 | function(result) { 633 | // console.debug(result); 634 | $("#ib-options").empty().append(YAAW.tpl.ib_options(result.result)); 635 | if ($("#task-gid-"+gid).attr("data-status") == "active") 636 | $("#ib-options-form *[name]:not(.active-allowed)").attr("disabled", true); 637 | } 638 | ); 639 | }, 640 | 641 | change_options: function(gid, options) { 642 | ARIA2.request("changeOption", [gid, options], 643 | function(result) { 644 | // console.debug(result); 645 | main_alert("alert-info", "选项已更新", 1000); 646 | } 647 | ); 648 | }, 649 | 650 | get_peers: function(gid) { 651 | ARIA2.request("getPeers", [gid], 652 | function(result) { 653 | // console.debug(result); 654 | $('').appendTo($('').appendTo($("#ib-peers").empty())) 655 | .append('') 656 | .append(YAAW.tpl.ib_peers(result.result)); 657 | //$("#ib-peers").empty().append(YAAW.tpl.ib_peers(result.result)); 658 | } 659 | ); 660 | }, 661 | 662 | pause_all: function() { 663 | ARIA2.request("pauseAll", [], 664 | function(result) { 665 | // console.debug(result); 666 | ARIA2.refresh(); 667 | main_alert("alert-info", "已暂停所有任务, 请等待 BitTorrent 服务器响应.", 2000); 668 | } 669 | ); 670 | }, 671 | 672 | unpause_all: function() { 673 | ARIA2.request("unpauseAll", [], 674 | function(result) { 675 | // console.debug(result); 676 | ARIA2.refresh(); 677 | main_alert("alert-info", "取消暂停所有任务", 2000); 678 | } 679 | ); 680 | }, 681 | 682 | purge_download_result: function() { 683 | ARIA2.request("purgeDownloadResult", [], 684 | function(result) { 685 | // console.debug(result); 686 | ARIA2.refresh(); 687 | main_alert("alert-info", "移除所有已完成/错误/已删除下载任务.", 2000); 688 | } 689 | ); 690 | }, 691 | 692 | get_global_option: function() { 693 | ARIA2.request("getGlobalOption", [], 694 | function(result) { 695 | if (!result.result) 696 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 697 | 698 | result = result.result; 699 | $("#aria2-gsetting").empty().append(YAAW.tpl.aria2_global_setting(result)); 700 | } 701 | ); 702 | }, 703 | 704 | init_add_task_option: function() { 705 | ARIA2.request("getGlobalOption", [], 706 | function(result) { 707 | if (!result.result) 708 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 709 | 710 | result = result.result; 711 | result["parameterized-uri"] = (result["parameterized-uri"] == "true" ? true : false) 712 | $("#add-task-option-wrap").empty().append(YAAW.tpl.add_task_option(result)); 713 | } 714 | ); 715 | }, 716 | 717 | change_global_option: function(options) { 718 | ARIA2.request("changeGlobalOption", [options], 719 | function(result) { 720 | if (!result.result) 721 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 722 | else 723 | main_alert("alert-success", "已保存", 2000); 724 | } 725 | ); 726 | }, 727 | 728 | global_stat: function() { 729 | ARIA2.request("getGlobalStat", [], 730 | function(result) { 731 | if (!result.result) { 732 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 733 | } 734 | 735 | result = result.result; 736 | var _tasks_cnt_snapshot = ""+result.numActive+","+result.numWaiting+","+result.numStopped; 737 | 738 | if (_tasks_cnt_snapshot != tasks_cnt_snapshot) { 739 | tasks_cnt_snapshot = _tasks_cnt_snapshot; 740 | need_refresh = true; 741 | if (auto_refresh && !select_lock) 742 | ARIA2.refresh(); 743 | } 744 | 745 | $("#global-speed").empty().append(YAAW.tpl.global_speed(result)); 746 | var title = ""; 747 | if (result.downloadSpeed > 0) { 748 | title += "↓" + YAAW.tpl.view.format_size_0()(result.downloadSpeed) + "/s "; 749 | } 750 | if (result.uploadSpeed > 0) { 751 | title += "↑" + YAAW.tpl.view.format_size_0()(result.uploadSpeed) + "/s "; 752 | } 753 | title += (title ? "- " : "") + "Aria2 Web 控制台"; 754 | document.title = title; 755 | } 756 | ); 757 | }, 758 | 759 | get_version: function() { 760 | ARIA2.request("getVersion", [], 761 | function(result) { 762 | if (!result.result) { 763 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 764 | } 765 | 766 | $("#global-version").text("Aria2 "+result.result.version || ""); 767 | } 768 | ); 769 | }, 770 | 771 | get_status: function(gid) { 772 | ARIA2.request("tellStatus", [gid], 773 | function(result) { 774 | if (!result.result) { 775 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 776 | } 777 | 778 | result = result.result; 779 | result.uris = []; 780 | for (var i = 0; i < result.files.length; i++) { 781 | var file = result.files[i]; 782 | file.title = file.path.replace(new RegExp("^"+result.dir.replace(/\\/g, "[\\/]")+"/?"), ""); 783 | file.selected = file.selected == "true" ? true : false; 784 | file.progress = (file.completedLength * 1.0 / file.length * 100).toFixed(2); 785 | if (file.uris && file.uris.length) { 786 | for (var j = 0; j < file.uris.length; j++) { 787 | var uri = file.uris[j].uri; 788 | if (result.uris.indexOf(uri) == -1) { 789 | result.uris.push(uri); 790 | } 791 | } 792 | } 793 | }; 794 | $("#ib-status").empty().append(YAAW.tpl.ib_status(result)); 795 | $("#ib-files .file-list").empty().append(YAAW.tpl.files_tree(result.files)); 796 | if ($("#task-gid-" + gid).attr("data-status") != "paused") 797 | $("#ib-file-save").hide(); 798 | if (result.bittorrent) { 799 | $("#ib-peers-a").show(); 800 | } 801 | } 802 | ); 803 | }, 804 | 805 | change_option: function(gid, options) { 806 | ARIA2.request("changeOption", [gid, options], 807 | function(result) { 808 | if (!result.result) { 809 | main_alert("alert-error", "错误: RPC 通信错误.", 5000); 810 | } else { 811 | main_alert("alert-success", "选项更改成功!", 2000); 812 | } 813 | } 814 | ); 815 | }, 816 | 817 | /********************************************************/ 818 | 819 | refresh: function() { 820 | if (!select_lock) { 821 | need_refresh = false; 822 | ARIA2.tell_active(); 823 | ARIA2.tell_waiting(); 824 | ARIA2.tell_stopped(); 825 | } 826 | }, 827 | 828 | select_lock: function (bool) { 829 | select_lock = bool; 830 | }, 831 | 832 | auto_refresh: function(interval) { 833 | if (interval_id) 834 | window.clearInterval(interval_id); 835 | if (interval < 1000) { 836 | auto_refresh = false; 837 | return ; 838 | } 839 | interval_id = window.setInterval(function() { 840 | ARIA2.global_stat(); 841 | if (select_lock) { 842 | if (need_refresh) { 843 | main_alert("", "任务列表已经改变。点击“刷新”按钮来更新任务列表。"); 844 | } 845 | } else { 846 | if (need_refresh) { 847 | ARIA2.refresh(); 848 | } else { 849 | ARIA2.tell_active(); 850 | } 851 | } 852 | }, interval); 853 | auto_refresh = true; 854 | }, 855 | 856 | finish_notification: 1, 857 | } 858 | })(); 859 | -------------------------------------------------------------------------------- /js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap.js by @fat & @mdo 3 | * Copyright 2012 Twitter, Inc. 4 | * http://www.apache.org/licenses/LICENSE-2.0.txt 5 | */ 6 | !function(a){a(function(){"use strict",a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed").remove()}var c=a(this),d=c.attr("data-target"),e;d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),e=a(d),b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.on(a.support.transition.end,f):f()},a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("alert");e||d.data("alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a(function(){a("body").on("click.alert.data-api",b,c.prototype.close)})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.button.defaults,c)};b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.data(),e=c.is("input")?"val":"html";a+="Text",d.resetText||c.data("resetText",c[e]()),c[e](d[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.parent('[data-toggle="buttons-radio"]');a&&a.find(".active").removeClass("active"),this.$element.toggleClass("active")},a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("button"),f=typeof c=="object"&&c;e||d.data("button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.defaults={loadingText:"loading..."},a.fn.button.Constructor=b,a(function(){a("body").on("click.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle")})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=c,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.prototype={cycle:function(b){return b||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},to:function(b){var c=this.$element.find(".active"),d=c.parent().children(),e=d.index(c),f=this;if(b>d.length-1||b<0)return;return this.sliding?this.$element.one("slid",function(){f.to(b)}):e==b?this.pause().cycle():this.slide(b>e?"next":"prev",a(d[b]))},pause:function(a){return a||(this.paused=!0),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(b,c){var d=this.$element.find(".active"),e=c||d[b](),f=this.interval,g=b=="next"?"left":"right",h=b=="next"?"first":"last",i=this,j=a.Event("slide");this.sliding=!0,f&&this.pause(),e=e.length?e:this.$element.find(".item")[h]();if(e.hasClass("active"))return;if(a.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(j);if(j.isDefaultPrevented())return;e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),this.$element.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid")},0)})}else{this.$element.trigger(j);if(j.isDefaultPrevented())return;d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return f&&this.cycle(),this}},a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("carousel"),f=a.extend({},a.fn.carousel.defaults,typeof c=="object"&&c);e||d.data("carousel",e=new b(this,f)),typeof c=="number"?e.to(c):typeof c=="string"||(c=f.slide)?e[c]():f.interval&&e.cycle()})},a.fn.carousel.defaults={interval:5e3,pause:"hover"},a.fn.carousel.Constructor=b,a(function(){a("body").on("click.carousel.data-api","[data-slide]",function(b){var c=a(this),d,e=a(c.attr("data-target")||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,"")),f=!e.data("modal")&&a.extend({},e.data(),c.data());e.carousel(f),b.preventDefault()})})}(window.jQuery),!function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.collapse.defaults,c),this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.prototype={constructor:b,dimension:function(){var a=this.$element.hasClass("width");return a?"width":"height"},show:function(){var b,c,d,e;if(this.transitioning)return;b=this.dimension(),c=a.camelCase(["scroll",b].join("-")),d=this.$parent&&this.$parent.find("> .accordion-group > .in");if(d&&d.length){e=d.data("collapse");if(e&&e.transitioning)return;d.collapse("hide"),e||d.data("collapse",null)}this.$element[b](0),this.transition("addClass",a.Event("show"),"shown"),this.$element[b](this.$element[0][c])},hide:function(){var b;if(this.transitioning)return;b=this.dimension(),this.reset(this.$element[b]()),this.transition("removeClass",a.Event("hide"),"hidden"),this.$element[b](0)},reset:function(a){var b=this.dimension();return this.$element.removeClass("collapse")[b](a||"auto")[0].offsetWidth,this.$element[a!==null?"addClass":"removeClass"]("collapse"),this},transition:function(b,c,d){var e=this,f=function(){c.type=="show"&&e.reset(),e.transitioning=0,e.$element.trigger(d)};this.$element.trigger(c);if(c.isDefaultPrevented())return;this.transitioning=1,this.$element[b]("in"),a.support.transition&&this.$element.hasClass("collapse")?this.$element.one(a.support.transition.end,f):f()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("collapse"),f=typeof c=="object"&&c;e||d.data("collapse",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.collapse.defaults={toggle:!0},a.fn.collapse.Constructor=b,a(function(){a("body").on("click.collapse.data-api","[data-toggle=collapse]",function(b){var c=a(this),d,e=c.attr("data-target")||b.preventDefault()||(d=c.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),f=a(e).data("collapse")?"toggle":c.data();a(e).collapse(f)})})}(window.jQuery),!function(a){function d(){a(b).parent().removeClass("open")}"use strict";var b='[data-toggle="dropdown"]',c=function(b){var c=a(b).on("click.dropdown.data-api",this.toggle);a("html").on("click.dropdown.data-api",function(){c.parent().removeClass("open")})};c.prototype={constructor:c,toggle:function(b){var c=a(this),e,f,g;if(c.is(".disabled, :disabled"))return;return f=c.attr("data-target"),f||(f=c.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,"")),e=a(f),e.length||(e=c.parent()),g=e.hasClass("open"),d(),g||e.toggleClass("open"),!1}},a.fn.dropdown=function(b){return this.each(function(){var d=a(this),e=d.data("dropdown");e||d.data("dropdown",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.dropdown.Constructor=c,a(function(){a("html").on("click.dropdown.data-api",d),a("body").on("click.dropdown",".dropdown form",function(a){a.stopPropagation()}).on("click.dropdown.data-api",b,c.prototype.toggle)})}(window.jQuery),!function(a){function c(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),d.call(b)},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),d.call(b)})}function d(a){this.$element.hide().trigger("hidden"),e.call(this)}function e(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('
位置客户端完成率下载速度上传速度