update CAT

This commit is contained in:
qist
2024-05-22 10:56:27 +08:00
parent 8a7360760f
commit ab6af24701
32 changed files with 1064 additions and 466 deletions
+14 -11
View File
@@ -7,7 +7,6 @@
* @Description: 阿里云盘Spider公共
*/
import {
getVod,
initSome,
clearFile,
playerContent,
@@ -17,9 +16,9 @@ import {
getFileByShare, getTempFileId
} from './ali_api.js';
import {JadeLogging} from "./log.js";
const JadeLog = new JadeLogging("阿里云盘")
const aliName = "阿里云盘"
const JadeLog = new JadeLogging(aliName)
const aliPlayFormatList = ["原画", "超清", "高清", "标清"]
async function initAli(token) {
await initSome();
@@ -41,15 +40,17 @@ function getShareId(share_url) {
}
}
async function detailContent(share_url_list, type_name = "电影") {
async function detailContentAli(share_url_list, type_name = "电影") {
try {
let video_items = [], sub_items = []
for (const share_url of share_url_list) {
for (let i=0;i<share_url_list.length;i++){
let share_url = share_url_list[i]
let share_id = getShareId(share_url)
let share_token = await setShareId(share_id)
if (share_token !== undefined) {
await getFileByShare(share_token, share_url, video_items, sub_items)
await getFileByShare(i+1,share_token, share_url, video_items, sub_items)
}
}
if (video_items.length > 0) {
@@ -57,13 +58,13 @@ async function detailContent(share_url_list, type_name = "电影") {
} else {
await JadeLog.error(`获取播放链接失败,检查分享链接为:${share_url_list.join("\t")}`)
}
return getVod(video_items, sub_items, type_name)
return {"video_items":video_items,"sub_items":sub_items}
} catch (e) {
await JadeLog.error('获取阿里视频失败,失败原因为:' + e.message + ' 行数为:' + e.lineNumber);
}
}
async function playContent(flag, id, flags) {
async function playContentAli(flag, id, flags) {
if (flags.length > 0) {
await JadeLog.info(`准备播放,播放类型为:${flag},播放文件Id为:${id},播放所有类型为:${flags.join("")}`)
} else {
@@ -78,6 +79,8 @@ async function playContent(flag, id, flags) {
export {
initAli,
detailContent,
playContent
detailContentAli,
playContentAli,
aliPlayFormatList,
aliName,
};
+14 -55
View File
@@ -306,8 +306,7 @@ async function refreshOpenToken() {
}
}
async function getFileByShare(share_token, share_url, video_item_list, sub_item_list) {
await JadeLog.info(`正在获取播放链接,分享链接为:${share_url}`)
async function getFileByShare(index,share_token, share_url, video_item_list, sub_item_list) {
let params = {};
params.share_id = shareId;
let file_id = share_url.split("folder/").slice(-1)[0]
@@ -317,27 +316,15 @@ async function getFileByShare(share_token, share_url, video_item_list, sub_item_
let response_str = await post("adrive/v3/share_link/get_share_by_anonymous", params),
response_json = JSON.parse(response_str), item_file_id = getParentFileId(file_id, response_json),
item = new Item(item_file_id);
await listFiles(item, video_item_list, sub_item_list, share_token);
await listFiles(index,item, video_item_list, sub_item_list, share_token);
}
async function getVod(video_item_list, sub_item_list, type_name) {
let play_foramt_list = ["原画", "超清", "高清", "标清"], episode_list = [], episode_str_list = [];
for (const video_item of video_item_list) {
episode_list.push(video_item.getDisplayName(type_name) + "$" + video_item.getFileId() + "+" + video_item.shareId + "+" + video_item.shareToken + findSubs(video_item.getName(), sub_item_list));
}
for (let index = 0; index < play_foramt_list.length; index++) {
episode_str_list.push(episode_list.join("#"));
}
return {
vod_play_url: episode_str_list.join("$$$"), vod_play_from: play_foramt_list.map(item => item).join("$$$"),
};
async function listFiles(index,item, video_item_list, sub_item_list, share_token) {
return await listFilesMarker(index,item, video_item_list, sub_item_list, "", share_token);
}
async function listFiles(item, video_item_list, sub_item_list, share_token) {
return await listFilesMarker(item, video_item_list, sub_item_list, "", share_token);
}
async function listFilesMarker(item, video_item_list, sub_item_list, netxt_markers, share_token) {
async function listFilesMarker(index,item, video_item_list, sub_item_list, netxt_markers, share_token) {
let new_item = {}, file_list = [];
new_item.limit = 200;
new_item.share_id = shareId;
@@ -345,10 +332,11 @@ async function listFilesMarker(item, video_item_list, sub_item_list, netxt_marke
new_item.parent_file_id = item.getFileId();
new_item.order_by = "name";
new_item.order_direction = "ASC";
new_item.share_index = index
if (netxt_markers.length > 0) {
new_item.marker = netxt_markers;
}
let items = Item.objectFrom(await shareFunc("adrive/v2/file/list_by_share", new_item), shareToken);
let items = Item.objectFrom(await shareFunc("adrive/v2/file/list_by_share", new_item), shareToken,index);
for (const r_item of items.getItems()) {
if (r_item.getType() === "folder") {
file_list.push(r_item);
@@ -385,9 +373,9 @@ async function listFilesMarker(item, video_item_list, sub_item_list, netxt_marke
}
}
}
items.getNextMarker().length > 0 && (await listFilesMarker(item, video_item_list, sub_item_list, items.getNextMarker()));
items.getNextMarker().length > 0 && (await listFilesMarker(index,item, video_item_list, sub_item_list, items.getNextMarker()));
for (const file of file_list) {
await listFiles(file, video_item_list, sub_item_list);
await listFiles(index,file, video_item_list, sub_item_list);
}
}
@@ -413,31 +401,6 @@ function getParentFileId(file_id, items) {
return "";
}
//字幕匹配
function pair(name, item_list, sub_item_list) {
for (const item of item_list) {
const sub_name = Utils.removeExt(item.getName()).toLowerCase();
if (name.indexOf(sub_name) > -1 || sub_name.indexOf(name) > -1) {
sub_item_list.push(item);
}
}
}
//找出所有字幕
function findSubs(name, item_list) {
let sub_item_list = [];
pair(Utils.removeExt(name).toLowerCase(), item_list, sub_item_list);
if (sub_item_list.length === 0) {
for (const item of item_list) {
sub_item_list.push(item);
}
}
let sub_str = "";
for (const item of sub_item_list) {
sub_str += "+" + Utils.removeExt(item.getName()) + "@@@" + item.getExt() + "@@@" + item.getFileId();
}
return sub_str;
}
async function getSubs(sub_list, share_id) {
let sub_url_list = [];
@@ -517,9 +480,7 @@ async function playerContent(file_id, share_id, share_token) {
// let sub_list = await getSubs(file_id_list,share_id);
await JadeLog.info("获取原画的播放地址和字幕下载链接成功", true)
await JadeLog.info(`下载地址为:${download_url}`)
return JSON.stringify({
parse: 0, url: download_url, header: getHeader(), format: "application/octet-stream", subs: []
});
return download_url;
} catch (e) {
await JadeLog.error("获取原画的播放地址和字幕下载链接失败:失败原因为:" + e);
}
@@ -540,9 +501,7 @@ async function playerContentByFlag(file_id, flag, share_id, shareToken) {
await JadeLog.info("获取转码后的播放地址和字幕下载链接成功", true)
await JadeLog.info(`下载地址为:${video_preview_url}`)
return JSON.stringify({
parse: 0, url: video_preview_url, header: getHeader(), format: "application/x-mpegURL", subs: []
});
return video_preview_url;
} catch (e) {
await JadeLog.error(`获取转码后的播放地址和字幕下载链接失败,失败原因为:${e}`)
}
@@ -560,7 +519,7 @@ function getPreviewUrl(video_preview_play_info, flag) {
return live_transcoding_task.url;
}
}
return live_transcoding_task_list[0].url;
return live_transcoding_task_list.slice(-1)[0].url;
}
function getSubsByPlayInfo(video_preview_play_info) {
@@ -707,5 +666,5 @@ async function setToken(token) {
}
export {
initSome, setToken, clearFile, setShareId, getFileByShare, getVod, playerContent, playerContentByFlag, getTempFileId
initSome, setToken, clearFile, setShareId, getFileByShare, playerContent, playerContentByFlag, getTempFileId
};
+15 -9
View File
@@ -253,10 +253,11 @@ class Item {
this.category = "";
this.size = "";
this.parent = "";
this.shareToken = ""
this.shareToken = "";
this.shareIndex = 0;
}
static objectFrom(json_str, shareToken) {
static objectFrom(json_str, shareToken,shareIndex) {
if (_.isEmpty(json_str)) {
return new Item();
}
@@ -273,8 +274,9 @@ class Item {
item.category = typeof item_json.category == "undefined" ? "" : item_json.category;
item.size = typeof item_json.size == "undefined" ? "" : item_json.size;
item.parent = typeof item_json.parent_file_id == "undefined" ? "" : item_json.parent_file_id;
item.shareIndex = shareIndex
typeof item.items != "undefined" && Array.isArray(item_json.items) && !_.isEmpty(item_json.items) && item_json.items.forEach(function (x) {
let new_item = Item.objectFrom(JSON.stringify((x)), shareToken)
let new_item = Item.objectFrom(JSON.stringify((x)), shareToken,shareIndex)
item.items.push(new_item);
});
return item;
@@ -324,15 +326,15 @@ class Item {
return _.isEmpty(this.parent) ? "" : "[" + this.parent + "]";
}
getShareIndex(){
return this.shareIndex
}
parentFunc(item) {
this.parent = item;
return this;
}
// getDisplayName() {
// return this.getParent() + " " + this.getName() + " " + this.getSize();
// }
getDisplayName(type_name) {
let name = this.getName();
name = name.replaceAll("玩偶哥 q 频道:【神秘的哥哥们】", "")
@@ -345,11 +347,15 @@ class Item {
}
name = Utils.getStrByRegexDefault(/\.S01E(.*?)\./, name)
const numbers = name.match(/\d+/g);
if (numbers.length > 0) {
if (!_.isEmpty(numbers) && numbers.length > 0) {
name = numbers[0]
}
}
return name + " " + this.getParent() + " " + this.getSize();
return name + " " + this.getParent() + " " + this.getSize();
}
getEpisodeUrl(type_name){
return this.getDisplayName(type_name) + "$" + this.getFileId() + "+" + this.shareId + "+" + this.shareToken
}
}
+106
View File
@@ -0,0 +1,106 @@
/**
* File: h:\PycharmProjects\Github\TVSpider\lib\cloud.js
* Project: h:\PycharmProjects\Github\TVSpider
* Created Date: Tuesday, May 21st 2024, 2:01:09 pm
* Author: jade
* -----
* Last Modified: Tue May 21 2024
* Modified By: jade
* -----
* Copyright (c) 2024 samples
* ------------------------------------
* Javascript will save your soul!
*/
import {initAli,detailContentAli,playContentAli, aliPlayFormatList,aliName} from "./ali.js"
import { initQuark,detailContentQuark,playContentQuark,quarkPlayFormatList,quarkName,getQuarkHeaders} from "./quark.js"
import * as Utils from "./utils.js";
import {_} from "../lib/cat.js";
async function initCloud(cfg){
initAli(cfg["aliToken"])
initQuark(cfg["quarkCookie"])
}
async function detailContent(share_url_list,type_name="电影"){
let ali_share_url_list = [],quark_share_url_list = []
const playVod = {}
for (const shareUrl of share_url_list){
let aliMatches = shareUrl.match(Utils.patternAli);
if (!_.isEmpty(aliMatches)) {
ali_share_url_list.push(aliMatches[1])
}
let quarkMatches = shareUrl.match(Utils.patternQuark);
if (!_.isEmpty(quarkMatches)){
quark_share_url_list.push(quarkMatches[1])
}
}
let aliItems = await detailContentAli(ali_share_url_list)
let quarkItems = await detailContentQuark(quark_share_url_list)
await getVod(aliPlayFormatList,aliName,playVod,aliItems.video_items,aliItems.sub_items,type_name)
await getVod(quarkPlayFormatList,quarkName,playVod,quarkItems.video_items,quarkItems.sub_items,type_name)
return playVod
}
async function getVod(play_foramt_list,cloud_name,playVod,video_item_list, sub_item_list, type_name) {
if (video_item_list.length ==0){
return
}
for (let i=0; i<video_item_list.slice(-1)[0].shareIndex;i++){
for (let index = 0; index < play_foramt_list.length; index++) {
let vodItems = []
for (const video_item of video_item_list) {
if (video_item.shareIndex === i + 1){
vodItems.push( video_item.getEpisodeUrl(type_name)+ findSubs(video_item.getName(), sub_item_list)); }
}
playVod[`${cloud_name}-${i+1}-${play_foramt_list[index]}`] = vodItems.join("#")
}
}
}
//字幕匹配
function pair(name, item_list, sub_item_list) {
for (const item of item_list) {
const sub_name = Utils.removeExt(item.getName()).toLowerCase();
if (name.indexOf(sub_name) > -1 || sub_name.indexOf(name) > -1) {
sub_item_list.push(item);
}
}
}
//找出所有字幕
function findSubs(name, item_list) {
let sub_item_list = [];
pair(Utils.removeExt(name).toLowerCase(), item_list, sub_item_list);
if (sub_item_list.length === 0) {
for (const item of item_list) {
sub_item_list.push(item);
}
}
let sub_str = "";
for (const item of sub_item_list) {
sub_str += "+" + Utils.removeExt(item.getName()) + "@@@" + item.getExt() + "@@@" + item.getFileId();
}
return sub_str;
}
async function playContent(flag,id,flags){
if (flag.indexOf(aliName) > -1) {
return await playContentAli(flag, id, flags)
}else if (flag.indexOf(quarkName) > -1){
return await playContentQuark(flag,id,flags)
}
}
function getHeaders(flag){
if (flag.indexOf(aliName) > -1) {
return {}
}else if (flag.indexOf(quarkName) > -1){
return getQuarkHeaders()
}
}
export {initCloud,detailContent,playContent,getHeaders,aliName,quarkName}
+63
View File
@@ -0,0 +1,63 @@
/**
* File: h:\PycharmProjects\Github\TVSpider\lib\quark.js
* Project: h:\PycharmProjects\Github\TVSpider
* Created Date: Monday, May 20th 2024, 4:54:26 pm
* Author: jade
* -----
* Last Modified: Tue May 21 2024
* Modified By: jade
* -----
* Copyright (c) 2024 samples
* ------------------------------------
* Javascript will save your soul!
*/
import {JadeLogging} from "./log.js";
import {Quark} from "./quark_api.js"
const quarkName = "夸克云盘"
const JadeLog = new JadeLogging(quarkName)
const quarkPlayFormatList = ["普画"]
const quark = new Quark()
async function initQuark(cookie) {
quark.initQuark(cookie)
await JadeLog.info(`夸克云盘初始化完成,Cookie为:${cookie}`, true)
}
async function detailContentQuark(share_url_list, type_name = "电影") {
try {
let video_items = [], sub_items = []
for (let i=0;i<share_url_list.length;i++){
let share_url = share_url_list[i]
await quark.getFilesByShareUrl(i+1,share_url,video_items,sub_items)
}
if (video_items.length > 0) {
await JadeLog.info(`获取播放链接成功,分享链接为:${share_url_list.join("\t")}`)
} else {
await JadeLog.error(`获取播放链接失败,检查分享链接为:${share_url_list.join("\t")}`)
}
return {"video_items":video_items,"sub_items":sub_items}
} catch (e) {
await JadeLog.error('获取夸克视频失败,失败原因为:' + e.message + ' 行数为:' + e.lineNumber);
}
}
async function playContentQuark(flag, id, flags){
let id_list = id.split("++")
let shareId = id_list[2],stoken = id_list[3], fileId = id_list[0], fileToken = id_list[1]
let playUrl = ""
if (flag.indexOf("原画") > -1){
playUrl = (await quark.getDownload(shareId, stoken, fileId, fileToken,true)).download_url
}else if (flag.indexOf("普画") > -1){
playUrl = (await quark.getLiveTranscoding(shareId, stoken, fileId, fileToken,true)).slice(-1)[0]["video_info"].url
}
return playUrl
}
function getQuarkHeaders(){
let headers = quark.getHeaders()
delete headers["Host"]
return headers
}
export {initQuark,detailContentQuark,playContentQuark,quarkPlayFormatList,quarkName,getQuarkHeaders}
+282
View File
@@ -0,0 +1,282 @@
/**
* File: /workspaces/TVSpider/lib/quark_api.js
* Project: /workspaces/TVSpider
* Created Date: Monday, May 20th 2024, 6:38:12 am
* Author: jade
* -----
* Last Modified: Tue May 21 2024
* Modified By: jade
* -----
* Copyright (c) 2024 samples
* ------------------------------------
* Javascript will save your soul!
*/
import {_,Crypto} from "../lib/cat.js";
import * as Utils from "../lib/utils.js"
import {Item} from "../lib/quark_object.js"
class Quark{
constructor(){
this.apiUrl = "https://drive-pc.quark.cn/1/clouddrive/"
this.cookie = ""
this.ckey = ""
this.shareTokenCache = {}
this.pr = "pr=ucpro&fr=pc"
this.subtitleExts = ['.srt', '.ass', '.scc', '.stl', '.ttml'];
this.saveFileIdCaches = {}
this.saveDirId = null
this.saveDirName = 'TV';
}
async initQuark(cookie) {
this.ckey = Crypto.enc.Hex.stringify(Crypto.MD5(cookie)).toString();
let localCfg = await local.get("quark", "cookie");
if (!_.isEmpty(localCfg)){
this.cookie = JSON.parse(localCfg)[this.ckey]
}else{
this.cookie = cookie
}
}
getHeaders(){
return {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch',
'Referer': 'https://pan.quark.cn/',
"Content-Type":"application/json",
"Cookie":this.cookie,
"Host":"drive-pc.quark.cn"
};
}
async api(url,data,retry,method){
const leftRetry = retry || 3;
let resp = await req(this.apiUrl + url,{
method:method || "post",
data:data,
headers:this.getHeaders()
})
if (resp.headers['set-cookie']) {
const puus = [resp.headers['set-cookie']].join(';;;').match(/__puus=([^;]+)/);
if (puus) {
if (this.cookie.match(/__puus=([^;]+)/)[1] != puus[1]) {
this.cookie = this.cookie.replace(/__puus=[^;]+/, `__puus=${puus[1]}`);
let cookieDic = {}
cookieDic[this.ckey] = this.cookie
await local.set("quark",this.cookie, JSON.stringify(cookieDic));
}
}
}
if (resp.code !== 200 && leftRetry > 0) {
Utils.sleep(1)
return await this.api(url, data, leftRetry - 1);
}
return JSON.parse(resp.content) || {};
}
getShareData(url) {
let regex = /https:\/\/pan\.quark\.cn\/s\/([^\\|#/]+)/;
let matches = regex.exec(url);
if (matches) {
return {
shareId: matches[1],
folderId: '0',
};
}
return null;
}
async getShareToken(shareData) {
if (!this.shareTokenCache[shareData.shareId]) {
delete this.shareTokenCache[shareData.shareId];
const shareToken = await this.api(`share/sharepage/token?${this.pr}`, {
pwd_id: shareData.shareId,
passcode: shareData.sharePwd || '',
});
if (shareToken.data && shareToken.data.stoken) {
this.shareTokenCache[shareData.shareId] = shareToken.data;
}
}
}
async listFile (shareIndex,shareData,videos,subtitles,shareId, folderId, page) {
const prePage = 200;
page = page || 1;
const listData = await this.api(`share/sharepage/detail?${this.pr}&pwd_id=${shareId}&stoken=${encodeURIComponent(this.shareTokenCache[shareId].stoken)}&pdir_fid=${folderId}&force=0&_page=${page}&_size=${prePage}&_sort=file_type:asc,file_name:asc`, null,null, 'get');
if (!listData.data) return [];
const items = listData.data.list;
if (!items) return [];
const subDir = [];
for (const item of items) {
if (item.dir === true) {
subDir.push(item);
} else if (item.file === true && item.obj_category === 'video') {
if (item.size < 1024 * 1024 * 5) continue;
item.stoken = this.shareTokenCache[shareData.shareId].stoken;
videos.push(Item.objectFrom(item,shareData.shareId,shareIndex));
} else if (item.type === 'file' && this.subtitleExts.some((x) => item.file_name.endsWith(x))) {
subtitles.push(Item.objectFrom(item,shareData,shareIndex));
}
}
if (page < Math.ceil(listData.metadata._total / prePage)) {
const nextItems = await this.listFile(shareIndex,shareData.shareId,videos,subtitles,shareId, folderId, page + 1);
for (const item of nextItems) {
items.push(item);
}
}
for (const dir of subDir) {
const subItems = await this.listFile(shareIndex,shareData,videos,subtitles,shareId, dir.fid);
for (const item of subItems) {
items.push(item);
}
}
return items;
};
findBestLCS(mainItem, targetItems) {
const results = [];
let bestMatchIndex = 0;
for (let i = 0; i < targetItems.length; i++) {
const currentLCS = Utils.lcs(mainItem.name, targetItems[i].name);
results.push({ target: targetItems[i], lcs: currentLCS });
if (currentLCS.length > results[bestMatchIndex].lcs.length) {
bestMatchIndex = i;
}
}
const bestMatch = results[bestMatchIndex];
return { allLCS: results, bestMatch: bestMatch, bestMatchIndex: bestMatchIndex };
}
async getFilesByShareUrl(shareIndex,shareInfo,videos,subtitles){
const shareData = typeof shareInfo === 'string' ? this.getShareData(shareInfo) : shareInfo;
if (!shareData) return [];
await this.getShareToken(shareData);
if (!this.shareTokenCache[shareData.shareId]) return [];
await this.listFile(shareIndex,shareData,videos,subtitles,shareData.shareId, shareData.folderId);
if (subtitles.length > 0) {
videos.forEach((item) => {
var matchSubtitle = this.findBestLCS(item, subtitles);
if (matchSubtitle.bestMatch) {
item.subtitle = matchSubtitle.bestMatch.target;
}
});
}
}
clean(){
const saves = Object.keys(this.saveFileIdCaches);
for (const save of saves) {
delete this.saveFileIdCaches[save];
}
}
async clearSaveDir() {
const listData = await this.api(`file/sort?${this.pr}&pdir_fid=${this.saveDirId}&_page=1&_size=200&_sort=file_type:asc,updated_at:desc`, {}, {}, 'get');
if (listData.data && listData.data.list && listData.data.list.length > 0) {
await this.api(`file/delete?${this.pr}`, {
action_type: 2,
filelist: listData.data.list.map((v) => v.fid),
exclude_fids: [],
});
}
}
async createSaveDir(clean) {
if (this.saveDirId) {
// 删除所有子文件
if (clean) await this.clearSaveDir();
return;
}
const listData = await this.api(`file/sort?${this.pr}&pdir_fid=0&_page=1&_size=200&_sort=file_type:asc,updated_at:desc`, {}, {}, 'get');
if (listData.data && listData.data.list)
for (const item of listData.data.list) {
if (item.file_name === this.saveDirName) {
this.saveDirId = item.fid;
await this.clearSaveDir();
break;
}
}
if (!this.saveDirId) {
const create = await this.api(`file?${this.pr}`, {
pdir_fid: '0',
file_name: this.saveDirName,
dir_path: '',
dir_init_lock: false,
});
if (create.data && create.data.fid) {
this.saveDirId = create.data.fid;
}
}
}
async save(shareId, stoken, fileId, fileToken, clean) {
await this.createSaveDir(clean);
if (clean) {
this.clean()
}
if (!this.saveDirId) return null;
if (!stoken) {
await this.getShareToken({
shareId: shareId,
});
if (!this.shareTokenCache[shareId]) return null;
}
const saveResult = await this.api(`share/sharepage/save?${this.pr}`, {
fid_list: [fileId],
fid_token_list: [fileToken],
to_pdir_fid: this.saveDirId,
pwd_id: shareId,
stoken: stoken || this.shareTokenCache[shareId].stoken,
pdir_fid: '0',
scene: 'link',
});
if (saveResult.data && saveResult.data.task_id) {
let retry = 0;
// wait task finish
while (true) {
const taskResult = await this.api(`task?${this.pr}&task_id=${saveResult.data.task_id}&retry_index=${retry}`, {}, {}, 'get');
if (taskResult.data && taskResult.data.save_as && taskResult.data.save_as.save_as_top_fids && taskResult.data.save_as.save_as_top_fids.length > 0) {
return taskResult.data.save_as.save_as_top_fids[0];
}
retry++;
if (retry > 2) break;
Utils.sleep(1);
}
}
return false;
}
async getLiveTranscoding(shareId, stoken, fileId, fileToken) {
if (!this.saveFileIdCaches[fileId]) {
const saveFileId = await this.save(shareId, stoken, fileId, fileToken, true);
if (!saveFileId) return null;
this.saveFileIdCaches[fileId] = saveFileId;
}
const transcoding = await this.api(`file/v2/play?${this.pr}`, {
fid: this.saveFileIdCaches[fileId],
resolutions: 'normal,low,high,super,2k,4k',
supports: 'fmp4',
});
if (transcoding.data && transcoding.data.video_list) {
return transcoding.data.video_list;
}
return null;
}
async getDownload(shareId, stoken, fileId, fileToken, clean) {
if (!this.saveFileIdCaches[fileId]) {
const saveFileId = await this.save(shareId, stoken, fileId, fileToken, clean);
if (!saveFileId) return null;
this.saveFileIdCaches[fileId] = saveFileId;
}
const down = await this.api(`file/download?${this.pr}&uc_param_str=`, {
fids: [this.saveFileIdCaches[fileId]],
});
if (down.data) {
return down.data[0];
}
return null;
}
}
export {Quark}
+98
View File
@@ -0,0 +1,98 @@
/**
* File: h:\PycharmProjects\Github\TVSpider\lib\quark_object.js
* Project: h:\PycharmProjects\Github\TVSpider
* Created Date: Monday, May 20th 2024, 5:26:45 pm
* Author: jade
* -----
* Last Modified: Tue May 21 2024
* Modified By: jade
* -----
* Copyright (c) 2024 samples
* ------------------------------------
* Javascript will save your soul!
*/
import {_} from "../lib/cat.js";
import * as Utils from "./utils.js";
class Item {
constructor() {
this.fileId = "";
this.shareId = ""
this.shareToken = "";
this.shareFileToken = ""
this.seriesId = ""
this.name = "";
this.type = "";
this.formatType = "";
this.size = "";
this.parent = "";
this.shareData = null;
this.shareIndex = 0;
this.lastUpdateAt = 0
}
static objectFrom(item_json, shareId,shareIndex) {
let item = new Item();
item.fileId = typeof item_json.fid == undefined ? "" : item_json.fid;
item.shareId = shareId
item.shareToken = typeof item_json.stoken == undefined ? "" : item_json.stoken;
item.shareFileToken = typeof item_json.share_fid_token == undefined ? "" : item_json.share_fid_token;
item.seriesId = typeof item_json.series_id == undefined? "":item_json.series_id
item.name = typeof item_json.file_name == undefined ? "" : item_json.file_name;
item.type = typeof item_json.obj_category == undefined ? "" : item_json.obj_category;
item.formatType = typeof item_json.format_type == undefined? "" : item_json.format_type;
item.size = typeof item_json.size == undefined ? "" : item_json.size;
item.parent = typeof item_json.pdir_fid == undefined ? "" : item_json.pdir_fid;
item.lastUpdateAt = typeof item_json.last_update_at == undefined ? "" : item_json.last_update_at
item.shareIndex = shareIndex
return item;
}
getFileExtension(){
return this.name.split(".").slice(-1)[0]
}
getFileId() {
return _.isEmpty(this.fileId) ? "" : this.fileId
}
getName() {
return _.isEmpty(this.name) ? "" : this.name;
}
getParent() {
return _.isEmpty(this.parent) ? "" : "[" + this.parent + "]";
}
getSize() {
return this.size === 0 ? "" : "[" + Utils.getSize(this.size) + "]";
}
getShareIndex(){
return this.shareIndex
}
getDisplayName(type_name) {
let name = this.getName();
if (type_name === "电视剧") {
let replaceNameList = ["4k", "4K"]
name = name.replaceAll("." + this.getFileExtension(), "")
name = name.replaceAll(" ", "").replaceAll(" ", "")
for (const replaceName of replaceNameList) {
name = name.replaceAll(replaceName, "")
}
name = Utils.getStrByRegexDefault(/\.S01E(.*?)\./, name)
const numbers = name.match(/\d+/g);
if (!_.isEmpty(numbers) && numbers.length > 0) {
name = numbers[0]
}
}
return name + " " + this.getSize();
}
getEpisodeUrl(type_name){
return this.getDisplayName(type_name) + "$" + this.getFileId() + "++" + this.shareFileToken + "++" + this.shareId + "++" + this.shareToken
}
}
export {Item}
+65 -1
View File
@@ -273,8 +273,70 @@ function formatContent(content) {
.replaceAll('&quot;', '\"')
.replaceAll(/<\/?[^>]+>/g, '');
}
/**
* 字符串相似度匹配
* @returns
*/
function lcs(str1, str2) {
if (!str1 || !str2) {
return {
length: 0,
sequence: '',
offset: 0,
};
}
var sequence = '';
var str1Length = str1.length;
var str2Length = str2.length;
var num = new Array(str1Length);
var maxlen = 0;
var lastSubsBegin = 0;
for (var i = 0; i < str1Length; i++) {
var subArray = new Array(str2Length);
for (var j = 0; j < str2Length; j++) {
subArray[j] = 0;
}
num[i] = subArray;
}
var thisSubsBegin = null;
for (i = 0; i < str1Length; i++) {
for (j = 0; j < str2Length; j++) {
if (str1[i] !== str2[j]) {
num[i][j] = 0;
} else {
if (i === 0 || j === 0) {
num[i][j] = 1;
} else {
num[i][j] = 1 + num[i - 1][j - 1];
}
if (num[i][j] > maxlen) {
maxlen = num[i][j];
thisSubsBegin = i - num[i][j] + 1;
if (lastSubsBegin === thisSubsBegin) {
// if the current LCS is the same as the last time this block ran
sequence += str1[i];
} else {
// this block resets the string builder if a different LCS is found
lastSubsBegin = thisSubsBegin;
sequence = ''; // clear it
sequence += str1.substr(lastSubsBegin, i + 1 - lastSubsBegin);
}
}
}
}
}
return {
length: maxlen,
sequence: sequence,
offset: thisSubsBegin,
};
}
let patternAli = /(https:\/\/www\.aliyundrive\.com\/s\/[^"]+|https:\/\/www\.alipan\.com\/s\/[^"]+)/
let patternQuark = /(https:\/\/pan\.quark\.cn\/s\/[^"]+)/
export {
isSub,
@@ -292,6 +354,7 @@ export {
base64Encode,
base64Decode,
patternAli,
patternQuark,
unescape,
decode,
MOBILEUA,
@@ -309,5 +372,6 @@ export {
randUUID,
formatContent,
formatUrl,
encode
encode,
lcs
};