alist_open.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { _ } from './lib/cat.js';
  2. import { findBestLCS } from './lib/similarity.js';
  3. const http = async function (url, options = {}) {
  4. if (options.method == 'POST' && options.data) {
  5. options.body = JSON.stringify(options.data);
  6. options.headers = Object.assign({ 'content-type': 'application/json' }, options.headers);
  7. }
  8. const res = await req(url, options);
  9. res.json = () => (res.content ? JSON.parse(res.content) : null);
  10. res.text = () => res.content;
  11. return res;
  12. };
  13. ['get', 'post'].forEach((method) => {
  14. http[method] = function (url, options = {}) {
  15. return http(url, Object.assign(options, { method: method.toUpperCase() }));
  16. };
  17. });
  18. const __drives = {};
  19. const __subtitle_cache = {};
  20. async function get_drives_path(tid) {
  21. const index = tid.indexOf('/', 1);
  22. const name = tid.substring(1, index);
  23. const path = tid.substring(index);
  24. return { drives: await get_drives(name), path };
  25. }
  26. async function get_drives(name) {
  27. const { settings, api, server } = __drives[name];
  28. if (settings.v3 == null) {
  29. //获取 设置
  30. settings.v3 = false;
  31. const data = (await http.get(server + '/api/public/settings')).json().data;
  32. if (_.isArray(data)) {
  33. settings.title = data.find((x) => x.key == 'title')?.value;
  34. settings.v3 = false;
  35. settings.version = data.find((x) => x.key == 'version')?.value;
  36. settings.enableSearch = data.find((x) => x.key == 'enable search')?.value == 'true';
  37. } else {
  38. settings.title = data.title;
  39. settings.v3 = true;
  40. settings.version = data.version;
  41. settings.enableSearch = false; //v3 没有找到 搜索配置
  42. }
  43. //不同版本 接口不一样
  44. api.path = settings.v3 ? '/api/fs/list' : '/api/public/path';
  45. api.file = settings.v3 ? '/api/fs/get' : '/api/public/path';
  46. api.search = settings.v3 ? '/api/public/search' : '/api/public/search';
  47. api.other = settings.v3 ? '/api/fs/other' : null;
  48. }
  49. return __drives[name];
  50. }
  51. let siteKey = '';
  52. let siteType = 0;
  53. function init(cfg) {
  54. siteKey = cfg.skey;
  55. siteType = cfg.stype;
  56. cfg.ext.forEach(
  57. (item) =>
  58. (__drives[item.name] = {
  59. name: item.name,
  60. server: item.server.endsWith('/') ? item.server.substring(0, item.server.length - 1) : item.server,
  61. startPage: item.startPage || '/', //首页
  62. showAll: item.showAll === true, //默认只显示 视频和文件夹,如果想显示全部 showAll 设置true
  63. params: item.params || {},
  64. _path_param: item.params
  65. ? _.sortBy(Object.keys(item.params), function (x) {
  66. return -x.length;
  67. })
  68. : [],
  69. settings: {},
  70. api: {},
  71. getParams(path) {
  72. const key = this._path_param.find((x) => path.startsWith(x));
  73. return Object.assign({}, this.params[key], { path });
  74. },
  75. async getPath(path) {
  76. const res = (await http.post(this.server + this.api.path, { data: this.getParams(path) })).json();
  77. return this.settings.v3 ? res.data.content : res.data.files;
  78. },
  79. async getFile(path) {
  80. const res = (await http.post(this.server + this.api.file, { data: this.getParams(path) })).json();
  81. const data = this.settings.v3 ? res.data : res.data.files[0];
  82. if (!this.settings.v3) data.raw_url = data.url; //v2 的url和v3不一样
  83. return data;
  84. },
  85. async getOther(method, path) {
  86. const data = this.getParams(path);
  87. data.method = method;
  88. const res = (await http.post(this.server + this.api.other, { data: data })).json();
  89. return res;
  90. },
  91. isFolder(data) {
  92. return data.type == 1;
  93. },
  94. isVideo(data) {
  95. //判断是否是 视频文件
  96. return this.settings.v3 ? data.type == 2 : data.type == 3;
  97. },
  98. isSubtitle(data) {
  99. if (data.type == 1) return false;
  100. const ext = ['.srt', '.ass', '.scc', '.stl', '.ttml'];
  101. return ext.some((x) => data.name.endsWith(x));
  102. },
  103. getType(data) {
  104. const isVideo = this.isVideo(data);
  105. return this.isFolder(data) ? 0 : isVideo ? 10 : 1;
  106. },
  107. getPic(data) {
  108. let pic = this.settings.v3 ? data.thumb : data.thumbnail;
  109. return pic || (this.isFolder(data) ? 'http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png' : '');
  110. },
  111. getSize(data) {
  112. let sz = data.size || 0;
  113. if (sz <= 0) return '';
  114. let filesize = '';
  115. if (sz > 1024 * 1024 * 1024 * 1024.0) {
  116. sz /= 1024 * 1024 * 1024 * 1024.0;
  117. filesize = 'TB';
  118. } else if (sz > 1024 * 1024 * 1024.0) {
  119. sz /= 1024 * 1024 * 1024.0;
  120. filesize = 'GB';
  121. } else if (sz > 1024 * 1024.0) {
  122. sz /= 1024 * 1024.0;
  123. filesize = 'MB';
  124. } else {
  125. sz /= 1024.0;
  126. filesize = 'KB';
  127. }
  128. return sz.toFixed(2) + filesize;
  129. },
  130. getRemark(data) {
  131. return '';
  132. },
  133. })
  134. );
  135. }
  136. async function dir(dir, pg) {
  137. for (const k in __subtitle_cache) {
  138. delete __subtitle_cache[k];
  139. }
  140. pg = pg || 1;
  141. if (pg == 0) pg == 1;
  142. if (dir === '/' || dir === '') {
  143. const result = _.map(__drives, function (d) {
  144. return { name: d.name, path: '/' + d.name + d.startPage, type: 0, thumb: '' };
  145. });
  146. return JSON.stringify({
  147. parent: '',
  148. page: pg,
  149. pagecount: pg,
  150. list: result,
  151. });
  152. }
  153. let { drives, path } = await get_drives_path(dir);
  154. const id = dir.endsWith('/') ? dir : dir + '/';
  155. const list = await drives.getPath(path);
  156. let subtList = [];
  157. let videos = [];
  158. let allList = [];
  159. list.forEach((item) => {
  160. if (drives.isSubtitle(item)) subtList.push(item.name);
  161. const isVideo = drives.isVideo(item);
  162. if (!drives.showAll && !drives.isFolder(item) && !isVideo) return;
  163. const file = {
  164. name: item.name.replaceAll('$', '_').replaceAll('#', '_'),
  165. path: id + item.name + (drives.isFolder(item) ? '/' : ''),
  166. thumb: drives.getPic(item),
  167. type: drives.getType(item),
  168. size: drives.getSize(item),
  169. remark: drives.getRemark(item),
  170. };
  171. if (drives.isVideo(item)) videos.push(file);
  172. allList.push(file);
  173. });
  174. if (subtList.length > 0) {
  175. videos.forEach((item) => {
  176. var sbust = findBestLCS(item.name, subtList);
  177. if (sbust.bestMatch) __subtitle_cache[item.path] = [id + sbust.bestMatch.target];
  178. });
  179. }
  180. return JSON.stringify({
  181. parent: id,
  182. page: pg,
  183. pagecount: pg,
  184. list: allList,
  185. });
  186. }
  187. async function file(file) {
  188. let { drives, path } = await get_drives_path(file);
  189. const item = await drives.getFile(path);
  190. const subs = [];
  191. if (__subtitle_cache[file]) {
  192. for (const sub of __subtitle_cache[file]) {
  193. try {
  194. let subP = await get_drives_path(sub);
  195. const subItem = await drives.getFile(subP.path);
  196. subs.push(subItem.raw_url);
  197. } catch (error) {}
  198. }
  199. }
  200. if (item.provider === 'AliyundriveShare2Open' && drives.api.other) {
  201. const urls = ['原画', item.raw_url];
  202. try {
  203. const res = await drives.getOther('video_preview', path);
  204. for (const live of res.data.video_preview_play_info.live_transcoding_task_list) {
  205. if (live.status === 'finished') {
  206. urls.push(live.template_id);
  207. urls.push(live.url);
  208. }
  209. }
  210. } catch (error) {}
  211. const result = {
  212. name: item.name,
  213. url: urls,
  214. size: drives.getSize(item),
  215. remark: drives.getRemark(item),
  216. header: {},
  217. extra: {
  218. subt: subs,
  219. },
  220. };
  221. return JSON.stringify(result);
  222. } else if (item.provider === '123Pan') {
  223. let url = item.raw_url;
  224. try {
  225. url = (await http.get(url)).json().data.redirect_url;
  226. } catch (error) {}
  227. const result = {
  228. name: item.name,
  229. url: url,
  230. size: drives.getSize(item),
  231. remark: drives.getRemark(item),
  232. header: {},
  233. extra: {
  234. subt: subs,
  235. },
  236. };
  237. return JSON.stringify(result);
  238. } else {
  239. const result = {
  240. name: item.name,
  241. url: item.raw_url,
  242. size: drives.getSize(item),
  243. remark: drives.getRemark(item),
  244. header: {},
  245. extra: {
  246. subt: subs,
  247. },
  248. };
  249. return JSON.stringify(result);
  250. }
  251. }
  252. function search(wd) {
  253. return JSON.stringify({
  254. list: [],
  255. });
  256. }
  257. export function __jsEvalReturn() {
  258. return {
  259. init: init,
  260. dir: dir,
  261. file: file,
  262. search: search,
  263. };
  264. }