From 36e6526259a5838833e83dd190b2aa5f5582d9f1 Mon Sep 17 00:00:00 2001
From: HFO4 <912394456@qq.com>
Date: Thu, 19 Apr 2018 19:07:22 +0800
Subject: [PATCH] complete remote download based on aria2
---
README.md | 1 +
application/index/controller/Admin.php | 31 +++++
.../index/controller/RemoteDownload.php | 4 +-
application/index/model/AdminHandler.php | 45 +++++++
application/index/model/Aria2.php | 13 +-
application/index/model/CronHandler.php | 22 ++++
application/index/view/admin/add_group.html | 12 ++
application/index/view/admin/download.html | 122 ++++++++++++++++++
application/index/view/admin/edit_group.html | 17 +++
application/index/view/header_admin.html | 6 +
application/index/view/home/Download.html | 1 -
mysql.sql | 40 ++++--
static/css/sb-admin.css | 2 +-
static/js/admin/aria2.js | 34 +++++
static/js/remoteDownload.js | 4 +-
15 files changed, 335 insertions(+), 19 deletions(-)
create mode 100644 application/index/view/admin/download.html
create mode 100644 static/js/admin/aria2.js
diff --git a/README.md b/README.md
index a10a7d1d..e3a1f367 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ Cloudreve - Make the cloud easy for everyone
* 快速对接多家云存储,支持七牛、又拍云、阿里云OSS、AWS S3、自建远程服务器,当然,还有本地存储
* 可限制单文件最大大小、MIMEType、文件后缀、用户可用容量
+* 基于Aria2的离线下载
* 图片、音频、视频、文本、Markdown、Ofiice文档 在线预览
* 移动端全站响应式布局
* 文件、目录分享系统,可创建私有分享或公开分享链接
diff --git a/application/index/controller/Admin.php b/application/index/controller/Admin.php
index f7380f13..0a2c52f5 100644
--- a/application/index/controller/Admin.php
+++ b/application/index/controller/Admin.php
@@ -248,6 +248,10 @@ class Admin extends Controller{
return $this->adminObj->saveMailSetting(input('post.'));
}
+ public function SaveAria2Setting(){
+ return $this->adminObj->saveAria2Setting(input('post.'));
+ }
+
public function SendTestMail(){
return $this->adminObj->sendTestMail(input('post.'));
}
@@ -482,5 +486,32 @@ class Admin extends Controller{
'policy' => $this->adminObj->getAvaliablePolicy(),
]);
}
+
+ public function RemoteDownload(){
+ $this->adminObj->listDownloads();
+ return view('download', [
+ 'options' => $this->siteOptions,
+ 'optionsForSet' => Option::getValues(["aria2"]),
+ 'list' => $this->adminObj->pageData,
+ 'originList' => $this->adminObj->listData,
+ 'pageNow' => $this->adminObj->pageNow,
+ 'pageTotal' => $this->adminObj->pageTotal,
+ 'dataTotal' => $this->adminObj->dataTotal,
+ ]);
+ }
+
+ public function CancelDownload(){
+ $aria2Options = Option::getValues(["aria2"]);
+ $aria2 = new \app\index\model\Aria2($aria2Options);
+ $downloadItem = Db::name("download")->where("id",input("post.id"))->find();
+ if(empty($downloadItem)){
+ return json(['error'=>1,'message'=>"未找到下载记录"]);
+ }
+ if($aria2->Remove($downloadItem["pid"],"")){
+ return json(['error'=>0,'message'=>"下载已取消"]);
+ }else{
+ return json(['error'=>1,'message'=>"取消失败"]);
+ }
+ }
}
diff --git a/application/index/controller/RemoteDownload.php b/application/index/controller/RemoteDownload.php
index d09d0f77..e16a1c53 100644
--- a/application/index/controller/RemoteDownload.php
+++ b/application/index/controller/RemoteDownload.php
@@ -129,7 +129,7 @@ class RemoteDownload extends Controller{
}
public function ListDownloading(){
- $downloadItems = Db::name("download")->where("owner",$this->userObj->uid)->where("status","in",["active","ready"])->order('id desc')->select();
+ $downloadItems = Db::name("download")->where("owner",$this->userObj->uid)->where("status","in",["active","ready","waiting"])->order('id desc')->select();
foreach ($downloadItems as $key => $value) {
$connectInfo = json_decode($value["info"],true);
if(isset($connectInfo["dir"])){
@@ -153,7 +153,7 @@ class RemoteDownload extends Controller{
public function ListFinished(){
$page = input("get.page");
- $downloadItems = Db::name("download")->where("owner",$this->userObj->uid)->where("status","not in",["active","ready"])->order('id desc')->page($page.',10')->select();
+ $downloadItems = Db::name("download")->where("owner",$this->userObj->uid)->where("status","not in",["active","ready","waiting"])->order('id desc')->page($page.',10')->select();
foreach ($downloadItems as $key => $value) {
$connectInfo = json_decode($value["info"],true);
if(isset($connectInfo["dir"])){
diff --git a/application/index/model/AdminHandler.php b/application/index/model/AdminHandler.php
index 0fa28a24..733d3b67 100644
--- a/application/index/model/AdminHandler.php
+++ b/application/index/model/AdminHandler.php
@@ -104,6 +104,10 @@ class AdminHandler extends Model{
return $this->saveOptions($options);
}
+ public function saveAria2Setting($options){
+ return $this->saveOptions($options);
+ }
+
public function saveMailTemplate($options){
return $this->saveOptions($options);
}
@@ -113,6 +117,7 @@ class AdminHandler extends Model{
unset($options["sizeTimes"]);
$options["grade_policy"] = 0;
$options["policy_list"] = $options["policy_name"];
+ $options["aria2"] = $options["aria2"] ? "1,1,1" : "0,0,0";
try {
Db::name("groups")->insert($options);
} catch (Exception $e) {
@@ -347,6 +352,46 @@ class AdminHandler extends Model{
return $userData;
}
+ public function listDownloads(){
+ $pageSize = 10;
+ $this->pageData = Db::name("download")
+ ->order("id desc")
+ ->paginate($pageSize);
+ $this->dataTotal = Db::name("download")
+ ->order("id desc")
+ ->count();
+ $this->pageTotal = ceil($this->dataTotal/$pageSize);
+ $this->listData = $this->pageData->all();
+ $userCache=[];
+ $userCacheList=[];
+ foreach ($this->listData as $key => $value) {
+ if(in_array($value["owner"], $userCacheList)){
+ $this->listData[$key]["user"] = $userCache[$value["owner"]];
+ }else{
+ $this->listData[$key]["user"] = Db::name("users")->where("id",$value["owner"])->find();
+ array_push($userCacheList,$value["owner"]);
+ $userCache[$value["owner"]] = $this->listData[$key]["user"];
+ }
+ $connectInfo = json_decode($value["info"],true);
+ if(isset($connectInfo["dir"])){
+ $this->listData[$key]["fileName"] = basename($connectInfo["dir"]);
+ $this->listData[$key]["completedLength"] = $connectInfo["completedLength"];
+ $this->listData[$key]["totalLength"] = $connectInfo["totalLength"];
+ $this->listData[$key]["downloadSpeed"] = $connectInfo["downloadSpeed"];
+ }else{
+ if(floor($value["source"])==$value["source"]){
+ $this->listData[$key]["fileName"] = Db::name("files")->where("id",$value["source"])->column("orign_name")[0];
+ }else{
+ $this->listData[$key]["fileName"] = $value["source"];
+ }
+ $this->listData[$key]["completedLength"] = 0;
+ $this->listData[$key]["totalLength"] = 0;
+ $this->listData[$key]["downloadSpeed"] = 0;
+ }
+ }
+ $this->pageNow = input("?get.page")?input("get.page"):1;
+ }
+
public function listFile(){
$pageSize = !cookie('?pageSize') ? 10 : cookie('pageSize');
$orderType = empty(cookie('orderMethodFile')) ? "id DESC" : cookie('orderMethodFile');
diff --git a/application/index/model/Aria2.php b/application/index/model/Aria2.php
index 4fa1745b..88b571f4 100644
--- a/application/index/model/Aria2.php
+++ b/application/index/model/Aria2.php
@@ -42,7 +42,7 @@ class Aria2 extends Model{
$this->pid = $respondData["result"];
}else{
$this->reqStatus = 0;
- $this->reqMsg = $respondData["error"]["message"];
+ $this->reqMsg = isset($respondData["error"]["message"]) ? $respondData["error"]["message"] : $this->reqMsg;
}
}
@@ -70,6 +70,11 @@ class Aria2 extends Model{
public function flushStatus($id,$uid,$policy){
$this->uid = $uid;
+ if(empty($policy)){
+ $user = Db::name("users")->where("id",$uid)->find();
+ $group = Db::name("groups")->where("id",$user["user_group"])->find();
+ $policy = Db::name("policy")->where("id",$group["policy_name"])->find();
+ }
$this->policy = $policy;
$downloadInfo = Db::name("download")->where("id",$id)->find();
if(empty($downloadInfo)){
@@ -148,15 +153,15 @@ class Aria2 extends Model{
}else{
$this->reqStatus = 0;
$this->reqMsg = $respondData["error"]["message"];
- $this->setError($respondData,$downloadInfo,$respondData["error"]["message"],"error",false);
+ $this->setError($respondData,$downloadInfo,$respondData["error"]["message"],"error",true);
return false;
}
return true;
}
private function setCanceled($quenInfo,$sqlData){
- @self::remove_directory(ROOT_PATH."public".DS."downloads".DS.$sqlData["path_id"]);
- if(!is_dir(ROOT_PATH."public".DS."downloads".DS.$sqlData["path_id"])){
+ @self::remove_directory($this->savePath.$sqlData["path_id"]);
+ if(!is_dir($this->savePath.$sqlData["path_id"])){
Db::name("download")->where("id",$sqlData["id"])->update([
"status" => "canceled",
]);
diff --git a/application/index/model/CronHandler.php b/application/index/model/CronHandler.php
index d57314d7..64263a46 100644
--- a/application/index/model/CronHandler.php
+++ b/application/index/model/CronHandler.php
@@ -7,6 +7,7 @@ use \think\Session;
use \app\index\model\FileManage;
use \app\index\model\Option;
use \app\index\model\Mail;
+use \app\index\model\Aria2;
class CronHandler extends Model{
@@ -40,6 +41,11 @@ class CronHandler extends Model{
$this->deleteCallbackData($value["interval_s"]);
}
break;
+ case 'flush_aria2':
+ if($this->checkInterval($value["interval_s"],$value["last_excute"])){
+ $this->flushAria2($value["interval_s"]);
+ }
+ break;
default:
# code...
break;
@@ -69,5 +75,21 @@ class CronHandler extends Model{
$this->setComplete("delete_callback_data");
}
+ public function flushAria2($interval){
+ echo("flushingAria2Status...");
+ $aria2Options = Option::getValues(["aria2"]);
+ $aria2 = new Aria2($aria2Options);
+ $toBeFlushed = Db::name("download")
+ ->where("status","<>","complete")
+ ->where("status","<>","error")
+ ->where("status","<>","canceled")
+ ->select();
+ foreach ($toBeFlushed as $key => $value) {
+ $aria2->flushStatus($value["id"],$value["owner"],null);
+ }
+ echo("Complete
");
+ $this->setComplete("flush_aria2");
+ }
+
}
?>
\ No newline at end of file
diff --git a/application/index/view/admin/add_group.html b/application/index/view/admin/add_group.html
index 7e190809..b4c2aee8 100644
--- a/application/index/view/admin/add_group.html
+++ b/application/index/view/admin/add_group.html
@@ -113,6 +113,18 @@
# | +文件名 | +创建者 | +文件大小 | +状态 | +进度 | +操作 | +
---|---|---|---|---|---|---|
{$download.id} | +{:$originList[$key]['fileName']} | +{:$originList[$key]['user']["user_nick"]} | +{:countSize($download.total_size)} | +{$download.status} | +{:floor($originList[$key]['completedLength']/$originList[$key]['totalLength']*10000)/100}% | +{eq name="download.status" value="active"}取消任务{else/} - {/eq} | +