disktag = $tag;
$this->redirect_uri = 'https://scfonedrive.github.io';
if (getConfig('client_id', $tag) && getConfig('client_secret', $tag)) {
$this->client_id = getConfig('client_id', $tag);
$this->client_secret = getConfig('client_secret', $tag);
} else {
$this->client_id = '106151778902-ajieetaab5ondhbvia97n4tr5k0cg8eo.apps.googleusercontent.com';
$this->client_secret = 'LlCV-rQClzYIKCEqiVddh68G';
}
//$this->oauth_url = 'https://www.googleapis.com/oauth2/v4/';
$this->oauth_url = 'https://accounts.google.com/o/oauth2/';
$this->api_url = 'https://www.googleapis.com/drive/v3';
$this->scope = 'https://www.googleapis.com/auth/drive';
$this->client_secret = urlencode($this->client_secret);
$this->scope = urlencode($this->scope);
//$this->DownurlStrName = '@microsoft.graph.downloadUrl';
//$this->ext_api_url = '/me/drive/root';
$this->driveId = getConfig('driveId', $tag);
$res = $this->get_access_token(getConfig('refresh_token', $tag));
}
public function isfine()
{
if (!$this->access_token) return false;
else return true;
}
public function show_base_class()
{
return get_class();
//$tmp[0] = get_class();
//$tmp[1] = get_class($this);
//return $tmp;
}
public function ext_show_innerenv()
{
return ['driveId'];
}
public function list_files($path = '/')
{
$files = $this->list_path($path);
return $this->files_format($files);
}
protected function files_format($files)
{
if (isset($files['files']) || (isset($files['mimeType'])&&$files['mimeType']=='application/vnd.google-apps.folder') ) {
$tmp['type'] = 'folder';
$tmp['id'] = $files['id'];
$tmp['name'] = $files['name'];
$tmp['time'] = $files['modifiedTime'];
$tmp['size'] = $files['size'];
$tmp['childcount'] = $files['folder']['childCount'];
$tmp['page'] = $files['folder']['page'];
foreach ($files['files'] as $file) {
$filename = strtolower($file['name']);
if ($file['mimeType']=='application/vnd.google-apps.folder') {
$tmp['list'][$filename]['type'] = 'folder';
} else {
$tmp['list'][$filename]['type'] = 'file';
//var_dump($file);
//echo $file['name'] . ':' . $this->DownurlStrName . ':' . $file[$this->DownurlStrName] . PHP_EOL;
$tmp['list'][$filename]['url'] = ($file['downUrl']?$file['downUrl']:$file['webContentLink']);
$tmp['list'][$filename]['mime'] = $file['mimeType'];
}
$tmp['list'][$filename]['id'] = $file['id'];
$tmp['list'][$filename]['name'] = $file['name'];
$tmp['list'][$filename]['time'] = $file['modifiedTime'];
$tmp['list'][$filename]['size'] = $file['size'];
}
} elseif (isset($files['mimeType'])) {
$tmp['type'] = 'file';
$tmp['id'] = $files['id'];
$tmp['name'] = $files['name'];
$tmp['time'] = $files['modifiedTime'];
$tmp['size'] = $files['size'];
$tmp['mime'] = $files['mimeType'];
$tmp['url'] = ($files['downUrl']?$files['downUrl']:$files['webContentLink']);
$tmp['content'] = $files['content'];
} else/*if (isset($files['error']))*/ {
return $files;
}
//error_log1(json_encode($tmp));
return $tmp;
}
protected function list_path($path = '/')
{
global $exts;
while (substr($path, -1)=='/') $path = substr($path, 0, -1);
if ($path == '') $path = '/';
if (!($files = getcache('path_' . $path, $this->disktag))) {
//$response = curl('GET', $this->api_url . '/drives', '', ['Authorization' => 'Bearer ' . $this->access_token]);
//$response = curl('GET', $this->api_url . '/files?fields=*,files(id,name,mimeType,size,modifiedTime,parents,webContentLink,thumbnailLink),nextPageToken' . (($this->driveId!='')?'&driveId=' . $this->driveId . '&corpora=teamDrive&includeItemsFromAllDrives=true&supportsAllDrives=true':''), '', ['Authorization' => 'Bearer ' . $this->access_token]);
if ($path == '/' || $path == '') {
$files = $this->fileList();
//error_log1('root_id' . $files['id']);
//$files['id'] = 'root';
//$files['type'] = 'folder';
} else {
$tmp = splitlast($path, '/');
$parent_path = $tmp[0];
$filename = urldecode($tmp[1]);
$parent_folder = $this->list_path($parent_path);
$i = 0;
foreach ($parent_folder['files'] as $item) {
if ($item['name']==$filename) {
if ($item['mimeType']=='application/vnd.google-apps.folder') {
$files = $this->fileList($item['id']);
$files['type'] = 'folder';
$files['id'] = $item['id'];
$files['name'] = $item['name'];
$files['time'] = $item['modifiedTime'];
$files['size'] = $item['size'];
} else {
if (isset($item['id'])&&$item['shared']!==true) $this->permission('create', $item['id']);
//$this->permission('delete', $files['id']);
//if (isset($item['mimeType']) && $item['mimeType']!='application/vnd.google-apps.folder') {
if (in_array(strtolower(splitlast($item['name'],'.')[1]), $exts['txt'])) {
if ($files['size']<1024*1024) {
if (!(isset($item['content'])&&$item['content']['stat']==200)) {
//if (!isset($item['downUrl'])) {
$res = curl('GET', $item['webContentLink'], '', [], 1);
$weblink = $res['returnhead']['Location'];
//if ($weblink!==null) $item['downUrl'] = $weblink;
//else error_log1('Cant get link:' . json_encode($res, JSON_PRETTY_PRINT));
//}
if ($res['stat']==302) {
$content1 = curl('GET', $weblink, '', ["User-Agent"=>"qkqpttgf/OneManager 3.0.0", "Accept"=>"*/*"]);
$tmp = null;
$tmp = json_decode(json_encode($content1), true);
if ($tmp['body']===null) {
$tmp['body'] = iconv("GBK", 'UTF-8//TRANSLIT', $content1['body']);
$tmp = json_decode(json_encode($tmp), true);
if ($tmp['body']!==null) $content1['body'] = $tmp['body'];
}
$item['content'] = $content1;
}// else $content1 = $res;
//error_log1($item['name'] . '~' . json_encode($content1, JSON_PRETTY_PRINT) . PHP_EOL);
$parent_folder['files'][$i] = $item;
savecache('path_' . $path, $parent_folder, $this->disktag);
}
} else {
$files['content']['stat'] = 202;
$files['content']['body'] = 'File too large.';
}
}
//}
//error_log1(json_encode($item, JSON_PRETTY_PRINT));
$files = $item;
}
}
$i++;
}
//echo $files['name'];
}
if (!$files) {
$files['error']['code'] = 'Not Found';
$files['error']['message'] = 'Not Found';
$files['error']['stat'] = 404;
} elseif (isset($files['stat'])) {
$files['error']['stat'] = $files['stat'];
$files['error']['code'] = 'Error';
$files['error']['message'] = $files['body'];
} else {
savecache('path_' . $path, $files, $this->disktag, 600);
}
}
//error_log1('path:' . $path . ', files:' . json_encode($files, JSON_PRETTY_PRINT));
//error_log1('path:' . $path . ', files:' . substr(json_encode($files), 0, 150));
return $files;
}
protected function fileList($parent_file_id = '')
{
$url = $this->api_url . '/files';
$url .= '?fields=files(id,name,mimeType,size,modifiedTime,parents,webContentLink,thumbnailLink,shared,permissions,permissionIds),nextPageToken';
//$url .= '?fields=files(*),nextPageToken';
//$url .= '?q=mimeType=\'application/vnd.google-apps.folder\'';
if ($parent_file_id!='') {
$q = $parent_file_id;
} else {
$q = $this->driveId;
}
$q = '\'' . $q . '\' in parents and trashed = false';
$q = urlencode($q);
$url .= '&q=' . $q;
if ($this->driveId!='root') $url .= '&driveId=' . $this->driveId . '&corpora=teamDrive&includeItemsFromAllDrives=true&supportsAllDrives=true';
$header['Authorization'] = 'Bearer ' . $this->access_token;
$res = curl('GET', $url, '', $header);
if ($res['stat']==200) return json_decode($res['body'], true);
else return $res;
}
protected function permission($op, $fileId)
{
$url = $this->api_url . '/files/' . $fileId . '/permissions';
if ($op=='create') {
$method = 'POST';
$header['Content-Type'] = 'application/json';
$tmp['role'] = 'reader';
$tmp['type'] = 'anyone';
$data = json_encode($tmp);
} elseif ($op=='delete') {
$url .= '/anyoneWithLink';
$method = 'DELETE';
$data = '';
} else {
return false;
}
$url .= '?supportsAllDrives=true';
$header['Authorization'] = 'Bearer ' . $this->access_token;
$res = curl($method, $url, $data, $header);
//error_log1('Set Share' . json_encode($res, JSON_PRETTY_PRINT));
return $res;
}
public function Rename($file, $newname) {
$url = $this->api_url . '/files/' . $file['id'] . '?supportsAllDrives=true';
$tmp['name'] = $newname;
$result = $this->GDAPI('PATCH', $url, json_encode($tmp));
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function Delete($file) {
$url = $this->api_url . '/files/' . $file['id'] . '?supportsAllDrives=true';
$result = $this->GDAPI('DELETE', $url);
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function Encrypt($folder, $passfilename, $pass) {
$existfile = $this->list_path($folder['path'] . '/' . $passfilename);
if (isset($existfile['name'])) {
if ($pass==='') {
// 如果为空,删除
$this->Delete(['id'=>$existfile['id']]);
return output('Success', 200);
} else {
$result = $this->editFile($existfile['id'], $pass);
}
} else {
if (!$folder['id']) {
$res = $this->list_path($folder['path']);
//error_log1('res:' . json_encode($res));
$folder['id'] = $res['id'];
}
if (!$folder['id']) {
$folder['id'] = $this->driveId;
}
$result = $this->createFile_c($folder['id'], $passfilename, $pass);
}
//error_log1('2,url:' . $url .' res:' . json_encode($result));
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function Move($file, $folder) {
$nowParentId = $this->list_path($file['path'])['id'];
if (!$nowParentId) {
$nowParentId = $this->driveId;
}
if (!$folder['id']) {
$res = $this->list_path($folder['path']);
//error_log1('res:' . json_encode($res));
$folder['id'] = $res['id'];
}
if (!$folder['id']) {
$folder['id'] = $this->driveId;
}
$url = $this->api_url . '/files/' . $file['id'] . '?removeParents=' . $nowParentId . '&addParents=' . $folder['id'] . '&supportsAllDrives=true';
//$tmp['name'] = $newname;
$result = $this->GDAPI('PATCH', $url);
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function Copy($file) {
$url = $this->api_url . '/files/' . $file['id'] . '/copy?supportsAllDrives=true';
$namearr = splitlast($file['name'], '.');
date_default_timezone_set('UTC');
if ($namearr[0]!='') {
$newname = $namearr[0] . '_' . date("Ymd\_His");
if ($namearr[1]!='') $newname .= '.' . $namearr[1];
} else {
$newname = '.' . $namearr[1] . '_' . date("Ymd\_His");
}
$tmp['name'] = $newname;
$result = $this->GDAPI('POST', $url, json_encode($tmp));
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function Edit($file, $content) {
$tmp = splitlast($file['path'], '/');
$folderpath = $tmp[0];
$filename = $tmp[1];
$existfile = $this->list_path($file['path']);
if (isset($existfile['name'])) {
$result = $this->editFile($existfile['id'], $content);
} else {
$result = $this->createFile_c($this->list_path($folderpath)['id'], $filename, $content);
}
//error_log1('edit: ' . json_encode($result, JSON_PRETTY_PRINT));
if ($result['stat']==200) return output('success', 0);
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function Create($parent, $type, $name, $content = '') {
$filename = spurlencode($name);
$filename = path_format($parent['path'] . '/' . $filename);
$res = $this->list_path($filename);
//error_log1($filename . '查重:' . json_encode($res, JSON_PRETTY_PRINT) . PHP_EOL);
if (isset($res['name'])) {
$tmp['error']['code'] = 'File exist';
$tmp['error']['message'] = $res;
$tmp['error']['stat'] = 409;
return output(json_encode($this->files_format($tmp), JSON_PRETTY_PRINT), $tmp['error']['stat']);
}
if (!$parent['id']) {
$res = $this->list_path($parent['path']);
//error_log1('找ID:' . json_encode($res));
$parent['id'] = $res['id'];
}
if (!$parent['id']) {
$parent['id'] = $this->driveId;
}
if ($type=='file') {
$result = $this->createFile_c($parent['id'], $name, $content);
}
if ($type=='folder') {
$result = $this->createFolder($parent['id'], $name);
}
//error_log1('data:' . $data . ' res:' . json_encode($result, JSON_PRETTY_PRINT));
//savecache('path_' . $path1, json_decode('{}',true), $_SERVER['disktag'], 1);
return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']);
}
public function get_thumbnails_url($path = '/') {
$res = $this->list_path($path);
$thumb_url = $res['thumbnailLink'];
return $thumb_url;
}
public function bigfileupload($path) {
return output('Stop!\nCan not upload form explorer without token.', 403);
// https://developers.google.com/drive/api/v3/manage-uploads#http---multiple-requests
if ($_POST['upbigfilename']=='') return output('error: no file name', 400);
if (!is_numeric($_POST['filesize'])) return output('error: no file size', 400);
if (!$_SERVER['admin']) if (!isset($_POST['filemd5'])) return output('error: no file md5', 400);
$filename = $_POST['upbigfilename'];
$filename = path_format($path . '/' . $filename);
$res = $this->list_path($filename);
//error_log1($filename . '查重:' . json_encode($res, JSON_PRETTY_PRINT) . PHP_EOL);
if (isset($res['name'])) {
$tmp['error']['code'] = 'File exist';
$tmp['error']['message'] = json_encode($res);
$tmp['error']['stat'] = 409;
return output(json_encode($this->files_format($tmp), JSON_PRETTY_PRINT), $tmp['error']['stat']);
}
$tmp = splitlast($_POST['upbigfilename'], '/');
if ($tmp[1]!='') {
$fileinfo['name'] = $tmp[1];
if ($_SERVER['admin']) $fileinfo['path'] = $tmp[0];
} else {
$fileinfo['name'] = $_POST['upbigfilename'];
}
$fileinfo['size'] = $_POST['filesize'];
$fileinfo['filelastModified'] = $_POST['filelastModified'];
if ($_SERVER['admin']) {
$filename = $fileinfo['name'];
} else {
$tmp1 = splitlast($fileinfo['name'], '.');
if ($tmp1[0]==''||$tmp1[1]=='') $filename = $_POST['filemd5'];
else $filename = $_POST['filemd5'] . '.' . $tmp1[1];
}
$parent = $this->list_path($path . '/' . $fileinfo['path']);
if (isset($parent['id'])) {
$parent_file_id = $parent['id'];
} else {
$res = $this->createFolder($this->list_path($path)['id'], $fileinfo['path']);
//error_log1($res['body']);
$parent_file_id = json_decode($res['body'], true)['id'];
}
$url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable';
$res = $this->list_path($path);
//error_log1('找ID:' . json_encode($res));
$parentId = $res['id'];
if (!$parentId) {
$parentId = $this->driveId;
}
$tmp['name'] = $_POST['upbigfilename'];
$tmp['parents'][0] = $parentId;
$header['Authorization'] = 'Bearer ' . $this->access_token;
$header['Content-Type'] = 'application/json; charset=UTF-8';
//$header['Content-Length'] = '';
//$header['X-Upload-Content-Type'] = '';
//$header['X-Upload-Content-Length'] = $_POST['filesize'];
$response = curl('POST', $url, json_encode($tmp), $header, 1);
return output($response['returnhead']['Location'], $response['stat']);
}
protected function editFile($id, $content) {
$url = 'https://www.googleapis.com/upload/drive/v3/files/' . $id . '?uploadType=multipart&supportsAllDrives=true';
$boundary = md5($id . date());
$header['Content-Type'] = 'multipart/related; boundary=' . $boundary;
$header['Authorization'] = 'Bearer ' . $this->access_token;
$data = '--' . $boundary . "\r\n";
$data .= 'Content-Type: application/json; charset=UTF-8' . "\r\n";
$data .= "\r\n";
$data .= "\r\n";
$data .= "\r\n";
$data .= '--' . $boundary . "\r\n";
$data .= 'Content-Type: text/plain' . "\r\n";
$data .= "\r\n";
$data .= $content . "\r\n";
$data .= '--' . $boundary . "--";
$result = curl('PATCH', $url, $data, $header);
//error_log1('url: ' . $url . ' data: ' . $data . ' result: ' . json_encode($result, JSON_PRETTY_PRINT));
return $result;
}
protected function createFile_c($parentId, $name, $content) {
while (substr($name, 0, 1)=='/') $name = substr($name, 1);
while (substr($name, -1)=='/') $name = substr($name, 0, -1);
if (strpos($name, '/')>0) {
$p = splitlast($name, '/');
$res = $this->createFolder($parentId, $p[0]);
$parentId = json_decode($res['body'], true)['id'];
$name = $p[1];
}
$url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsAllDrives=true';
$tmp['name'] = $name;
$tmp['parents'][0] = $parentId;
$boundary = md5($name . date());
$header['Content-Type'] = 'multipart/related; boundary=' . $boundary;
$header['Authorization'] = 'Bearer ' . $this->access_token;
$data = '--' . $boundary . "\r\n";
$data .= 'Content-Type: application/json; charset=UTF-8' . "\r\n";
$data .= "\r\n";
$data .= json_encode($tmp, JSON_PRETTY_PRINT) . "\r\n";
$data .= "\r\n";
$data .= '--' . $boundary . "\r\n";
$data .= 'Content-Type: text/plain' . "\r\n";
$data .= "\r\n";
$data .= $content . "\r\n";
$data .= '--' . $boundary . "--";
$result = curl('POST', $url, $data, $header);
return $result;
}
protected function createFolder($parentId, $name) {
while (substr($name, 0, 1)=='/') $name = substr($name, 1);
while (substr($name, -1)=='/') $name = substr($name, 0, -1);
if (strpos($name, '/')>0) {
$p = splitlast($name, '/');
$res = $this->createFolder($parentId, $p[0]);
$parentId = json_decode($res['body'], true)['id'];
$name = $p[1];
}
$url = $this->api_url . '/files?&supportsAllDrives=true';
$tmp['name'] = $name;
$tmp['parents'][0] = $parentId;
$tmp['mimeType'] = 'application/vnd.google-apps.folder';
$data = json_encode($tmp);
$header['Content-Type'] = 'application/json; charset=UTF-8';
$header['Authorization'] = 'Bearer ' . $this->access_token;
$result = curl('POST', $url, $data, $header);
return $result;
}
public function AddDisk() {
global $constStr;
global $EnvConfigs;
$envs = '';
foreach ($EnvConfigs as $env => $v) if (isCommonEnv($env)) $envs .= '\'' . $env . '\', ';
$url = path_format($_SERVER['PHP_SELF'] . '/');
if (isset($_GET['Finish'])) {
if ($this->access_token == '') {
$refresh_token = getConfig('refresh_token', $this->disktag);
if (!$refresh_token) {
$html = 'No refresh_token config, please AddDisk again or wait minutes.
' . $this->disktag;
$title = 'Error';
return message($html, $title, 201);
}
$response = $this->get_access_token($refresh_token);
if (!$response) return message($this->error['body'], 'Error', $this->error['stat']);
}
$tmp = null;
if ($_POST['DriveType']=='Googledrive') {
$tmp['driveId'] = 'root';
} else {
// 直接是id
$tmp['driveId'] = $_POST['DriveType'];
}
$response = setConfigResponse( setConfig($tmp, $this->disktag) );
if (api_error($response)) {
$html = api_error_msg($response);
$title = 'Error';
return message($html, $title, 201);
} else {
$str .= '';
return message($str, getconstStr('WaitJumpIndex'), 201);
}
}
if (isset($_GET['SelectDrive'])) {
if ($this->access_token == '') {
$refresh_token = getConfig('refresh_token', $this->disktag);
if (!$refresh_token) {
$html = 'No refresh_token config, please AddDisk again or wait minutes.
' . $this->disktag;
$title = 'Error';
return message($html, $title, 201);
}
$response = $this->get_access_token($refresh_token);
if (!$response) return message($this->error['body'], 'Error', $this->error['stat']);
}
$api = $this->api_url . '/drives';
$arr = curl('GET', $api, '', [ 'Authorization' => 'Bearer ' . $this->access_token ]);
//if (!($arr['stat']==200||$arr['stat']==403||$arr['stat']==400||$arr['stat']==404))
if ($arr['stat']!=200) return message($arr['stat'] . json_encode(json_decode($arr['body']), JSON_PRETTY_PRINT), 'Get followedSites', $arr['stat']);
error_log1($arr['body']);
$drives = json_decode($arr['body'], true)['drives'];
$title = 'Select Driver';
$html = '
' . $tmp['body'] . '', $tmp['stat']); //return message('
' . json_encode($ret, JSON_PRETTY_PRINT) . '', 500); } if (isset($_GET['install1'])) { if (get_class($this)=='Googledrive') { return message(' ' . getconstStr('JumptoOffice') . ' ', getconstStr('Wait') . ' 1s', 201); } else { return message('Something error, retry after a few seconds.', 'Retry', 201); } } if (isset($_GET['install0'])) { if ($_POST['disktag_add']!='') { $_POST['disktag_add'] = preg_replace('/[^0-9a-zA-Z|_]/i', '', $_POST['disktag_add']); $f = substr($_POST['disktag_add'], 0, 1); if (strlen($_POST['disktag_add'])==1) $_POST['disktag_add'] .= '_'; if (isCommonEnv($_POST['disktag_add'])) { return message('Do not input ' . $envs . '