diff --git a/application/index/controller/RemoteDownload.php b/application/index/controller/RemoteDownload.php
index 8046c9f3..6bbe1222 100644
--- a/application/index/controller/RemoteDownload.php
+++ b/application/index/controller/RemoteDownload.php
@@ -47,7 +47,7 @@ class RemoteDownload extends Controller{
public function addUrl(){
$policyData = Db::name("policy")->where("id",$this->userObj->groupData["policy_name"])->find();
- if(!$this->checkPerimission(0) || $policyData["policy_type"] != "local"){
+ if(!$this->checkPerimission(0) || ($policyData["policy_type"] != "local" && $policyData["policy_type"] != "onedrive")){
return json(["result"=>['success'=>false,'error'=>"您当前的无用户无法执行此操作"]]);
}
$aria2Options = Option::getValues(["aria2"]);
diff --git a/application/index/model/AdminHandler.php b/application/index/model/AdminHandler.php
index 91470f70..730a75ce 100644
--- a/application/index/model/AdminHandler.php
+++ b/application/index/model/AdminHandler.php
@@ -756,35 +756,5 @@ class AdminHandler extends Model{
]);
}
- public function oneDriveTest(){
- $policyId =1;
- $policyData = Db::name("policy")->where("id",$policyId)->find();
-
- $onedrive = new Client([
- 'stream_back_end' => \Krizalys\Onedrive\StreamBackEnd::TEMP,
- 'client_id' => $policyData["bucketname"],
-
- // Restore the previous state while instantiating this client to proceed in
- // obtaining an access token.
- 'state' => json_decode($policyData["sk"]),
- ]);
- $onedrive->renewAccessToken($policyData["ak"]);
- Db::name("policy")->where("id",$policyId)->update([
- "sk" => json_encode($onedrive->getState()),
- ]);
- // $file = fopen("C:/Users/i/Downloads/Video/test.mp4","r");
- // $onedrive->createFile(urlencode("Git提交代码简教程.txt"),"/me/drive/root:/sdfdsf",$file);
- //$uploadUrl = $onedrive->apiPost("/me/drive/root:/test.m4a:/createUploadSession",[])->uploadUrl;
- //echo $uploadUrl;
- // $file = fopen("F:/qampp/htdocs/public/uploads/chunks/oDAjV3vT.chunk","r");
- // $chunksize = filesize("F:/qampp/htdocs/public/uploads/chunks/oDAjV3vT.chunk");
- // $headers[] = "Content-Length: ".$chunksize;
- // $headers[] = "Content-Range: bytes 8388608-".(8388608+$chunksize-1)."/11628372";
- // var_dump($headers);
- // var_dump($onedrive->sendFileChunk("https://cquedu-my.sharepoint.com/personal/abslant_cquedu_onmicrosoft_com/_api/v2.0/drive/items/013RFVFIF6Y2GOVW7725BZO354PWSELRRZ/uploadSession?guid='0fa969a7-72d6-411f-9538-fc456913ff34'&path='~tmp41_test.m4a'&overwrite=True&rename=False&dc=0&tempauth=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvY3F1ZWR1LW15LnNoYXJlcG9pbnQuY29tQGQwZDgxY2Q1LTgwNjUtNDYwNS1hODg2LTFjODllN2UwNzc4ZSIsImlzcyI6IjAwMDAwMDAzLTAwMDAtMGZmMS1jZTAwLTAwMDAwMDAwMDAwMCIsIm5iZiI6IjE1MzYyMjM4NDYiLCJleHAiOiIxNTM2MzEwMjQ2IiwiZW5kcG9pbnR1cmwiOiJ6Q1psKy9nVTJwdVErbFd3Q29hM0dlOEMxMzgxNjJFcVJ5ZVdkNzFKUE40PSIsImVuZHBvaW50dXJsTGVuZ3RoIjoiMjQzIiwiaXNsb29wYmFjayI6IlRydWUiLCJjaWQiOiJOalppWlRVeE9UQXRNVGM1T1MwME0yVmtMV0U0T1RJdFpqZzFZbUpoT0RSbU9HRmwiLCJ2ZXIiOiJoYXNoZWRwcm9vZnRva2VuIiwic2l0ZWlkIjoiWXpVNE1UTTNOekF0WlRZNE1pMDBNVE14TFdFME5UVXRaVE5rWldVM1ptWmxPR1JrIiwiYXBwX2Rpc3BsYXluYW1lIjoiQ2xvdWRyZXZlRGV2IiwiYXBwaWQiOiJjNWM0Zjk3ZC1mOWIwLTQzNjAtOWEzZS0xM2JiM2MyNzZkYWEiLCJ0aWQiOiJkMGQ4MWNkNS04MDY1LTQ2MDUtYTg4Ni0xYzg5ZTdlMDc3OGUiLCJ1cG4iOiJhYnNsYW50QGNxdWVkdS5vbm1pY3Jvc29mdC5jb20iLCJwdWlkIjoiMTAwMzdGRkVBRDdGRjJDMyIsInNjcCI6ImFsbGZpbGVzLndyaXRlIiwidHQiOiIyIiwidXNlUGVyc2lzdGVudENvb2tpZSI6bnVsbH0.aWh2N2szZE4rRDhXdUp3Vm9GWnlUcHczMzhaWXJrY1diVklyRWtzTlhTOD0",$headers,$file));
- // fclose($file);
- }
-
-
}
?>
\ No newline at end of file
diff --git a/application/index/model/Aria2.php b/application/index/model/Aria2.php
index 1340b9a1..0f007ae6 100644
--- a/application/index/model/Aria2.php
+++ b/application/index/model/Aria2.php
@@ -24,6 +24,12 @@ class Aria2 extends Model{
$this->savePath = rtrim(rtrim($options["aria2_tmppath"],"/"),"\\").DS;
}
+ /**
+ * 新建普通URL下载任务
+ *
+ * @param string $url
+ * @return void
+ */
public function addUrl($url){
$this->pathId = uniqid();
$reqFileds = [
@@ -46,6 +52,12 @@ class Aria2 extends Model{
}
}
+ /**
+ * 新建种子下载任务
+ *
+ * @param string $torrentUrl 种子URL
+ * @return void
+ */
public function addTorrent($torrentUrl){
$this->pathId = uniqid();
$reqFileds = [
@@ -68,6 +80,14 @@ class Aria2 extends Model{
}
}
+ /**
+ * 刷新下载状态
+ *
+ * @param int $id 任务ID
+ * @param int $uid 用户ID
+ * @param array $policy 上传策略
+ * @return void
+ */
public function flushStatus($id,$uid,$policy){
$this->uid = $uid;
if(empty($policy)){
@@ -159,6 +179,13 @@ class Aria2 extends Model{
return true;
}
+ /**
+ * 取消任务
+ *
+ * @param array $quenInfo 任务信息(aria2)
+ * @param array $sqlData 任务信息(数据库)
+ * @return void
+ */
private function setCanceled($quenInfo,$sqlData){
@self::remove_directory($this->savePath.$sqlData["path_id"]);
if(!is_dir($this->savePath.$sqlData["path_id"])){
@@ -168,6 +195,12 @@ class Aria2 extends Model{
}
}
+ /**
+ * 移除整个目录
+ *
+ * @param string $dir
+ * @return void
+ */
static function remove_directory($dir){
if($handle=opendir("$dir")){
while(false!==($item=readdir($handle))){
@@ -184,6 +217,13 @@ class Aria2 extends Model{
}
}
+ /**
+ * 将单文件任务升级至多文件任务
+ *
+ * @param array $quenInfo
+ * @param array $sqlData
+ * @return void
+ */
private function updateToMuiltpe($quenInfo,$sqlData){
foreach ($quenInfo["files"] as $key => $value) {
Db::name("download")->insert([
@@ -203,8 +243,16 @@ class Aria2 extends Model{
Db::name("download")->where("id",$sqlData["id"])->delete();
}
+ /**
+ * 下载完成后续处理
+ *
+ * @param array $quenInfo
+ * @param array $sqlData
+ * @param int $fileIndex
+ * @return void
+ */
private function setComplete($quenInfo,$sqlData,$fileIndex=null){
- if($this->policy["policy_type"] != "local"){
+ if($this->policy["policy_type"] != "local" && $this->policy["policy_type"] != "onedrive"){
$this->setError($quenInfo,$sqlData,"您当前的上传策略无法使用离线下载");
return false;
}
@@ -230,27 +278,64 @@ class Aria2 extends Model{
$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"][$sqlData["file_index"]]["path"],$savePath);
- @unlink(dirname($quenInfo["files"][$sqlData["file_index"]]["path"]));
- $jsonData = array(
- "path" => ltrim(str_replace("/", ",", $sqlData["save_dir"]),","),
- "fname" => basename($quenInfo["files"][$sqlData["file_index"]]["path"]),
- "objname" => $generatePath.DS.$fileName,
- "fsize" => $quenInfo["files"][$sqlData["file_index"]]["length"],
- );
- @list($width, $height, $type, $attr) = getimagesize($savePath);
- $picInfo = empty($width)?" ":$width.",".$height;
- $addAction = FileManage::addFile($jsonData,$this->policy,$this->uid,$picInfo);
- if(!$addAction[0]){
- //取消任务
- $this->setError($quenInfo,$sqlData,$addAction[1]);
- return false;
+
+ if($this->policy["policy_type"] == "onedrive"){
+
+ $savePath = ROOT_PATH . 'public/uploads/'.$generatePath.DS.$fileName;
+ $task = new Task();
+ $task->taskName = "Upload RemoteDownload File " . $quenInfo["files"][$sqlData["file_index"]]["path"] . " to Onedrive";
+ $task->taskType = $quenInfo["files"][$sqlData["file_index"]]["length"]<=4*1024*1024 ? "UploadRegularRemoteDownloadFileToOnedrive" :"UploadLargeRemoteDownloadFileToOnedrive";
+ @list($width, $height, $type, $attr) = getimagesize($quenInfo["files"][$sqlData["file_index"]]["path"]);
+ $picInfo = empty($width)?"":$width.",".$height;
+ $task->taskContent = json_encode([
+ "path" => ltrim(str_replace("/", ",", $sqlData["save_dir"]),","),
+ "fname" => basename($quenInfo["files"][$sqlData["file_index"]]["path"]),
+ "originPath" => $quenInfo["files"][$sqlData["file_index"]]["path"],
+ "objname" => $fileName,
+ "savePath" => $generatePath,
+ "fsize" => $quenInfo["files"][$sqlData["file_index"]]["length"],
+ "picInfo" => $picInfo,
+ "policyId" => $this->policy["id"],
+ ]);
+ $task->userId = $this->uid;
+ $task->saveTask();
+
+ }else{
+
+ $savePath = ROOT_PATH . 'public/uploads/'.$generatePath.DS.$fileName;
+ is_dir(dirname($savePath))? :mkdir(dirname($savePath),0777,true);
+ rename($quenInfo["files"][$sqlData["file_index"]]["path"],$savePath);
+ @unlink(dirname($quenInfo["files"][$sqlData["file_index"]]["path"]));
+ $jsonData = array(
+ "path" => ltrim(str_replace("/", ",", $sqlData["save_dir"]),","),
+ "fname" => basename($quenInfo["files"][$sqlData["file_index"]]["path"]),
+ "objname" => $generatePath.DS.$fileName,
+ "fsize" => $quenInfo["files"][$sqlData["file_index"]]["length"],
+ );
+ @list($width, $height, $type, $attr) = getimagesize($savePath);
+ $picInfo = empty($width)?" ":$width.",".$height;
+ $addAction = FileManage::addFile($jsonData,$this->policy,$this->uid,$picInfo);
+ if(!$addAction[0]){
+ //取消任务
+ $this->setError($quenInfo,$sqlData,$addAction[1]);
+ return false;
+ }
+
}
+
FileManage::storageCheckOut($this->uid,$quenInfo["files"][$sqlData["file_index"]]["length"]);
}
+ /**
+ * 设置任务为失败状态
+ *
+ * @param array $quenInfo
+ * @param array $sqlData
+ * @param string $msg 失败消息
+ * @param string $status 状态
+ * @param boolean $delete 是否删除下载文件
+ * @return void
+ */
private function setError($quenInfo,$sqlData,$msg,$status="error",$delete=true){
$this->Remove($sqlData["pid"],$sqlData);
$this->removeDownloadResult($sqlData["pid"],$sqlData);
@@ -266,6 +351,13 @@ class Aria2 extends Model{
]);
}
+ /**
+ * 移除任务
+ *
+ * @param int $gid
+ * @param array $sqlData
+ * @return void
+ */
public function Remove($gid,$sqlData){
$reqFileds = [
"params" => ["token:".$this->authToken,$gid],
@@ -281,6 +373,13 @@ class Aria2 extends Model{
return false;
}
+ /**
+ * 删除下载结果
+ *
+ * @param int $gid
+ * @param array $sqlData
+ * @return void
+ */
public function removeDownloadResult($gid,$sqlData){
$reqFileds = [
"params" => ["token:".$this->authToken,$gid],
@@ -296,6 +395,12 @@ class Aria2 extends Model{
return false;
}
+ /**
+ * 强制移除任务
+ *
+ * @param int $gid
+ * @return void
+ */
public function forceRemove($gid){
$reqFileds = [
"params" => ["token:".$this->authToken,$gid],
@@ -311,6 +416,13 @@ class Aria2 extends Model{
return false;
}
+ /**
+ * 检查容量
+ *
+ * @param array $quenInfo
+ * @param array $sqlData
+ * @return void
+ */
private function storageCheck($quenInfo,$sqlData){
if(!FileManage::sotrageCheck($this->uid,$quenInfo["totalLength"])){
return false;
@@ -321,6 +433,12 @@ class Aria2 extends Model{
return true;
}
+ /**
+ * 发送请求
+ *
+ * @param string $data
+ * @return array
+ */
private function sendReq($data){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $this->apiUrl."jsonrpc");
diff --git a/application/index/model/CronHandler.php b/application/index/model/CronHandler.php
index 64263a46..5f7233ce 100644
--- a/application/index/model/CronHandler.php
+++ b/application/index/model/CronHandler.php
@@ -46,6 +46,11 @@ class CronHandler extends Model{
$this->flushAria2($value["interval_s"]);
}
break;
+ case 'flush_onedrive_token':
+ if($this->checkInterval($value["interval_s"],$value["last_excute"])){
+ $this->flushOnedriveToken($value["interval_s"]);
+ }
+ break;
default:
# code...
break;
@@ -91,5 +96,26 @@ class CronHandler extends Model{
$this->setComplete("flush_aria2");
}
+ public function flushOnedriveToken($interval){
+ echo("flushOnedriveToken...");
+ $toBeFlushedPolicy = Db::name("policy")->where("policy_type","onedrive")->select();
+ foreach ($toBeFlushedPolicy as $key => $value) {
+ $onedrive = new \Krizalys\Onedrive\Client([
+ 'stream_back_end' => \Krizalys\Onedrive\StreamBackEnd::TEMP,
+ 'client_id' => $value["bucketname"],
+
+ // Restore the previous state while instantiating this client to proceed in
+ // obtaining an access token.
+ 'state' => json_decode($value["sk"]),
+ ]);
+ $onedrive->renewAccessToken($value["ak"]);
+ Db::name("policy")->where("id",$value["id"])->update([
+ "sk" => json_encode($onedrive->getState()),
+ ]);
+ }
+ echo("Complete
");
+ $this->setComplete("flush_onedrive_token");
+ }
+
}
?>
\ No newline at end of file
diff --git a/application/index/model/Task.php b/application/index/model/Task.php
index 20413bad..9aa04561 100644
--- a/application/index/model/Task.php
+++ b/application/index/model/Task.php
@@ -58,17 +58,114 @@ class Task extends Model{
case "uploadSingleToOnedrive":
$this->uploadSingleToOnedrive();
break;
+ case "UploadRegularRemoteDownloadFileToOnedrive":
+ $this->uploadSingleToOnedrive();
+ break;
case "uploadChunksToOnedrive":
$this->uploadChunksToOnedrive();
break;
+ case "UploadLargeRemoteDownloadFileToOnedrive":
+ $this->uploadUnchunkedFile();
+ break;
default:
- $this->output->writeln("Unknown task type");
+ $this->output->writeln("Unknown task type (".$this->taskModel["type"].")");
+ break;
+ }
+ }
+
+ /**
+ * 上传未分片的大文件至Onedrive
+ *
+ * @return void
+ */
+ private function uploadUnchunkedFile(){
+ $this->taskContent = json_decode($this->taskModel["attr"],true);
+ $policyData = Db::name("policy")->where("id",$this->taskContent["policyId"])->find();
+ $this->policyModel = $policyData;
+ $onedrive = new Client([
+ 'stream_back_end' => \Krizalys\Onedrive\StreamBackEnd::TEMP,
+ 'client_id' => $policyData["bucketname"],
+
+ // Restore the previous state while instantiating this client to proceed in
+ // obtaining an access token.
+ 'state' => json_decode($policyData["sk"]),
+ ]);
+
+ //创建分片上传Session,获取上传URL
+ try{
+ $uploadUrl = $onedrive->apiPost("/me/drive/root:/".rawurlencode($this->taskContent["savePath"] . "/" . $this->taskContent["objname"]).":/createUploadSession",[])->uploadUrl;
+ }catch(\Exception $e){
+ $this->status="error";
+ $this->errorMsg = $e->getMessage();
+ $this->cleanTmpChunk();
+ return;
+ }
+ //创建分片上传Session,获取上传URL
+ try{
+ $uploadUrl = $onedrive->apiPost("/me/drive/root:/".rawurlencode($this->taskContent["savePath"] . "/" . $this->taskContent["objname"]).":/createUploadSession",[])->uploadUrl;
+ }catch(\Exception $e){
+ $this->status="error";
+ $this->errorMsg = $e->getMessage();
+ $this->cleanTmpChunk();
+ return;
+ }
+
+ //每次4MB上传文件
+
+ if(!$file = @fopen($this->taskContent["originPath"],"r")){
+ $this->status="error";
+ $this->errorMsg = "File not exist.";
+ $this->cleanTmpChunk();
+ return;
+ }
+ $offset = 0;
+ $totalSize = filesize($this->taskContent["originPath"]);
+ while (1) {
+ //移动文件指针
+ fseek($file, $offset);
+
+ $chunksize = (($offset+4*1024*1024)>$totalSize)?($totalSize-$offset):1024*4*1024;
+ $headers = [];
+ $headers[] = "Content-Length: ".$chunksize;
+ $headers[] = "Content-Range: bytes ".$offset."-".($offset+$chunksize-1)."/".$this->taskContent["fsize"];
+
+ //发送单个分片数据
+ try{
+ $onedrive->sendFileChunk($uploadUrl,$headers,fread($file,$chunksize));
+ }catch(\Exception $e){
+ $this->status="error";
+ $this->errorMsg = $e->getMessage();
+ $this->cleanTmpChunk();
+ return;
+ }
+ $this->output->writeln("[Info] Chunk Uploaded. Offset:".$offset);
+ $offset+=$chunksize;
+ if($offset+1 >=$totalSize){
break;
+ }
+
}
+ fclose($file);
+ $jsonData = array(
+ "path" => $this->taskContent["path"],
+ "fname" => $this->taskContent["fname"],
+ "objname" => $this->taskContent["savePath"]."/".$this->taskContent["objname"],
+ "fsize" => $this->taskContent["fsize"],
+ );
+
+ $addAction = FileManage::addFile($jsonData,$policyData,$this->taskModel["uid"],$this->taskContent["picInfo"]);
+ if(!$addAction[0]){
+ $this->setError($addAction[1],true,"/me/drive/root:/".rawurlencode($this->taskContent["savePath"] . "/" . $this->taskContent["objname"]),$onedrive);
+ $this->cleanTmpChunk();
+ return;
+ }
+
+ $this->cleanTmpChunk();
+
}
/**
- * 上传 分片的大文件至Onedrive
+ * 上传已分片的大文件至Onedrive
*
* @return void
*/
@@ -162,7 +259,7 @@ class Task extends Model{
'state' => json_decode($policyData["sk"]),
]);
- $filePath = ROOT_PATH . 'public/uploads/'.$this->taskContent["savePath"] . "/" . $this->taskContent["objname"];
+ $filePath = $this->taskModel["type"] == "UploadRegularRemoteDownloadFileToOnedrive"?$this->taskContent["originPath"]:ROOT_PATH . 'public/uploads/'.$this->taskContent["savePath"] . "/" . $this->taskContent["objname"];
if($file = @fopen($filePath,"r")){
try{
$onedrive->createFile(rawurlencode($this->taskContent["objname"]),"/me/drive/root:/".$this->taskContent["savePath"],$file);
@@ -202,7 +299,12 @@ class Task extends Model{
* @return bool 是否成功
*/
private function cleanTmpFile(){
- return @unlink(ROOT_PATH . 'public/uploads/'.$this->taskContent["savePath"] . "/" . $this->taskContent["objname"]);
+ if($this->taskModel["type"] == "UploadRegularRemoteDownloadFileToOnedrive"){
+ return @unlink($this->taskContent["originPath"]);
+ }else{
+ return @unlink(ROOT_PATH . 'public/uploads/'.$this->taskContent["savePath"] . "/" . $this->taskContent["objname"]);
+ }
+
}
/**
@@ -211,8 +313,12 @@ class Task extends Model{
* @return void
*/
private function cleanTmpChunk(){
- foreach ($this->taskContent["chunks"] as $key => $value) {
- @unlink( ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
+ if($this->taskModel["type"] == "UploadLargeRemoteDownloadFileToOnedrive"){
+ @unlink($this->taskContent["originPath"]);
+ }else{
+ foreach ($this->taskContent["chunks"] as $key => $value) {
+ @unlink( ROOT_PATH . 'public/uploads/chunks/'.$value["obj_name"].".chunk");
+ }
}
}
diff --git a/application/index/view/member/login.html b/application/index/view/member/login.html
index 193afd30..467c7dd1 100644
--- a/application/index/view/member/login.html
+++ b/application/index/view/member/login.html
@@ -57,7 +57,7 @@
{else/}
{/eq}
-
+