Quark.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php namespace Pan\Lib;
  2. use Dever;
  3. class Quark
  4. {
  5. private $header;
  6. private $partition;
  7. public function run($account, $task, $partition)
  8. {
  9. if ($partition) {
  10. $this->partition = $partition;
  11. }
  12. $this->header($account['cookie']);
  13. if ($task['mul'] == 1 && $task['path']) {
  14. $this->handle($account, $task);
  15. } elseif ($task['file']) {
  16. $file = Dever::load('view', 'upload')->local($task['file']);
  17. $excel = Dever::load('import', 'excel')->act($file);
  18. if ($excel) {
  19. foreach ($excel as $k => $v) {
  20. if ($v['A']) {
  21. $task['path'] = trim($v['A']);
  22. $task['code'] = trim($v['B']);
  23. $this->handle($account, $task);
  24. }
  25. }
  26. }
  27. }
  28. }
  29. # 处理
  30. private function handle($account, $task)
  31. {
  32. if (empty($task['code'])) {
  33. $task['code'] = '';
  34. }
  35. $temp = explode("\n", $task['path']);
  36. $task['path'] = $temp[0];
  37. if (isset($temp[1])) {
  38. $task['code'] = $temp[1];
  39. }
  40. $path = pathinfo($task['path']);
  41. if (strstr($path['filename'], '-')) {
  42. $path = explode('-', $path['filename']);
  43. $path = $path[0];
  44. } else {
  45. $path = $path['filename'];
  46. }
  47. if ($task['type'] == 1) {
  48. $this->save($path, $account, $task);
  49. } elseif ($task['type'] == 2) {
  50. $this->share($path, $account, $task);
  51. }
  52. }
  53. # 转存
  54. private function save($pwd_id, $account, $task, $end = false)
  55. {
  56. $token = $this->token($pwd_id, $task['code']);
  57. if ($token) {
  58. $page = 1;
  59. $state = true;
  60. while($state) {
  61. $data = $this->detail($page, $pwd_id, $token);
  62. if ($data) {
  63. foreach ($data as $k => $v) {
  64. $task_id = $this->saveFile($task['save_path'], $pwd_id, $token, $v['fid'], $v['share_fid_token'], $v['pdir_fid']);
  65. $check = $this->check($account['id'], $task['id'], $v['fid']);
  66. if (!$check) {
  67. $this->up($account['id'], $task['id'], $pwd_id, $v['fid'], $v['file_name'], $task_id, $task_id, $v);
  68. }
  69. }
  70. $page++;
  71. } else {
  72. $state = false;
  73. }
  74. }
  75. }
  76. }
  77. # 分享
  78. private function share($path, $account, $task, $end = false)
  79. {
  80. $page = 1;
  81. $state = true;
  82. # 该path下是否还有目录,默认没有
  83. $result = false;
  84. while($state) {
  85. # 获取当前目录下的文件列表
  86. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/file/sort?pr=ucpro&fr=pc&uc_param_str=&pdir_fid='.$path.'&_page='.$page.'&_size=50&_fetch_total=1&_fetch_sub_dirs=0&_sort=file_type:asc,updated_at:desc', array(), 'get', false, $this->header)->result();
  87. $result = Dever::json_decode($result);
  88. if (isset($result['data']['list']) && $result['data']['list']) {
  89. $total = count($result['data']['list']);
  90. foreach ($result['data']['list'] as $k => $v) {
  91. if ($task['oper_filter']) {
  92. $temp = explode("\n", $task['oper_filter']);
  93. foreach ($temp as $k => $v) {
  94. if (strstr($v['file_name'], $v)) {
  95. continue;
  96. }
  97. }
  98. }
  99. if ($v['file_type'] == 1) {
  100. # 文件
  101. $ext = pathinfo($v['file_name'], PATHINFO_EXTENSION);
  102. if ($task['oper_ext'] && (!strstr($task['oper_ext'], $ext) || !strstr($task['oper_ext'], 'file'))) {
  103. continue;
  104. }
  105. if ($end) {
  106. continue;
  107. }
  108. } else {
  109. $result = true;
  110. # 目录
  111. if ($end) {
  112. continue;
  113. }
  114. if ($task['oper_ext'] && !strstr($task['oper_ext'], 'dir')) {
  115. continue;
  116. }
  117. if ($task['oper'] == 2) {
  118. # 获取所有资源
  119. $this->handle($v['fid'], $account, $task);
  120. } elseif ($task['oper'] == 3) {
  121. # 寻找最后一级资源
  122. $last = $this->handle($v['fid'], $account, $task, true);
  123. if (!$last) {
  124. $this->handle($v['fid'], $account, $task);
  125. }
  126. continue;
  127. }
  128. }
  129. $check = $this->check($account['id'], $task['id'], $v['fid']);
  130. if (!$check) {
  131. $task_id = $this->create($v['fid'], $v['file_name']);
  132. if ($task_id) {
  133. $share_id = $this->task($task_id);
  134. if ($share_id) {
  135. $info = $this->password($share_id);
  136. $this->up($account['id'], $task['id'], $path, $v['fid'], $v['file_name'], $task_id, $share_id, $info, $page, $total, $k+1);
  137. }
  138. }
  139. }
  140. }
  141. $page++;
  142. } else {
  143. $state = false;
  144. }
  145. }
  146. return $result;
  147. }
  148. # 导入分享数据
  149. public function import($account, $task, $partition)
  150. {
  151. if ($partition) {
  152. $this->partition = $partition;
  153. }
  154. $this->header($account['cookie']);
  155. $page = 1;
  156. $state = true;
  157. while($state) {
  158. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/share/mypage/detail?pr=ucpro&fr=pc&uc_param_str=&_page='.$page.'&_size=50&_order_field=created_at&_order_type=desc&_fetch_total=1&_fetch_notify_follow=1', array(), 'get', false, $this->header)->result();
  159. $result = Dever::json_decode($result);
  160. if (isset($result['data']['list']) && $result['data']['list']) {
  161. foreach ($result['data']['list'] as $k => $v) {
  162. $check = $this->check($account['id'], $task['id'], $v['first_fid'], $v['share_id']);
  163. if (!$check) {
  164. $this->up($account['id'], $task['id'], 'share', $v['first_fid'], $v['title'], false, $v['share_id'], $v);
  165. }
  166. }
  167. $page++;
  168. } else {
  169. $state = false;
  170. }
  171. }
  172. }
  173. private function header($cookie)
  174. {
  175. if (!$this->header) {
  176. $this->header['accept'] = 'application/json, text/plain, */*';
  177. $this->header['content-type'] = 'application/json';
  178. $this->header['sec-ch-ua'] = '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"';
  179. $this->header['ec-ch-ua-mobile'] = '?0';
  180. $this->header['user-agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36';
  181. $this->header['sec-ch-ua-platform'] = '"Windows"';
  182. $this->header['origin'] = 'https://pan.quark.cn';
  183. $this->header['sec-fetch-site'] = 'same-site';
  184. $this->header['sec-fetch-mode'] = 'cors';
  185. $this->header['sec-fetch-dest'] = 'empty';
  186. $this->header['accept-encoding'] = 'gzip, deflate, br';
  187. $this->header['accept-language'] = 'zh-CN,zh;q=0.9';
  188. $this->header['referer'] = 'https://pan.quark.cn/';
  189. $this->header['cookie'] = $cookie;
  190. }
  191. }
  192. # 获取token
  193. private function token($pwd_id, $code)
  194. {
  195. $param = array();
  196. $param['pwd_id'] = $pwd_id;
  197. $param['passcode'] = $code;
  198. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/share/sharepage/token?pr=ucpro&fr=pc&uc_param_str=&__dt=405&__t=' . Dever::uuid(), $param, 'post', true, $this->header)->result();
  199. $result = Dever::json_decode($result);
  200. if (isset($result['data']['stoken']) && $result['data']['stoken']) {
  201. return $result['data']['stoken'];
  202. } else {
  203. return false;
  204. }
  205. }
  206. # 获取详情
  207. private function detail($page, $pwd_id, $token)
  208. {
  209. $param = array();
  210. $param['pwd_id'] = $pwd_id;
  211. $param['stoken'] = $token;
  212. $param['pdir_fid'] = '0';
  213. $param['_page'] = $page;
  214. $param['_size'] = 50;
  215. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/share/sharepage/detail', $param, 'get', false, $this->header)->result();
  216. $result = Dever::json_decode($result);
  217. if (isset($result['data']['list']) && $result['data']['list']) {
  218. return $result['data']['list'];
  219. } else {
  220. return false;
  221. }
  222. }
  223. # 开始分享
  224. private function create($id, $name)
  225. {
  226. $param = array();
  227. $param['expired_type'] = 1;
  228. $param['fid_list'] = array($id);
  229. $param['title'] = $name;
  230. $param['url_type'] = 1;//2是有提取码,1是无提取码
  231. //$param['passcode'] = '';
  232. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/share?pr=ucpro&fr=pc&uc_param_str=', $param, 'post', true, $this->header)->result();
  233. $result = Dever::json_decode($result);
  234. if (isset($result['data']['task_id']) && $result['data']['task_id']) {
  235. return $result['data']['task_id'];
  236. } else {
  237. return false;
  238. }
  239. }
  240. # 保存文件
  241. private function saveFile($save_path, $pwd_id, $token, $first_id, $share_fid_token, $to_pdir_fid)
  242. {
  243. if ($save_path) {
  244. $save_path = pathinfo($save_path);
  245. $save_path = explode('-', $save_path['filename']);
  246. $save_path = $save_path[0];
  247. } else {
  248. $save_path = '0';
  249. }
  250. $param['fid_list'] = $first_id;
  251. $param['fid_token_list'] = array($share_fid_token);
  252. $param['to_pdir_fid'] = $to_pdir_fid;
  253. $param['pwd_id'] = $pwd_id;
  254. $param['stoken'] = $token;
  255. $param['pdir_fid'] = $save_path;
  256. $param['scene'] = 'link';
  257. $result = Dever::curl('https://drive.quark.cn/1/clouddrive/share/sharepage/save?pr=ucpro&fr=pc&uc_param_str=&__dt=&__t=', $param, 'post', true, $this->header)->result();
  258. $result = Dever::json_decode($result);
  259. if (isset($result['data']['task_id']) && $result['data']['task_id']) {
  260. return $this->task($result['data']['task_id']);
  261. } else {
  262. return false;
  263. }
  264. }
  265. # 启动分享任务
  266. private function task($task_id)
  267. {
  268. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/task?pr=ucpro&fr=pc&uc_param_str=&task_id='.$task_id.'&retry_index=0', array(), 'get', false, $this->header)->result();
  269. $result = Dever::json_decode($result);
  270. if (isset($result['data']['share_id']) && $result['data']['share_id']) {
  271. return $result['data']['share_id'];
  272. } elseif (isset($result['data']['task_id']) && $result['data']['task_id']) {
  273. return $result['data']['task_id'];
  274. } else {
  275. return false;
  276. }
  277. }
  278. # 获得分享链接
  279. private function password($share_id)
  280. {
  281. $param['share_id'] = $share_id;
  282. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/share/password?pr=ucpro&fr=pc&uc_param_str=', $param, 'post', true, $this->header)->result();
  283. $result = Dever::json_decode($result);
  284. if (isset($result['data']['share_url']) && $result['data']['share_url']) {
  285. return $result['data'];
  286. } else {
  287. return false;
  288. }
  289. }
  290. # 删除分享
  291. public function delete($share_id, $cookie)
  292. {
  293. $this->header($cookie);
  294. $param['share_ids'] = $share_id;
  295. $result = Dever::curl('https://drive-pc.quark.cn/1/clouddrive/share/delete?pr=ucpro&fr=pc&uc_param_str=', $param, 'post', true, $this->header)->result();
  296. $result = Dever::json_decode($result);
  297. if (isset($result['message']) && $result['message'] == 'ok') {
  298. return true;
  299. } else {
  300. return false;
  301. }
  302. }
  303. # 检测数据
  304. private function check($account_id, $account_task_id, $fid, $share_id = false)
  305. {
  306. if ($this->partition) {
  307. $db = Dever::db('task_data', 'pan', 'default', $this->partition);
  308. } else {
  309. $db = Dever::db('task_data', 'pan');
  310. }
  311. $data['account_id'] = $account_id;
  312. $data['account_task_id'] = $account_task_id;
  313. $data['fid'] = $fid;
  314. if ($share_id) {
  315. $data['share_id'] = $share_id;
  316. }
  317. return $db->find($data);
  318. }
  319. # 保存数据
  320. private function up($account_id, $account_task_id, $path, $fid, $file_name, $task_id, $share_id, $info, $page = 1, $total = 1, $num = 1)
  321. {
  322. if ($this->partition) {
  323. $db = Dever::db('task_data', 'pan', 'default', $this->partition);
  324. } else {
  325. $db = Dever::db('task_data', 'pan');
  326. }
  327. $data['account_id'] = $account_id;
  328. $data['account_task_id'] = $account_task_id;
  329. $data['path'] = $path;
  330. $data['fid'] = $fid;
  331. $data['file_name'] = $file_name;
  332. if ($task_id) {
  333. $data['task_id'] = $task_id;
  334. }
  335. $data['share_id'] = $share_id;
  336. $data['share_url'] = $info['share_url'];
  337. if ($info) {
  338. $data['info'] = Dever::json_encode($info);
  339. }
  340. $db->insert($data);
  341. /*
  342. $task_data = $db->find(array('share_id' => $data['share_id']));
  343. if (!$task_data) {
  344. $db->insert($data);
  345. }*/
  346. }
  347. }