diff --git a/base/custom.conf b/base/custom.conf index 03ad06b40ab3d0c059a645d2470564d863926d5f..086d28fe47e610d983b2377cfef7c29612290ccc 100644 --- a/base/custom.conf +++ b/base/custom.conf @@ -21,7 +21,7 @@ }, # 缓存js # {"key":"js_origin","name":"JS(原始)","type":3,"api":"{{host}}/txt/js/原始JS.js","searchable":1,"quickSearch":1,"filterable":1,"ext":""}, - {"key":"Alist","name":"Alist","type":3,"api":"{{host}}/libs/alist.js","searchable":0,"quickSearch":0,"filterable":0,"ext":"{{host}}/txt/json/alist.json"}, + {"key":"Alist","name":"Alist","type":3,"api":"{{host}}/libs/alist.min.js","searchable":0,"quickSearch":0,"filterable":0,"ext":"{{host}}/txt/json/alist.json"}, {"key":"js_origin_puto","name":"原始JS(pluto)","type":3,"api":"js_origin_test","searchable":1,"quickSearch":1,"filterable":1,"ext":"{{host}}/txt/js/原始JS/origin.js"}, {"key":"js_origin_tvb","name":"原始JS(俊tvb)","type":3,"api":"{{host}}/txt/js/origin/原始JS.js","searchable":1,"quickSearch":1,"filterable":1,"ext":"{}"}, {"key":"drpy_zbk","name":"真不卡(drpy)","type":3,"api":"js_drpy_zbk","searchable":1,"quickSearch":1,"filterable":1,"ext":"{{host}}/txt/pluto/drpy.js"}, diff --git a/js/version.txt b/js/version.txt index e79ffb278b6d24a767051cab28b05e95166f0e62..889e8207d240ca9d69fbe14b0421bd1c7fb78eeb 100644 --- a/js/version.txt +++ b/js/version.txt @@ -1 +1 @@ -3.9.22beta3 \ No newline at end of file +3.9.23 \ No newline at end of file diff --git a/libs/alist.js b/libs/alist.js index 2a1b6aa84320cc563337a9c4bd24fffb71838840..c762c6f7ded8e94702e38e354b372c0e24d53d1e 100644 --- a/libs/alist.js +++ b/libs/alist.js @@ -22,7 +22,7 @@ String.prototype.rstrip = function (chars) { let regex = new RegExp(chars + "$"); return this.replace(regex, ""); }; - +var showMode = 'single'; /** * 打印日志 * @param any 任意变量 @@ -144,7 +144,28 @@ function init(ext) { getPic(data) { let pic = this.settings.v3 ? data.thumb : data.thumbnail; return pic || (this.isFolder(data) ? "http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png" : ''); - } + }, + 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) { + // print(e.message); + // print(data); + return '' + } + }, } } ); @@ -158,7 +179,11 @@ function home(filter) { type_flag: '1', })); let filter_dict = {}; - let filters = [{'key': 'order', 'name': '排序方式', 'value': [{'n': '名称正序', 'v': 'vod_name_asc'}, {'n': '名称倒序', 'v': 'vod_name_desc'}]}]; + let filters = [{'key': 'order', 'name': '排序', 'value': [{'n': '名称⬆️', 'v': 'vod_name_asc'}, {'n': '名称⬇️', 'v': 'vod_name_desc'}, + {'n': '时间⬆️', 'v': 'vod_time_asc'}, {'n': '时间⬇️', 'v': 'vod_time_desc'}, + {'n': '大小⬆️', 'v': 'vod_size_asc'}, {'n': '大小⬇️', 'v': 'vod_size_desc'}]}, + {'key': 'show', 'name': '播放展示', 'value': [{'n': '单集', 'v': 'single'},{'n': '全集', 'v': 'all'}]} + ]; classes.forEach(it=>{ filter_dict[it.type_id] = filters; }); @@ -185,14 +210,18 @@ function category(tid, pg, filter, extend) { if (!drives.showAll && !drives.isFolder(item) && !drives.isVideo(item)) { return //只显示视频文件和文件夹 } - let remark = get_size(item.size); + let vod_time = drives.getTime(item); + let vod_size = get_size(item.size); + let remark = vod_time.split(' ')[0].substr(3)+'\t'+vod_size; const vod = { 'vod_id': id + item.name + (drives.isFolder(item) ? '/' : ''), '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_remarks': drives.isFolder(item) ? remark + ' 文件夹' : remark - } + }; if (drives.isVideo(item)) { vodFiles.push(vod); } @@ -219,7 +248,8 @@ function category(tid, pg, filter, extend) { sub = subs.slice(-1)[0]; } vodFiles[0].vod_id += "@@@" + sub; - vodFiles[0].vod_remarks += " 有字幕"; + // vodFiles[0].vod_remarks += " 有字幕"; + vodFiles[0].vod_remarks += "🏷️"; } else { vodFiles.forEach(item => { const lh = 0; @@ -233,21 +263,31 @@ function category(tid, pg, filter, extend) { }); if (sub) { item.vod_id += "@@@" + sub; - item.vod_remarks += " 有字幕"; + // item.vod_remarks += " 有字幕"; + item.vod_remarks += "🏷️"; } }); } - print("----category----"); + print("----category----,tid:"+tid); let fl = filter?extend:{}; if(fl.order){ // print(fl.order); let key = fl.order.split('_').slice(0,-1).join('_'); let order = fl.order.split('_').slice(-1)[0]; print(`排序key:${key},排序order:${order}`); - allList = sortListByName(allList,key,order); + if(key.includes('name')){ + allList = sortListByName(allList,key,order); + }else if(key.includes('time')){ + allList = sortListByTime(allList,key,order); + }else if(key.includes('size')){ + allList = sortListBySize(allList,key,order); + } }else{ allList = sortListByName(allList,'vod_name','asc'); } + if(fl.show){ + showMode = fl.show; + } // print(allList); return JSON.stringify({ 'page': 1, @@ -258,9 +298,8 @@ function category(tid, pg, filter, extend) { }); } -function detail(tid) { - let { drives, path } = get_drives_path(tid); - if (path.endsWith("/")) { //长按文件夹可以 加载里面全部视频到详情 +function getAll(tid,drives,path){ + try { const content = category(tid, null, false, null); const { list } = JSON.parse(content); let vod_play_url = []; @@ -285,24 +324,41 @@ function detail(tid) { print("----detail1----"); print(vod); return JSON.stringify({ 'list': [vod] }); + }catch (e) { + print(e.message); + return JSON.stringify({ 'list': [{}] }); + } +} + +function detail(tid) { + let { drives, path } = get_drives_path(tid); + if (path.endsWith("/")) { //长按文件夹可以 加载里面全部视频到详情 + return getAll(tid,drives,path); } else { - let paths = path.split("@@@"); - let vod_name = paths[0].substring(paths[0].lastIndexOf("/") + 1); - let vod = { - vod_id: tid, - vod_name: vod_name, - type_name: "文件", - vod_pic: "https://avatars.githubusercontent.com/u/97389433?s=120&v=4", - vod_content: tid, - vod_play_from: drives.name, - vod_play_url: vod_name + "$" + path, - vod_remarks: drives.settings.title, - }; - print("----detail2----"); - print(vod); - return JSON.stringify({ - 'list': [vod] - }); + if(showMode!=='all'){ + let paths = path.split("@@@"); + let vod_name = paths[0].substring(paths[0].lastIndexOf("/") + 1); + let vod = { + vod_id: tid, + vod_name: vod_name, + type_name: "文件", + vod_pic: "https://avatars.githubusercontent.com/u/97389433?s=120&v=4", + vod_content: tid, + vod_play_from: drives.name, + vod_play_url: vod_name + "$" + path, + vod_remarks: drives.settings.title, + }; + print("----detail2----"); + print(vod); + return JSON.stringify({ + 'list': [vod] + }); + }else{ + let new_tid = tid.split('/').slice(0,-1).join('/')+'/'; + print(`全集模式 tid:${tid}=>tid:${new_tid}`); + let { drives, path } = get_drives_path(new_tid); + return getAll(new_tid,drives,path); + } } } @@ -487,6 +543,42 @@ const sortListByName = (vodList,key,order) => { return ASCarr }; +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, diff --git a/libs/alist.min.js b/libs/alist.min.js new file mode 100644 index 0000000000000000000000000000000000000000..fa7c02187ed44c2134c60e0f003286f97586e742 --- /dev/null +++ b/libs/alist.min.js @@ -0,0 +1 @@ +import{distance}from"https://unpkg.com/fastest-levenshtein@1.0.16/esm/mod.js";import{getFirstLetterList}from"https://gitcode.net/qq_32394351/dr_py/-/raw/master/libs/pinyin_getFirstLetterList.js";String.prototype.rstrip=function(chars){let regex=new RegExp(chars+"$");return this.replace(regex,"")};var showMode="single";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={}){if(options.method==="POST"&&options.data){options.body=JSON.stringify(options.data);options.headers=Object.assign({"content-type":"application/json"},options.headers)}const res=req(url,options);res.json=()=>res.content?JSON.parse(res.content):null;res.text=()=>res.content;return res};["get","post"].forEach(method=>{http[method]=function(url,options={}){return http(url,Object.assign(options,{method:method.toUpperCase()}))}});const __drives={};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.v3=false;const data=http.get(server+"/api/public/settings").json().data;if(Array.isArray(data)){settings.title=data.find(x=>x.key==="title")?.value;settings.v3=false;settings.version=data.find(x=>x.key==="version")?.value;settings.enableSearch=data.find(x=>x.key==="enable search")?.value==="true"}else{settings.title=data.title;settings.v3=true;settings.version=data.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){const data=http.get(ext).json();data.forEach(item=>{let _path_param=[];if(item.params){_path_param=Object.keys(item.params);_path_param.sort((a,b)=>a.length-b.length)}__drives[item.name]={name:item.name,server:item.server.endsWith("/")?item.server.rstrip("/"):item.server,startPage:item.startPage||"/",showAll:item.showAll===true,params:item.params||{},_path_param:_path_param,settings:{},api:{},getParams(path){const key=this._path_param.find(x=>path.startsWith(x));return Object.assign({},this.params[key],{path:path})},getPath(path){const res=http.post(this.server+this.api.path,{data:this.getParams(path)}).json();return this.settings.v3?res.data.content:res.data.files},getFile(path){return{raw_url:this.server+"/d"+path}},isFolder(data){return data.type===1},isVideo(data){return this.settings.v3?data.type===2:data.type===3},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)?"http://img1.3png.com/281e284a670865a71d91515866552b5f172b.png":"")},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""}}}});print("init执行完毕")}function home(filter){let classes=Object.keys(__drives).map(key=>({type_id:`${key}$${__drives[key].startPage}`,type_name:key,type_flag:"1"}));let filter_dict={};let filters=[{key:"order",name:"排序",value:[{n:"名称⬆️",v:"vod_name_asc"},{n:"名称⬇️",v:"vod_name_desc"},{n:"时间⬆️",v:"vod_time_asc"},{n:"时间⬇️",v:"vod_time_desc"},{n:"大小⬆️",v:"vod_size_asc"},{n:"大小⬇️",v:"vod_size_desc"}]},{key:"show",name:"播放展示",value:[{n:"单集",v:"single"},{n:"全集",v:"all"}]}];classes.forEach(it=>{filter_dict[it.type_id]=filters});print("----home----");print(classes);return JSON.stringify({class:classes,filters:filter_dict})}function homeVod(params){return JSON.stringify({list:[]})}function category(tid,pg,filter,extend){let{drives,path}=get_drives_path(tid);const id=tid.endsWith("/")?tid:tid+"/";const list=drives.getPath(path);let subList=[];let vodFiles=[];let allList=[];list.forEach(item=>{if(drives.is_subt(item)){subList.push(item.name)}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;const vod={vod_id:id+item.name+(drives.isFolder(item)?"/":""),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_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=>{const lh=0;let sub;subList.forEach(s=>{const l=levenshteinDistance(s,item.vod_name);if(l>60&&l>lh){sub=s}});if(sub){item.vod_id+="@@@"+sub;item.vod_remarks+="🏷️"}})}print("----category----,tid:"+tid);let fl=filter?extend:{};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")){allList=sortListByName(allList,key,order)}else if(key.includes("time")){allList=sortListByTime(allList,key,order)}else if(key.includes("size")){allList=sortListBySize(allList,key,order)}}else{allList=sortListByName(allList,"vod_name","asc")}if(fl.show){showMode=fl.show}return JSON.stringify({page:1,pagecount:1,limit:allList.length,total:allList.length,list:allList})}function getAll(tid,drives,path){try{const content=category(tid,null,false,null);const{list}=JSON.parse(content);let vod_play_url=[];list.forEach(x=>{if(x.vod_tag==="file"){vod_play_url.push(`${x.vod_name}$${x.vod_id.substring(x.vod_id.indexOf("$")+1)}`)}});const pl=path.split("/");const vod_name=pl[pl.length-2]||drives.name;let vod={vod_id:tid,vod_name:vod_name,type_name:"文件夹",vod_pic:"https://avatars.githubusercontent.com/u/97389433?s=120&v=4",vod_content:tid,vod_tag:"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 detail(tid){let{drives,path}=get_drives_path(tid);if(path.endsWith("/")){return getAll(tid,drives,path)}else{if(showMode!=="all"){let paths=path.split("@@@");let vod_name=paths[0].substring(paths[0].lastIndexOf("/")+1);let vod={vod_id:tid,vod_name:vod_name,type_name:"文件",vod_pic:"https://avatars.githubusercontent.com/u/97389433?s=120&v=4",vod_content:tid,vod_play_from:drives.name,vod_play_url:vod_name+"$"+path,vod_remarks:drives.settings.title};print("----detail2----");print(vod);return JSON.stringify({list:[vod]})}else{let new_tid=tid.split("/").slice(0,-1).join("/")+"/";print(`全集模式 tid:${tid}=>tid:${new_tid}`);let{drives,path}=get_drives_path(new_tid);return getAll(new_tid,drives,path)}}}function play(flag,id,flags){const drives=get_drives(flag);const urls=id.split("@@@");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){return JSON.stringify({list:[]})}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)}const sortListByFirst=(vodList,key)=>{key=key||"vod_name";const symbol_list=[];const cn_list=[];const en_list=[];const num_list=[];vodList.forEach(vod=>{const{vod_name}=vod;if(/[\u4e00-\u9fa5]/.test(vod_name[0])){cn_list.push(vod)}else if(/[a-zA-Z]/.test(vod_name[0])){en_list.push(vod)}else if(/[\d]/.test(vod_name[0])){num_list.push(vod)}else{symbol_list.push(vod)}});const newList=[...cn_list.sort((a,b)=>a.vod_name[0]?.localeCompare(b.vod_name[0])),...en_list.sort((a,b)=>a.vod_name[0].localeCompare(b.vod_name[0])),...num_list.sort((a,b)=>a.vod_name[0]-b.vod_name[0]),...symbol_list.sort((a,b)=>a.vod_name[0]-b.vod_name[0])];return newList};function isAllChinese(str){return/^[\u4E00-\u9FA5]+$/.test(str)}function isChinese(char){return/^[\u4E00-\u9FA5]$/.test(char)}const sortListByName=(vodList,key,order)=>{if(!key){return vodList}order=order||"asc";let ASCarr=vodList.sort((a,b)=>{a=a[key];b=b[key];if(typeof a==="number"&&typeof b==="string"){return-1}if(typeof a==="string"&&typeof b==="number"){return 1}if(isNaN(a)||isNaN(b)){if(isAllChinese(a)&&!isAllChinese(b)){return 1}if(!isAllChinese(a)&&isAllChinese(b)){return-1}a=a.toString();b=b.toString();let result=0;for(let index=0;index<(a.length-b.length?b.length:a.length);index++){if(!isChinese(a[index])&&isChinese(b[index])){result=-1}if(isChinese(a[index])&&!isChinese(b[index])){result=1}if(isChinese(a[index])&&isChinese(b[index])){let pinyinA=getFirstLetterList(a[index]).toString();let pinyinB=getFirstLetterList(b[index]).toString();result=pinyinA.localeCompare(pinyinB,"zh-Hans-CN",{sensitivity:"accent"})}if(result!==0){break}}return result||a.toString().localeCompare(b.toString(),"zh-Hans-CN",{sensitivity:"accent"})}else{return Number(a)-Number(b)}});if(order==="desc"){ASCarr.reverse()}return ASCarr};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}; \ No newline at end of file diff --git a/readme.md b/readme.md index 6a66ab3617288d4030368ac47b925ba7be9cc535..85a216c1c0d2c0086476d04a7be896fc7325ac46 100644 --- a/readme.md +++ b/readme.md @@ -49,6 +49,12 @@ [dockerfile教程](https://blog.csdn.net/qq_46158060/article/details/125718218) [获取本地设备信息](https://blog.csdn.net/cui_yonghua/article/details/125508991) [获取本地设备信息](https://m.jb51.net/article/140716.htm) +###### 2022/11/22 +- [X] 增加了alist的api,版本号升级至 3.9.23 +- [X] 需要在custom.conf加一行自定义配置,例如: +```json +{"key":"Alist","name":"Alist","type":3,"api":"{{host}}/libs/alist.min.js","searchable":0,"quickSearch":0,"filterable":0,"ext":"{{host}}/txt/json/alist.json"}, +``` ###### 2022/11/21 - [X] 重新定义依赖代理逻辑 - [X] 设置中心增加自定义环境变量,演示源:007影视.js