From ee569197478642fcfd929e5a3927aaa928711170 Mon Sep 17 00:00:00 2001
From: HFO4 <912394456@qq.com>
Date: Sat, 7 Apr 2018 11:02:43 +0800
Subject: [PATCH 01/10] =?UTF-8?q?aria2=E4=B8=8B=E8=BD=BD=E5=A4=B1=E8=B4=A5?=
=?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
application/config.php | 2 +-
application/index/model/Aria2.php | 50 +++++++++++++++++++++++++++----
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/application/config.php b/application/config.php
index 38405e4a..fd8a9488 100644
--- a/application/config.php
+++ b/application/config.php
@@ -18,7 +18,7 @@ return [
// 应用命名空间
'app_namespace' => 'app',
// 应用调试模式
- 'app_debug' => false,
+ 'app_debug' => true,
// 应用Trace
'app_trace' => false,
// 应用模式状态
diff --git a/application/index/model/Aria2.php b/application/index/model/Aria2.php
index 8b7f57b0..ab6617cf 100644
--- a/application/index/model/Aria2.php
+++ b/application/index/model/Aria2.php
@@ -85,6 +85,7 @@ class Aria2 extends Model{
"downloadSpeed" => $respondData["result"]["downloadSpeed"],
"errorMessage" => isset($respondData["result"]["errorMessage"]) ? $respondData["result"]["errorMessage"] : "",
]),
+ "msg" => isset($respondData["result"]["errorMessage"]) ? $respondData["result"]["errorMessage"] : "",
]);
switch ($respondData["result"]["status"]) {
case 'complete':
@@ -98,7 +99,7 @@ class Aria2 extends Model{
}else{
$this->reqStatus = 0;
$this->reqMsg = "空间容量不足";
- //取消离线下载
+ $this->setError($respondData["result"],$downloadInfo,"空间容量不足");
return false;
}
}else{
@@ -110,7 +111,7 @@ class Aria2 extends Model{
private function setComplete($quenInfo,$sqlData){
if($this->policy["policy_type"] != "local"){
- //取消任务
+ $this->setError($quenInfo,$sqlData,"您当前的上传策略无法使用离线下载");
return false;
}
$suffixTmp = explode('.', $quenInfo["dir"]);
@@ -123,7 +124,7 @@ class Aria2 extends Model{
}
if($sufficCheck){
//取消任务
- $this->setError();
+ $this->setError($quenInfo,$sqlData,"文件类型不被允许");
return false;
}
if($this->policy['autoname']){
@@ -147,14 +148,53 @@ class Aria2 extends Model{
$addAction = FileManage::addFile($jsonData,$this->policy,$this->uid,$picInfo);
if(!$addAction[0]){
//取消任务
- $this->setError();
+ $this->setError($quenInfo,$sqlData,$addAction[1]);
return false;
}
FileManage::storageCheckOut($this->uid,(int)$quenInfo["totalLength"]);
}
- private function setError(){
+ private function setError($quenInfo,$sqlData,$msg,$status="error"){
+ $this->Remove($sqlData["pid"],$sqlData);
+ $this->removeDownloadResult($sqlData["pid"],$sqlData);
+ if(file_exists($quenInfo["files"][0]["path"])){
+ @unlink($quenInfo["files"][0]["path"]);
+ @unlink(dirname($quenInfo["files"][0]["path"]));
+ }
+ Db::name("download")->where("id",$sqlData["id"])->update([
+ "msg" => $msg,
+ "status" => $status,
+ ]);
+ }
+ public function Remove($gid,$sqlData){
+ $reqFileds = [
+ "params" => ["token:".$this->authToken,$gid],
+ "jsonrpc" => "2.0",
+ "id" => uniqid(),
+ "method" => "aria2.remove"
+ ];
+ $reqFileds = json_encode($reqFileds,JSON_OBJECT_AS_ARRAY);
+ $respondData = $this->sendReq($reqFileds);
+ if(isset($respondData["result"])){
+ return true;
+ }
+ return false;
+ }
+
+ public function removeDownloadResult($gid,$sqlData){
+ $reqFileds = [
+ "params" => ["token:".$this->authToken,$gid],
+ "jsonrpc" => "2.0",
+ "id" => uniqid(),
+ "method" => "aria2.removeDownloadResult"
+ ];
+ $reqFileds = json_encode($reqFileds,JSON_OBJECT_AS_ARRAY);
+ $respondData = $this->sendReq($reqFileds);
+ if(isset($respondData["result"])){
+ return true;
+ }
+ return false;
}
private function storageCheck($quenInfo,$sqlData){
From 1b87365b8a4e2108f51f57ad4b019949aee32ad7 Mon Sep 17 00:00:00 2001
From: HFO4 <912394456@qq.com>
Date: Sat, 7 Apr 2018 15:16:57 +0800
Subject: [PATCH 02/10] =?UTF-8?q?aria2=20=E7=A7=8D=E5=AD=90=E4=B8=8B?=
=?UTF-8?q?=E8=BD=BD=E5=8F=8A=E5=A4=9A=E6=96=87=E4=BB=B6=E5=A4=84=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../index/controller/RemoteDownload.php | 18 +++
application/index/model/Aria2.php | 107 +++++++++++++-----
2 files changed, 99 insertions(+), 26 deletions(-)
diff --git a/application/index/controller/RemoteDownload.php b/application/index/controller/RemoteDownload.php
index 04201747..1259d512 100644
--- a/application/index/controller/RemoteDownload.php
+++ b/application/index/controller/RemoteDownload.php
@@ -39,6 +39,8 @@ class RemoteDownload extends Controller{
"msg" => "",
"info"=>"",
"source" =>$url,
+ "file_index" => 0,
+ "is_single" => 1,
]);
}
@@ -57,6 +59,22 @@ class RemoteDownload extends Controller{
}
}
+ public function AddTorrent(){
+ $policyData = Db::name("policy")->where("id",$this->userObj->groupData["policy_name"])->find();
+ if(!$this->checkPerimission(0) || $policyData["policy_type"] != "local"){
+ return json(['error'=>1,'message'=>'您当前的无用户无法执行此操作']);
+ }
+ $aria2Options = Option::getValues(["aria2"]);
+ $aria2 = new Aria2($aria2Options);
+ $torrentObj = new \app\index\model\FileManage(input("post.path"),$this->userObj->uid);
+ $downloadStart = $aria2->addTorrent($torrentObj->signTmpUrl());
+ if($aria2->reqStatus){
+ $this->insertRecord($aria2,input("post.path"));
+ }else{
+ return json(['error'=>1,'message'=>$aria2->reqMsg]);
+ }
+ }
+
public function FlushStatus(){
$aria2Options = Option::getValues(["aria2"]);
$aria2 = new Aria2($aria2Options);
diff --git a/application/index/model/Aria2.php b/application/index/model/Aria2.php
index ab6617cf..b6c44481 100644
--- a/application/index/model/Aria2.php
+++ b/application/index/model/Aria2.php
@@ -46,6 +46,28 @@ class Aria2 extends Model{
}
}
+ public function addTorrent($torrentUrl){
+ $this->pathId = uniqid();
+ $reqFileds = [
+ "params" => ["token:".$this->authToken,
+ [$torrentUrl],["dir" => $this->savePath.$this->pathId],
+ ],
+ "jsonrpc" => "2.0",
+ "id" => $this->pathId,
+ "method" => "aria2.addUri"
+ ];
+ $reqFileds["params"][2] = array_merge($reqFileds["params"][2],$this->saveOptions);
+ $reqFileds = json_encode($reqFileds,JSON_OBJECT_AS_ARRAY);
+ $respondData = $this->sendReq($reqFileds);
+ if(isset($respondData["result"])){
+ $this->reqStatus = 1;
+ $this->pid = $respondData["result"];
+ }else{
+ $this->reqStatus = 0;
+ $this->reqMsg = $respondData["error"]["message"];
+ }
+ }
+
public function flushStatus($id,$uid,$policy){
$this->uid = $uid;
$this->policy = $policy;
@@ -74,14 +96,25 @@ class Aria2 extends Model{
$respondData = $this->sendReq($reqFileds);
if(isset($respondData["result"])){
if($this->storageCheck($respondData["result"],$downloadInfo)){
+ if($downloadInfo["is_single"] && count($respondData["result"]["files"]) >1){
+ $this->updateToMuiltpe($respondData["result"],$downloadInfo);
+ return false;
+ }
+ if(isset($respondData["result"]["followedBy"])){
+ Db::name("download")->where("id",$id)
+ ->update([
+ "pid" => $respondData["result"]["followedBy"][0],
+ ]);
+ return false;
+ }
Db::name("download")->where("id",$id)
->update([
"status" => $respondData["result"]["status"],
"last_update" => date("Y-m-d h:i:s"),
"info" => json_encode([
- "completedLength" => $respondData["result"]["completedLength"],
- "totalLength" => $respondData["result"]["totalLength"],
- "dir" => $respondData["result"]["files"][0]["path"],
+ "completedLength" => $respondData["result"]["files"][$downloadInfo["file_index"]]["completedLength"],
+ "totalLength" => $respondData["result"]["files"][$downloadInfo["file_index"]]["length"],
+ "dir" => $respondData["result"]["files"][$downloadInfo["file_index"]]["path"],
"downloadSpeed" => $respondData["result"]["downloadSpeed"],
"errorMessage" => isset($respondData["result"]["errorMessage"]) ? $respondData["result"]["errorMessage"] : "",
]),
@@ -105,10 +138,30 @@ class Aria2 extends Model{
}else{
$this->reqStatus = 0;
$this->reqMsg = $respondData["error"]["message"];
+ $this->setError($respondData,$downloadInfo,$respondData["error"]["message"],"error",false);
+ return false;
}
return true;
}
+ private function updateToMuiltpe($quenInfo,$sqlData){
+ foreach ($quenInfo["files"] as $key => $value) {
+ Db::name("download")->insert([
+ "pid" => $sqlData["pid"],
+ "path_id" => $sqlData["path_id"],
+ "owner" => $sqlData["owner"],
+ "save_dir" => 1,
+ "status" => "ready",
+ "msg" => "",
+ "info"=>"",
+ "source" =>$sqlData["source"],
+ "file_index" => $key,
+ "is_single" => 0,
+ ]);
+ }
+ Db::name("download")->where("id",$sqlData["id"])->delete();
+ }
+
private function setComplete($quenInfo,$sqlData){
if($this->policy["policy_type"] != "local"){
$this->setError($quenInfo,$sqlData,"您当前的上传策略无法使用离线下载");
@@ -128,20 +181,20 @@ class Aria2 extends Model{
return false;
}
if($this->policy['autoname']){
- $fileName = $uploadHandller->getObjName($this->policy['namerule'],"local",basename($quenInfo["files"][0]["path"]));
+ $fileName = $uploadHandller->getObjName($this->policy['namerule'],"local",basename($quenInfo["files"][$sqlData["file_index"]]["path"]));
}else{
- $fileName = basename($quenInfo["files"][0]["path"]);
+ $fileName = basename($quenInfo["files"][$sqlData["file_index"]]["path"]);
}
$generatePath = $uploadHandller->getDirName($this->policy['dirrule']);
$savePath = ROOT_PATH . 'public/uploads/'.$generatePath.DS.$fileName;
is_dir(dirname($savePath))? :mkdir(dirname($savePath),0777,true);
- rename($quenInfo["files"][0]["path"],$savePath);
- @unlink(dirname($quenInfo["files"][0]["path"]));
+ rename($quenInfo["files"][$sqlData["file_index"]]["path"],$savePath);
+ @unlink(dirname($quenInfo["files"][$sqlData["file_index"]]["path"]));
$jsonData = array(
"path" => "",
- "fname" => basename($quenInfo["files"][0]["path"]),
+ "fname" => basename($quenInfo["files"][$sqlData["file_index"]]["path"]),
"objname" => $generatePath.DS.$fileName,
- "fsize" => $quenInfo["totalLength"],
+ "fsize" => $quenInfo["files"][$sqlData["file_index"]]["length"],
);
@list($width, $height, $type, $attr) = getimagesize($savePath);
$picInfo = empty($width)?" ":$width.",".$height;
@@ -151,15 +204,17 @@ class Aria2 extends Model{
$this->setError($quenInfo,$sqlData,$addAction[1]);
return false;
}
- FileManage::storageCheckOut($this->uid,(int)$quenInfo["totalLength"]);
+ FileManage::storageCheckOut($this->uid,(int)$quenInfo["files"][$sqlData["file_index"]]["length"]);
}
- private function setError($quenInfo,$sqlData,$msg,$status="error"){
+ private function setError($quenInfo,$sqlData,$msg,$status="error",$delete=true){
$this->Remove($sqlData["pid"],$sqlData);
$this->removeDownloadResult($sqlData["pid"],$sqlData);
- if(file_exists($quenInfo["files"][0]["path"])){
- @unlink($quenInfo["files"][0]["path"]);
- @unlink(dirname($quenInfo["files"][0]["path"]));
+ if($delete){
+ if(file_exists($quenInfo["files"][$sqlData["file_index"]]["path"])){
+ @unlink($quenInfo["files"][$sqlData["file_index"]]["path"]);
+ @unlink(dirname($quenInfo["files"][$sqlData["file_index"]]["path"]));
+ }
}
Db::name("download")->where("id",$sqlData["id"])->update([
"msg" => $msg,
@@ -209,18 +264,18 @@ class Aria2 extends Model{
private function sendReq($data){
$curl = curl_init();
- curl_setopt($curl, CURLOPT_URL, $this->apiUrl."jsonrpc");
- curl_setopt($curl, CURLOPT_POST, 1);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
- curl_setopt($curl, CURLOPT_TIMEOUT, 15);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- $tmpInfo = curl_exec($curl);
- if (curl_errno($curl)) {
- $this->reqStatus = 0;
- $this->reqMsg = "请求失败,".curl_error($curl);
- }
- curl_close($curl);
- return json_decode($tmpInfo,true);
+ curl_setopt($curl, CURLOPT_URL, $this->apiUrl."jsonrpc");
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 15);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ $tmpInfo = curl_exec($curl);
+ if (curl_errno($curl)) {
+ $this->reqStatus = 0;
+ $this->reqMsg = "请求失败,".curl_error($curl);
+ }
+ curl_close($curl);
+ return json_decode($tmpInfo,true);
}
}
From b8b63662eaa2bd8a33e691b16a6d3c3c5f753f05 Mon Sep 17 00:00:00 2001
From: HFO4 <912394456@qq.com>
Date: Mon, 9 Apr 2018 22:04:56 +0800
Subject: [PATCH 03/10] =?UTF-8?q?=E7=A6=BB=E7=BA=BF=E4=B8=8B=E8=BD=BD?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0URL=E4=BA=A4=E4=BA=92=E7=95=8C=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../index/controller/RemoteDownload.php | 3 +-
application/index/model/Aria2.php | 7 +++
application/index/view/home/home.html | 2 +
static/js/angular-filemanager.min.js | 49 +++++++++++++++++--
static/js/home.js | 3 ++
5 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/application/index/controller/RemoteDownload.php b/application/index/controller/RemoteDownload.php
index 1259d512..98225cac 100644
--- a/application/index/controller/RemoteDownload.php
+++ b/application/index/controller/RemoteDownload.php
@@ -54,8 +54,9 @@ class RemoteDownload extends Controller{
$downloadStart = $aria2->addUrl(input("post.url"));
if($aria2->reqStatus){
$this->insertRecord($aria2,input("post.url"));
+ return json(["result"=>['success'=>true,'error'=>null]]);
}else{
- return json(['error'=>1,'message'=>$aria2->reqMsg]);
+ return json(["result"=>['success'=>false,'error'=>$aria2->reqMsg]]);
}
}
diff --git a/application/index/model/Aria2.php b/application/index/model/Aria2.php
index b6c44481..508bc919 100644
--- a/application/index/model/Aria2.php
+++ b/application/index/model/Aria2.php
@@ -129,6 +129,13 @@ class Aria2 extends Model{
# code...
break;
}
+ if(($respondData["result"]["files"][$downloadInfo["file_index"]]["completedLength"] == $respondData["result"]["files"][$downloadInfo["file_index"]]["length"]) && $respondData["result"]["status"]=="active"){
+ $this->setComplete($respondData["result"],$downloadInfo);
+ Db::name("download")->where("id",$id)
+ ->update([
+ "status" => "complete",
+ ]);
+ }
}else{
$this->reqStatus = 0;
$this->reqMsg = "空间容量不足";
diff --git a/application/index/view/home/home.html b/application/index/view/home/home.html
index 593b101f..76332275 100644
--- a/application/index/view/home/home.html
+++ b/application/index/view/home/home.html
@@ -28,6 +28,8 @@
allowSource : "{$policyData.origin_link}",
upUrl : "{$policyData.server}",
allowShare:"{$groupData.allow_share}",
+ allowRemoteDownload:"{:explode(",",$groupData.aria2)[0]}",
+ allowTorrentDownload:"{:explode(",",$groupData.aria2)[1]}",
};
diff --git a/static/js/angular-filemanager.min.js b/static/js/angular-filemanager.min.js
index 25542c33..bb1c720d 100644
--- a/static/js/angular-filemanager.min.js
+++ b/static/js/angular-filemanager.min.js
@@ -323,6 +323,17 @@ function(e, r) {
e.modal("move", !0)
})
},
+ e.startRemoteDownload = function(){
+ if(e.temp['url'] == ""){
+ return e.apiMiddleware.apiHandler.error = a.instant("下载URL不能为空");
+ }else{
+ e.apiMiddleware.apiHandler.error = !1;
+ return void e.apiMiddleware.startRemoteDownload(e.temp['url'],n.selectedModalPath).then(function() {
+ e.modal("remoteDownload", !0);
+ toastr["success"]("离线下载任务已创建");
+ })
+ }
+ }
e.rename = function() {
var r = e.singleSelection(),
n = r.tempModel.name,
@@ -456,6 +467,11 @@ function(e) {
i = "/" + n.join("/");
return e.singleSelection() && !e.singleSelection().isFolder() && (i += "/" + e.singleSelection().tempModel.name),
i.replace(/\/\//, "/")
+ },
+ r.getSelectedPathForDownload = function() {
+ var path = r.selectedModalPath.filter(Boolean);
+ var result = '/' + path.join('/');
+ return result.replace(/\/\//, '/');
}
}
])
@@ -739,7 +755,7 @@ function(e) {
e.module("FileManagerApp").provider("fileManagerConfig",
function() {
var r = {
- appName: "angular-filemanager v1.5",
+ appName: "Cloudreve FileManager",
defaultLang: "zh_cn",
listUrl: "/File/ListFile",
previewUrl:"/File/Preview",
@@ -757,6 +773,7 @@ function(e) {
extractUrl: "bridges/php/handler.php",
permissionsUrl: "bridges/php/handler.php",
sourceUrl:"/File/gerSource",
+ remoteDownloadUrl: "/RemoteDownload/addUrl",
basePath: "/",
searchForm: !0,
sidebar: !0,
@@ -778,7 +795,9 @@ function(e) {
remove: !0,
createFolder: !0,
pickFiles: !1,
- pickFolders: !1
+ pickFolders: !1,
+ allowRemoteDownload: !1,
+ allowTorrentDownload: !1,
},
multipleDownloadFileName: "angular-filemanager.zip",
filterFileExtensions: [],
@@ -994,6 +1013,25 @@ function(e, r) {
}),
s.promise
},
+ o.prototype.startRemoteDownload = function(api,url,path) {
+ var o = this,
+ s = n.defer(),
+ l = {
+ action: "remoteDownload",
+ path: path,
+ url:url
+ };
+ return o.inprocess = !0,
+ o.error = "",
+ e.post(api, l).success(function(e, r) {
+ o.deferredHandler(e, s, r)
+ }).error(function(e, r) {
+ o.deferredHandler(e, s, r, a.instant("error_moving"))
+ })["finally"](function() {
+ o.inprocess = !1
+ }),
+ s.promise
+ },
o.prototype.remove = function(r, i,dir) {
var t = this,
o = n.defer(),
@@ -1307,6 +1345,9 @@ function(e) {
var dirList = this.getFileList(dir);
return this.apiHandler.move(r.moveUrl,dirList ,i, this.getPath(n))
},
+ i.prototype.startRemoteDownload = function(url,path) {
+ return this.apiHandler.startRemoteDownload(r.remoteDownloadUrl,url ,this.getPath(path))
+ },
i.prototype.remove = function(e,dir) {
var n = this.getFileList(e);
var dirList = this.getFileList(dir);
@@ -1516,8 +1557,8 @@ angular.module("FileManagerApp").run(["$templateCache",
e.put("src/templates/main-table-modal.html", '
'),
e.put("src/templates/main-table.html", '\r\n'),
e.put("src/templates/main.html", '\r\n
\r\n\r\n
\r\n\r\n
\r\n
\r\n
\r\n'),
- e.put("src/templates/modals.html", '\r\n
\r\n
\r\n \r\n
\r\n
\r\n
![{{singleSelection().model.name}}]()
\r\n
{{\'loading\' | translate}} ...\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
{{singleSelection() && singleSelection().model.name}} 的源文件地址: \r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
{{\'loading\' | translate}} ...\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
{{\'loading\' | translate}} ...\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n\r\n\r\n\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
的分享地址: \r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n\r\n \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n'),
- e.put("src/templates/navbar.html", '\r\n'),
+ e.put("src/templates/modals.html", '\r\n
\r\n
\r\n \r\n
\r\n
\r\n
![{{singleSelection().model.name}}]()
\r\n
{{\'loading\' | translate}} ...\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
{{singleSelection() && singleSelection().model.name}} 的源文件地址: \r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
{{\'loading\' | translate}} ...\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
{{\'loading\' | translate}} ...\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
的分享地址: \r\n \r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n \r\n\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n'),
+ e.put("src/templates/navbar.html", '