YH/js/alist_xy2.js
2024-10-18 00:34:20 -05:00

1308 lines
39 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
distance
} from "./mod.js";
import {
sortListByCN
} from "./sortName.js";
import cheerio from "assets://js/lib/cheerio.min.js"
String.prototype.rstrip = function(chars) {
let regex = new RegExp(chars + "$");
return this.replace(regex, "")
};
var showMode = "single";
var searchDriver = "";
var search_type = "";
var detail_order = "name";
var __poster_mode = true;
var __filter_data = null;
let __imageServer = "https://"
let __imageSource = '@Referer=https://api.douban.com/@User-Agent=Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/113.0.0.0%20Safari/537.36';
const __folder_img = "https://pic.616pic.com/ys_bnew_img/00/46/91/Kduke9oSev.jpg";
const __play_list_img = "https://pic.616pic.com/ys_bnew_img/00/24/42/xp3ozLGSm4.jpg";
const __num = "200";
const request_timeout = 10000;
const VERSION = "alist v2/v3 202402020830";
function print(any) {
any = any || "";
if (typeof any == "object" && Object.keys(any).length > 0) {
try {
any = JSON.stringify(any);
console.log(any)
} catch (e) {
console.log(typeof any + ":" + any.length)
}
} else if (typeof any == "object" && Object.keys(any).length < 1) {
console.log("null object")
} else {
console.log(any)
}
}
const http = function(url, options = {},noAuth = false,timeout = request_timeout) {
if (options.method === "POST" && options.data) {
options.body = JSON.stringify(options.data);
options.headers = Object.assign({
"content-type": "application/json"
}, options.headers);
if (!noAuth){
options.headers = Object.assign({
'Authorization': 'alist-09ceb38a-f143-47f7-b255-c3eec819cd7b8RfQ6P4fxESnlox2sKdJQqlPfDrWzbgSOIqyFAmIlHmUFrcQ97CSr5yoGA5wkw70'
}, options.headers);
}
}
options.timeout = timeout;
try {
const res = req(url, options);
res.json = () => res && res.content ? JSON.parse(res.content) : null;
res.text = () => res && res.content ? res.content : "";
return res
} catch (e) {
return {
json() {
return null
},
text() {
return ""
}
}
}
};
["get", "post"].forEach(method => {
http[method] = function(url, options = {},noAuth = false,timeout = request_timeout) {
return http(url, Object.assign(options, {
method: method.toUpperCase()
}),noAuth,timeout)
}
});
const __drives = {};
function isMedia(file) {
return /\.(dff|dsf|mp3|aac|wav|wma|cda|flac|m4a|mid|mka|mp2|mpa|mpc|ape|ofr|ogg|ra|wv|tta|ac3|dts|tak|webm|wmv|mpeg|mov|ram|swf|mp4|avi|rm|rmvb|flv|mpg|mkv|m3u8|ts|3gp|asf)$/.test(file.toLowerCase())
}
function get_drives_path(tid) {
const index = tid.indexOf("$");
const name = tid.substring(0, index);
const path = tid.substring(index + 1);
return {
drives: get_drives(name),
path: path
}
}
function get_drives(name) {
const {
settings,
api,
server
} = __drives[name];
if (settings.v3 == null) {
settings.title = "小雅的分类 Alist";
settings.v3 = true;
settings.version = "小雅魔改版";
settings.enableSearch = false
api.path = settings.v3 ? "/api/fs/list" : "/api/public/path";
api.file = settings.v3 ? "/api/fs/get" : "/api/public/path";
api.search = settings.v3 ? "/api/public/search" : "/api/public/search"
}
return __drives[name]
}
function init(ext) {
console.log("当前版本号:" + VERSION);
let data;
if (typeof ext == "object") {
data = ext;
print("alist ext:object")
} else if (typeof ext == "string") {
if (ext.startsWith("http")) {
let alist_data = ext.split(";");
let alist_data_url = alist_data[0];
search_type = alist_data.length > 2 ? alist_data[2] : search_type;
print(alist_data_url);
data = http.get(alist_data_url).json()
} else {
print("alist ext:json string");
data = JSON.parse(ext)
}
}
let drives = [];
if (Array.isArray(data) && data.length > 0 && data[0].hasOwnProperty("server") && data[0].hasOwnProperty("name")) {
drives = data
} else if (!Array.isArray(data) && data.hasOwnProperty("drives") && Array.isArray(data.drives)) {
drives = data.drives.filter(it => it.type && it.type === "alist" || !it.type)
}
print(drives);
__poster_mode = true;
searchDriver = (drives.find(x => x.search) || {}).name || "";
if (!searchDriver && drives.length > 0) {
searchDriver = drives[0].name
__poster_mode = false;
}
print(searchDriver);
drives.forEach(item => {
let _path_param = [];
if (item.params) {
_path_param = Object.keys(item.params);
_path_param.sort((a, b) => a.length - b.length)
}
let servers = item.server.split(";");
servers.forEach((server, index, array) => {
array[index] = server.replace(/\/$/, '');
});
let server = servers[0];
__drives[item.name] = {
name: item.name,
server: server,
servers: servers,
startPage: item.startPage || "/",
showAll: item.showAll === true,
search: !!item.search,
noAuth: !!item.noAuth,
noPoster: !!item.noPoster,
pathByApi: !!item.pathByApi,
isPreview: !!item.isPreview,
params: item.params || {},
_path_param: _path_param,
settings: {},
api: {},
isFullList: false,
getParams(path) {
const key = this._path_param.find(x => path.startsWith(x));
return Object.assign({}, this.params[key], {
path: path
})
},
getPath(path) {
try {
const res = http.post(this.server + this.api.path, {
data: this.getParams(path)
}, this.noAuth,5000);
return this.settings.v3 ? res.json().data.content : res.json().data.files;
} catch (error) {
}
for (const server of this.servers) {
try {
if (server !== this.server) {
const res = http.post(server + this.api.path, {
data: this.getParams(path)
}, this.noAuth,5000);
this.server = server;
return this.settings.v3 ? res.json().data.content : res.json().data.files;
}
} catch (error) {
}
}
return null;
},
getFile(path) {
let raw_url = this.server + "/d" + path;
raw_url = encodeURI(raw_url);
let previewSuccess = false;
try
{
if (isMedia(path) && this.isPreview)
{
const res = http.post(this.server + "/api/fs/other", {
data: Object.assign({},this.getParams(path),{method: "video_preview"})
}).json();
let urls = res.data.video_preview_play_info.live_transcoding_task_list;
raw_url = urls[urls.length-1].url;
previewSuccess = true;
}
}
catch(e)
{
previewSuccess = false;
raw_url = this.server + "/d" + path;
raw_url = encodeURI(raw_url);
}
if (!previewSuccess && this.pathByApi)
{
const res = http.post(this.server + "/api/fs/get", {
data: this.getParams(path)
}, this.noAuth).json();
raw_url = res.data.raw_url;
}
return {
raw_url: raw_url
}
},
isFolder(data) {
return data.type === 1
},
isVideo(data) {
return this.settings.v3 ? data.type === 2 || data.type === 0 || data.type === 3 : data.type === 3 || data.type === 0 || data.type === 4
},
is_subt(data) {
if (data.type === 1) {
return false
}
const ext = /\.(srt|ass|scc|stl|ttml)$/;
return ext.test(data.name)
},
getPic(data) {
let pic = this.settings.v3 ? data.thumb : data.thumbnail;
return pic || (this.isFolder(data) ? __folder_img : "")
},
getTime(data, isStandard) {
isStandard = isStandard || false;
try {
let tTime = data.updated_at || data.time_str || data.modified || "";
let date = "";
if (tTime) {
tTime = tTime.split("T");
date = tTime[0];
if (isStandard) {
date = date.replace(/-/g, "/")
}
tTime = tTime[1].split(/Z|\./);
date += " " + tTime[0]
}
return date
} catch (e) {
return ""
}
}
}
});
//__imageServer = __drives[searchDriver].server + "/image/";
try
{
__filter_data = http.get(__drives[searchDriver].server + "/tvbox/json/alist.filters.json").json().startPages;
}catch(e)
{
__filter_data = null;
}
print("init执行完毕")
}
function genFilters(tid){
let {
drives,
path
} = get_drives_path(tid);
if (!__poster_mode || drives.noPoster)
{
return [];
}
let values = [{
n: "全部分类",
v: "all"
}];
try
{
var data = __filter_data;
data = data.find(it => it.startPage === path).names;
data.forEach(item => {
let subpath = item;
values.push({
n: subpath,
v: subpath
});
});
} catch (e){
const list = drives.getPath(path);
list.forEach(item => {
if (drives.isFolder(item)) {
let subpath = item.name;
values.push({
n: subpath,
v: subpath
});
}
});
}
let filters = [{
key: "subpath",
name: "分类:",
value: values
},{
key: "douban",
name: "豆瓣评分:",
value: [{
n: "全部评分",
v: "0"
},{
n: "9分以上",
v: "9"
},{
n: "8分以上",
v: "8"
},{
n: "7分以上",
v: "7"
},{
n: "6分以上",
v: "6"
},{
n: "5分以上",
v: "5"
}]
},{
key: "doubansort",
name: "豆瓣排序:",
value: [{
n: "原始顺序",
v: "0"
},{
n: "豆瓣评分⬇️",
v: "1"
},{
n: "豆瓣评分⬆️",
v: "2"
}]
},{
key: "random",
name: "随机显示:",
value: [{
n: "固定显示",
v: "0"
},{
n: "随机显示️",
v: "9999999999"
},{
n: "随机200个",
v: "200"
},{
n: "随机500个",
v: "500"
}]
}];
return filters;
}
function home(filter) {
let classes = Object.keys(__drives).map(key => ({
type_id: `${key}$${__drives[key].startPage}`,
type_name: key,
type_flag: __drives[key].startPage === "/" || !__poster_mode || __drives[key].noPoster? "1" : "2"
}));
let filter_dict = {};
classes.forEach(it => {
filter_dict[it.type_id] = genFilters(it.type_id);
});
print("----home----");
print(classes);
return JSON.stringify({
class: classes,
filters: filter_dict
})
}
function homeVod(params) {
if (!searchDriver) {
return JSON.stringify({
list: []
})
} else {
let driver = __drives[searchDriver];
driver.vods = getAllVods("filter=last&num=" + __num,driver.name).list;
return JSON.stringify({
list: driver.vods
});
}
}
function parseSou(htmlContent){
const regex = /<a\s+href=([^>]*)>/g;
let matches = [];
let match;
while ((match = regex.exec(htmlContent)) !== null) {
if (match[1] === "/" || match[1] === "https://t.me/xiaoyaliu"){
continue;
}
matches.push(match[1]);
}
return matches;
}
function getAllVods (para,drivename,pg = "0",filter = false,extend={}) {
let driver = __drives[drivename];
let orgdrive = __drives[drivename];
let surl = driver.server + "/sou?" + para + "&type=video&num=" + __num;
let fl = filter ? extend : {};
let isflmode = !!fl.subpath || !!fl.doubansort || !!fl.douban || !!fl.random;
let fullList = false;
pg = parseInt(pg);
if (!pg || pg > 1 || isflmode){
surl = driver.server + "/sou?" + para + "&type=video";
fullList = true;
}
if (pg === 1 && !isflmode && orgdrive.name === "每日更新")
{
surl = driver.server + "/sou?filter=last&num=" + __num + "&type=video";
}
if (orgdrive.startPage !== "/"){
if (orgdrive.isFullList || (!fullList && orgdrive.vods != null)){
return {
list: orgdrive.vods
};
}
}
else
{
orgdrive.isFullList = true;
}
let html = http.get(surl).text();
let lists = parseSou(html);
let vods = [];
let vods_pikpak = [];
let vods_ali = [];
let excludeReg = /\.(pdf|epub|mobi|txt|doc|lrc)$/;
let pikpakRegex = /pikpak/;
let cnt = 0;
lists.forEach(it => {
let isPikpak = false;
let vhref = it;
if (vhref) {
vhref = unescape(vhref)
}
if (excludeReg.test(vhref.toLowerCase())) {
return
}
if (pikpakRegex.test(vhref.toLowerCase())) {
isPikpak = true;
}
const parts = vhref.split('#')
if (parts.length >= 2) {
vhref = parts[0]
}
cnt++;
let vid = __drives[drivename].name + "$" + vhref + "#search#";
if (showMode === "all") {
vid += "#all#"
}
let have_pic = 0;
let vod_dbid = "";
let poster = '';
let douban_rate = '';
let display_path = '';
if (parts.length === 5) {
let uri_parts = parts[4].split('://')
poster = __imageServer + uri_parts[1] + __imageSource;
have_pic = 1;
}
else{
// return
}
if (parts.length >= 4) {
douban_rate = parts[3] ;
}
if (parts.length >= 3) {
vod_dbid = parts[2] ;
}
if (parts.length < 2) {
let path_list = parts[0].split('/');
//display_path = path_list[path_list.length - 2] + '/' + path_list[path_list.length - 1];
display_path = path_list[path_list.length - 1];
}
vods = vods_ali;
if (isPikpak){
vods = vods_pikpak;
}
vods.push({
vod_id: vid,
vod_dbid: vod_dbid,
vod_name: parts.length <2 ? display_path :parts[1],
vod_tag: "file",
vod_pic: have_pic ? poster : "http://img.xiaoya.pro/xiaoya.jpg",
vod_remarks: douban_rate == '' ? "" : "豆瓣:" + douban_rate,
vod_fullpath: parts[0],
vod_poster: have_pic
});
});
vods = vods_ali.concat(vods_pikpak);
if (!orgdrive.isFullList){
orgdrive.isFullList = fullList;
}
let vods_poster = vods.filter(it => it.vod_poster);
let vods_none_poster = vods.filter(it => !it.vod_poster);
vods = vods_poster.concat(vods_none_poster);
orgdrive.vods = vods;
return {
list: vods
}
}
function removeDuplicates(arr) {
const seen = new Set();
return arr.filter((item) => {
const itemString = JSON.stringify(item);
if (!seen.has(itemString)) {
seen.add(itemString);
return true;
}
return false;
});
}
function root_category(tid, pg, filter, extend) {
let vods = [];
let orid = tid.replace(/#all#|#search#/g, "");
let {
drives,
path
} = get_drives_path(orid);
drives.vods = getAllVods("box=" + path,drives.name,pg,filter,extend).list
let fullpath = path;
let fl = filter ? extend : {};
if(fl.subpath && fl.subpath !== "all"){
fullpath = path + "/" + fl.subpath;
}
drives.vods.forEach(it => {
const pattern = new RegExp("^" + fullpath);
if (!pattern.test(it.vod_fullpath))
{
return
}
vods.push(it);
});
let douban = 0;
if(fl.douban){
douban = parseFloat(fl.douban);
}
let highRatedVods = vods.filter(vod => {
var ratingString = vod.vod_remarks.replace("豆瓣:", "").trim();
if (ratingString === ""){
ratingString="0";
}
return ratingString !== '' && parseFloat(ratingString) >= douban;
});
vods = highRatedVods;
if(fl.doubansort && fl.doubansort === "1"){
vods.sort((a, b) => {
const ratingA = parseFloat(a.vod_remarks.replace("豆瓣:", "").trim()) || 0;
const ratingB = parseFloat(b.vod_remarks.replace("豆瓣:", "").trim()) || 0;
return ratingB - ratingA;
});
}
if(fl.doubansort && fl.doubansort === "2"){
vods.sort((a, b) => {
const ratingA = parseFloat(a.vod_remarks.replace("豆瓣:", "").trim()) || 0;
const ratingB = parseFloat(b.vod_remarks.replace("豆瓣:", "").trim()) || 0;
return ratingA - ratingB;
});
}
let random = 0;
if(fl.random)
{
random = parseInt(fl.random);
}
if(random !== 0)
{
let keepsequence = (fl.doubansort && fl.doubansort !== "0");
vods = getRandomElements(vods,random,keepsequence);
}
return JSON.stringify({
page: 1,
pagecount: drives.isFullList ? 1 : 2,
//pagecount: 2,
//limit: vods.length,
//total: vods.length,
list: vods
})
}
function getRandomElements(arr, count, keepsequence) {
if (arr.length <= count) {
if (keepsequence) {
return arr.slice();
} else {
const shuffledArray = arr.slice();
for (let i = shuffledArray.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];
}
return shuffledArray;
}
}
const randomIndexes = [];
const selectedIndexes = new Set();
while (randomIndexes.length < count) {
const index = Math.floor(Math.random() * arr.length);
if (!selectedIndexes.has(index)) {
selectedIndexes.add(index);
randomIndexes.push(index);
}
}
if (keepsequence) {
randomIndexes.sort((a, b) => a - b);
}
const result = randomIndexes.map(index => arr[index]);
return result;
}
function category(tid, pg, filter, extend) {
let orid = tid.replace(/#all#|#search#/g, "");
let {
drives,
path
} = get_drives_path(orid);
if ( __poster_mode && !drives.noPoster && path !=="/" && path === drives.startPage){
return root_category(tid, pg, filter, extend);
}
const id = orid.endsWith("/") ? orid : orid + "/";
let list = null;
if (!filter && extend.list)
{
list = extend.list;
}else
{
list = drives.getPath(path);
}
let subList = [];
let vodFiles = [];
let allList = [];
let fl = filter ? extend : {};
if (fl.show) {
showMode = fl.show
}
list.forEach(item => {
if (drives.is_subt(item)) {
subList.push(item.name)
}
if ( !drives.isFolder(item) && !/\.(dff|dsf|mp3|aac|wav|wma|cda|flac|m4a|mid|mka|mp2|mpa|mpc|ape|ofr|ogg|ra|wv|tta|ac3|dts|tak|webm|wmv|mpeg|mov|ram|swf|mp4|avi|rm|rmvb|flv|mpg|mkv|m3u8|ts|3gp|asf)$/.test(item.name)){
return
}
if (!drives.showAll && !drives.isFolder(item) && !drives.isVideo(item)) {
return
}
let vod_time = drives.getTime(item);
let vod_size = get_size(item.size);
let remark = vod_time.split(" ")[0].substr(3) + "\t" + vod_size;
let vod_id = id + item.name + (drives.isFolder(item) ? "/" : "");
if (showMode === "all") {
vod_id += "#all#"
}
print(vod_id);
const vod = {
vod_id: vod_id,
vod_name: item.name.replaceAll("$", "").replaceAll("#", ""),
vod_pic: drives.getPic(item),
vod_time: vod_time,
vod_size: item.size,
vod_tag: drives.isFolder(item) ? "folder" : "file",
// vod_tag: "file",
vod_remarks: drives.isFolder(item) ? remark + " 文件夹" : remark
};
if (drives.isVideo(item)) {
vodFiles.push(vod)
}
allList.push(vod)
});
if (vodFiles.length === 1 && subList.length > 0) {
let sub;
if (subList.length === 1) {
sub = subList[0]
} else {
let subs = JSON.parse(JSON.stringify(subList));
subs.sort((a, b) => {
let a_similar = (a.includes("chs") ? 100 : 0) + levenshteinDistance(a, vodFiles[0].vod_name);
let b_similar = (b.includes("chs") ? 100 : 0) + levenshteinDistance(b, vodFiles[0].vod_name);
if (a_similar > b_similar) {
return 1
} else {
return -1
}
});
sub = subs.slice(-1)[0]
}
vodFiles[0].vod_id += "@@@" + sub;
vodFiles[0].vod_remarks += "🏷️"
} else {
vodFiles.forEach(item => {
var lh = 0;
let sub;
subList.forEach(s => {
const l = levenshteinDistance(s, item.vod_name);
if (l > 60 && l > lh) {
sub = s
lh = l;
}
});
if (sub) {
item.vod_id += "@@@" + sub;
item.vod_remarks += "🏷️"
}
})
}
if (fl.order) {
let key = fl.order.split("_").slice(0, -1).join("_");
let order = fl.order.split("_").slice(-1)[0];
print(`排序key:${key},排序order:${order}`);
if (key.includes("name")) {
detail_order = "name";
allList = sortListByName(allList, key, order)
} else if (key.includes("cn")) {
detail_order = "cn";
allList = sortListByCN(allList, "vod_name", order)
} else if (key.includes("time")) {
detail_order = "time";
allList = sortListByTime(allList, key, order)
} else if (key.includes("size")) {
detail_order = "size";
allList = sortListBySize(allList, key, order)
} else if (fl.order.includes("none")) {
detail_order = "none";
print("不排序")
}
} else {
if (detail_order !== "none") {
allList = sortListByName(allList, "vod_name", "asc")
}
}
if (pg && vodFiles.length > 1) {
const vod = {
vod_id: id + "~playlist",
vod_name: "播放列表",
vod_pic: __play_list_img,
vod_tag: "file",
vod_remarks: "共" + vodFiles.length + "集"
};
allList.unshift(vod)
}
print("----category----" + `tid:${tid},detail_order:${detail_order},showMode:${showMode}`);
return JSON.stringify({
page: 1,
pagecount: 1,
limit: allList.length,
total: allList.length,
list: allList
})
}
function getAll(otid, tid, drives, path,ls = null,nopic = false) {
try {
const content = category(tid, null, false, {list: ls});
const isFile = isMedia(otid.replace(/#all#|#search#/g, "").split("@@@")[0]);
const {
list
} = JSON.parse(content);
let vod_play_url = [];
list.forEach(x => {
if (x.vod_tag === "file") {
let vid = x.vod_id.replace(/#all#|#search#/g, "");
vod_play_url.push(`${x.vod_name}$${drives.name}~~~${vid.substring(vid.indexOf("$")+1)}`)
}
});
const pl = path.split("/").filter(it => it);
let vod_name = pl[pl.length - 1] || drives.name;
if (vod_name === drives.name) {
print(pl)
}
if (otid.includes("#search#")) {
// vod_name += "[搜]"
}
let orvod = nopic ? null : findVodById(drives,tid);
let vod_pic = orvod !== null ? orvod.vod_pic : "https://avatars.githubusercontent.com/u/97389433?s=120&v=4";
let vod = {
vod_id: otid,
vod_name: vod_name,
type_name: "文件夹",
vod_pic: vod_pic,
vod_content: tid,
vod_tag: isFile ? "file" : "folder",
vod_play_from: drives.name,
vod_play_url: vod_play_url.join("#"),
vod_remarks: drives.settings.title
};
print("----detail1----");
print(vod);
return JSON.stringify({
list: [vod]
})
} catch (e) {
print(e.message);
return JSON.stringify({
list: [{}]
})
}
}
function playlist(otid, tid, drives, path) {
tid = tid.replace('/~playlist', '')
otid = otid.replace('/~playlist', '')
path = path.replace('/~playlist', '')
return getAll(otid, tid, drives, path)
}
function findVodById(drives, targetVodId) {
targetVodId = targetVodId.replace(/#all#|#search#/g, "");
let foundVod = null;
// 使用 Array.find 查找元素
if (drives !== null && drives.vods != null) {
foundVod = drives.vods.find(vod => vod.vod_id.replace(/#all#|#search#/g, "") === targetVodId);
}
if (!foundVod)
{
try
{
const result = get_drives_path(targetVodId);
let driver = drives;
let path = result.path;
let wd = "/";
const parts = path.split('/');
if (parts.length >1)
{
wd += parts[1];
}
if (wd !== "/" && !drives.noPoster)
{
foundVod = getAllVods("box=" + wd,driver.name).list.find(vod =>{
let r = get_drives_path(vod.vod_id.replace(/#all#|#search#/g, ""));
return path === r.path;
});
}
}catch(e)
{
foundVod = null;
}
}
return foundVod || null;
}
function isPathFolder(path) {
return !(/\.(dff|dsf|mp3|aac|wav|wma|cda|flac|m4a|mid|mka|mp2|mpa|mpc|ape|ofr|ogg|ra|wv|tta|ac3|dts|tak|webm|wmv|mpeg|mov|ram|swf|mp4|avi|rm|rmvb|flv|mpg|mkv|m3u8|ts|3gp|asf|nfo)$/.test(path.toLowerCase()));
}
function genFolderPlayList(drives,path,url,from)
{
let vod_play_url = url;
let vod_play_from =from;
let subFolderList = [];
try
{
let list = drives.getPath(path);
list.forEach(item => {
if (!drives.isFolder(item)) {
return
}
subFolderList.push(item.name)
});
var searchurl = drives.name + "$" + path;
var tempvod = getAll(searchurl + "#search#", searchurl, drives, "/" + path,list,true);
if (JSON.parse(tempvod).list[0].vod_play_url != "")
{
vod_play_url = vod_play_url+"$$$"+JSON.parse(tempvod).list[0].vod_play_url;
vod_play_from = vod_play_from+"$$$"+path.substring(path.lastIndexOf("/") + 1);
}
}
catch(e)
{
vod_play_url = url;
vod_play_from =from;
}
subFolderList.forEach(item => {
const result = genFolderPlayList(drives,path + "/" + item,vod_play_url,vod_play_from);
vod_play_url = result.vod_play_url;
vod_play_from = result.vod_play_from;
});
return {
vod_play_url: vod_play_url,
vod_play_from: vod_play_from
};
}
function getDoubanInfo(id) {
try{
if (id === "")
{
return {};
}
const url = "https://movie.douban.com/subject/" + id +"/";
let html = http.get(url).text();
const $ = cheerio.load(html);
let plot = $('#link-report-intra span[property="v:summary"]').text().trim();
const yearElement = $('.year');
let year = yearElement.text().replace(/\(|\)/g, '');
let region = "";
var text = html;
var regex = /<span class="pl">制片国家\/地区:<\/span>[\s\n]*([^<]+)/;
var match = text.match(regex);
if (match && match[1]) {
region = match[1].trim();
}
const actorElements = $('meta[property^="video:actor"]');
let actors = actorElements.map((index, element) => {
return $(element).attr('content');
}).get();
actors = actors.join('/');
const directorElement = $('meta[property="video:director"]');
const director = directorElement.attr('content');
const genreElement = $('span.pl:contains("类型:")');
const type = genreElement.nextAll('span[property="v:genre"]').map((index, element) => {
return $(element).text();
}).get().join('/');
return {
plot,
year,
region,
actors,
director,
type
};
}catch(e){
return {};
}
}
function getFolderVodDetail(tid){
let orid = tid.replace(/#all#|#search#/g, "");
let {
drives,
path
} = get_drives_path(orid);
if (!isPathFolder(path.toLowerCase())){
return "";
}
if (path.endsWith("/~playlist")){
return "";
}
let orvod = findVodById(drives,tid) ;
let vod_pic = orvod !== null ? orvod.vod_pic : "https://avatars.githubusercontent.com/u/97389433?s=120&v=4";
let {
vod_play_url,
vod_play_from
} = genFolderPlayList(drives,path,"","");
vod_play_from = vod_play_from.replace(/^[$]{3}/, '');
vod_play_url = vod_play_url.replace(/^[$]{3}/, '');
let doubanInfo = {};
let vod_name = path.substring(path.lastIndexOf("/") + 1);
if (orvod)
{
vod_name = orvod.vod_name;
doubanInfo = getDoubanInfo(orvod.vod_dbid);
}
let vod_content = doubanInfo.plot ? doubanInfo.plot + " \n\n文件路径" + path : path;
let vod = {
vod_id: orid,
vod_name: vod_name,
type_name: doubanInfo.type,
vod_pic: vod_pic,
vod_content: vod_content,
vod_actor: doubanInfo.actors,
vod_area: doubanInfo.region,
vod_director: doubanInfo.director,
vod_year: doubanInfo.year,
vod_play_from: vod_play_from,
vod_play_url: vod_play_url,
vod_remarks: drives.settings.title
};
return JSON.stringify({
list: [vod]
})
}
function detail(tid) {
let folderVod = getFolderVodDetail(tid.split("@@@")[0]);
if (folderVod !== ""){
return folderVod;
}
let isSearch = tid.includes("#search#");
let isAll = tid.includes("#all#");
let otid = tid;
tid = tid.replace(/#all#|#search#/g, "");
let isFile = isMedia(tid.split("@@@")[0]);
print(`isFile:${tid}?${isFile}`);
let {
drives,
path
} = get_drives_path(tid);
print(`drives:${drives},path:${path}`);
if (path.endsWith("/")) {
return getAll(otid, tid, drives, path)
} else if (path.endsWith("/~playlist")) {
return playlist(otid, tid, drives, path)
} else {
if (isSearch && !isFile) {
return getAll(otid, tid, drives, path)
} else if (isAll) {
let new_tid;
if (isFile) {
new_tid = tid.split("/").slice(0, -1).join("/") + "/"
} else {
new_tid = tid
}
print(`全集模式 tid:${tid}=>tid:${new_tid}`);
let {
drives,
path
} = get_drives_path(new_tid);
return getAll(otid, new_tid, drives, path)
} else if (isFile) {
let paths = path.split("@@@");
let orvod = findVodById(drives,tid);
let vod_pic = orvod !== null ? orvod.vod_pic : "https://avatars.githubusercontent.com/u/97389433?s=120&v=4";
let doubanInfo = {};
let vod_name = paths[0].substring(paths[0].lastIndexOf("/") + 1);
if (orvod)
{
vod_name = orvod.vod_name;
doubanInfo = getDoubanInfo(orvod.vod_dbid);
}
let vod_content = doubanInfo.plot ? doubanInfo.plot + " \n\n文件路径" + paths[0]: paths[0];
let vod = {
vod_id: otid,
vod_name: vod_name,
type_name: doubanInfo.type,
vod_pic: vod_pic,
vod_content: vod_content,
vod_actor: doubanInfo.actors,
vod_area: doubanInfo.region,
vod_director: doubanInfo.director,
vod_year: doubanInfo.year,
vod_play_from: drives.name,
vod_play_url: vod_name + "$" + drives.name + "~~~" + path,
vod_remarks: drives.settings.title
};
print("----detail2----");
print(vod);
return JSON.stringify({
list: [vod]
})
} else {
return JSON.stringify({
list: []
})
}
}
}
function play(flag, id, flags) {
if (__drives[flag]==null){
//flag = __drives[searchDriver].name;
}
let urls = id.split("@@@");
flag = urls[0].split("~~~")[0];
urls[0] = urls[0].split("~~~")[1];
const drives = get_drives(flag);
let vod = {
parse: 0,
playUrl: "",
url: drives.getFile(urls[0]).raw_url
};
if (urls.length >= 2) {
const path = urls[0].substring(0, urls[0].lastIndexOf("/") + 1);
vod.subt = drives.getFile(path + urls[1]).raw_url
}
print("----play----");
print(vod);
return JSON.stringify(vod)
}
function search(wd, quick) {
print(__drives);
print("可搜索的alist驱动:" + searchDriver);
if (!searchDriver || !wd) {
return JSON.stringify({
list: []
})
} else {
let driver = __drives[searchDriver];
wd = wd.split(" ").filter(it => it.trim()).join("+");
print(driver);
driver.vods = getAllVods("box=" + wd,driver.name).list;
return JSON.stringify({
page: 1,
pagecount: 1,
list: driver.vods
});
}
}
function get_size(sz) {
if (sz <= 0) {
return ""
}
let filesize = "";
if (sz > 1024 * 1024 * 1024 * 1024) {
sz /= 1024 * 1024 * 1024 * 1024;
filesize = "TB"
} else if (sz > 1024 * 1024 * 1024) {
sz /= 1024 * 1024 * 1024;
filesize = "GB"
} else if (sz > 1024 * 1024) {
sz /= 1024 * 1024;
filesize = "MB"
} else if (sz > 1024) {
sz /= 1024;
filesize = "KB"
} else {
filesize = "B"
}
let sizeStr = sz.toFixed(2) + filesize,
index = sizeStr.indexOf("."),
dou = sizeStr.substr(index + 1, 2);
if (dou === "00") {
return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)
} else {
return sizeStr
}
}
function levenshteinDistance(str1, str2) {
return 100 - 100 * distance(str1, str2) / Math.max(str1.length, str2.length)
}
function naturalSort(options) {
if (!options) {
options = {}
}
return function(a, b) {
if (options.key) {
a = a[options.key];
b = b[options.key]
}
var EQUAL = 0;
var GREATER = options.order === "desc" ? -1 : 1;
var SMALLER = -GREATER;
var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi;
var sre = /(^[ ]*|[ ]*$)/g;
var dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
var hre = /^0x[0-9a-f]+$/i;
var ore = /^0/;
var normalize = function normalize(value) {
var string = "" + value;
return options.caseSensitive ? string : string.toLowerCase()
};
var x = normalize(a).replace(sre, "") || "";
var y = normalize(b).replace(sre, "") || "";
var xN = x.replace(re, "\0$1\0").replace(/\0$/, "").replace(/^\0/, "").split("\0");
var yN = y.replace(re, "\0$1\0").replace(/\0$/, "").replace(/^\0/, "").split("\0");
if (!x && !y) return EQUAL;
if (!x && y) return GREATER;
if (x && !y) return SMALLER;
var xD = parseInt(x.match(hre)) || xN.length != 1 && x.match(dre) && Date.parse(x);
var yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null;
var oFxNcL, oFyNcL;
if (yD) {
if (xD < yD) return SMALLER;
else if (xD > yD) return GREATER
}
for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
oFxNcL = !(xN[cLoc] || "").match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
oFyNcL = !(yN[cLoc] || "").match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return isNaN(oFxNcL) ? GREATER : SMALLER;
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += "";
oFyNcL += ""
}
if (oFxNcL < oFyNcL) return SMALLER;
if (oFxNcL > oFyNcL) return GREATER
}
return EQUAL
}
}
const sortListByName = (vodList, key, order) => {
if (!key) {
return vodList
}
order = order || "asc";
return vodList.sort(naturalSort({
key: key,
order: order,
caseSensitive: true
}))
};
const getTimeInt = timeStr => {
return new Date(timeStr).getTime()
};
const sortListByTime = (vodList, key, order) => {
if (!key) {
return vodList
}
let ASCarr = vodList.sort((a, b) => {
a = a[key];
b = b[key];
return getTimeInt(a) - getTimeInt(b)
});
if (order === "desc") {
ASCarr.reverse()
}
return ASCarr
};
const sortListBySize = (vodList, key, order) => {
if (!key) {
return vodList
}
let ASCarr = vodList.sort((a, b) => {
a = a[key];
b = b[key];
return (Number(a) || 0) - (Number(b) || 0)
});
if (order === "desc") {
ASCarr.reverse()
}
return ASCarr
};
export default {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search
};