-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
自动下载和搜索有较大的延迟 #1
Comments
你使用的是 golang 还是 cf-worker 版本? 目前 golang 版本和 cf-worker 版本都没有缓存机制,二者都是在监听到 弹弹play 客户端发起的 API 请求后,实时访问 dmhy 的相关搜索页面,从 HTML 中解析提取信息并返回。 按道理 "API 返回的信息" 应该和 "在浏览器中的搜索结果" 是一致的。 按照你的描述进行测试,当前 dmhy 主页的第一项为 "恶魔恋歌" ,为 2021-08-14_17:00 发布, 而在 2021-08-14_17:28 时进行的 搜索结果 中并未出现。 说明此时 dmhy 可能尚未将此条资源添加到索引中,即 "延迟" 可能是由 dmhy 本身引起的。 |
了解了,3Q |
我用 cf-worker 版本简单实现了一个 "搜索指令/选项" 的功能: 如果你感兴趣的话,可以帮我测试一下。 具体效果如下:
// https://github.com/LussacZheng/dandanplay-resource-service
// version: 0.0.4-alpha
// build: 2021-08-15 01:31 GMT+8
// wrangler: 1.19.0
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e){e.exports=JSON.parse('{"b":"0.0.4-alpha","a":"https://github.com/LussacZheng/dandanplay-resource-service"}')},function(e,t,n){"use strict";n.r(t);class r{constructor(e){const{keyword:t,options:n}=function(e){let t={};return{keyword:e.replace(/ ?\$(\w+)(:(\d+))?/gi,(e,n,r,o)=>(t[n]=parseInt(o)||1,"")),options:t}}(e);this.keyword=t,this.realtime=n.realtime||0}}function o(e,t){return e.replace(/\$\{(\w+)\}/gi,(e,n)=>t[n])}function a(e){const t=new Date(e).toLocaleString("default",{formatMatcher:"best fit",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"});return new Date(t+" UTC").toISOString().substr(0,19).replace("T"," ")}function s(e,t){if(0===t.length)return e[1];let n={};return t.length>e.length-1&&t.splice(e.length-1),t.forEach((t,r)=>{n[t]=e[r+1]}),n}var i=function(e,t,n,r="first"){switch(r){case"all":return function(e,t,n){const r=e.matchAll(t),o=Array.from(r,e=>s(e,n));return 0===o.length?null:o}(e,t,n);case"last":return function(e,t,n){const r=[...e.matchAll(t)],o=r[r.length-1];return 0===r.length?null:s(o,n)}(e,t,n);default:return function(e,t,n){let r=t.exec(e);return t.lastIndex=0,null===r?null:s(r,n)}(e,t,n)}};const u={headers:{"content-type":"application/json;charset=utf-8"}},l={headers:{"content-type":"text/html;charset=utf-8"}},c={headers:{accept:"text/html;charset=utf-8","user-agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"}};async function d(e,t=c){let n;try{n=await fetch(decodeURI(e),t)}catch(e){console.error(e)}return await async function(e){const{headers:t}=e,n=t.get("content-type");return n.includes("application/json")?await e.json():(n.includes("application/text")||n.includes("text/html"),await e.text())}(n)}const p="https://share.dmhy.org",h={type_and_subgroup_url:p+"/topics/advanced-search?team_id=0&sort_id=0&orderby=",list_url:p+"/topics/list/page/1?keyword=${keyword}&sort_id=${type}&team_id=${subgroup}&order=date-desc",index_url:p+"/topics/list/page/${realtime}"},g="未能成功解析标题",f=-2,y="未能成功解析类别",m=-1,w="未知字幕组",b="magnet_not_found_未能成功解析磁力链接或磁力链接不存在",_="未能成功解析资源发布页面",I="未能成功解析资源大小",v="1970-01-01 08:00:00",R=/<option value="(\d+)">(.+?)<\/option>/gim,S=/<option value="(\d+)" style="color: [\w#]+">(.+?)<\/option>/gim,x={HasMore:/下一頁/g,Resources:/<tr class="">(.*?)<\/tr>/gis,TypeId:/href="\/topics\/list\/sort_id\/(\d+)"/gim,TypeName:/<font color=[\w#]+>(.+)<\/font>/gim,SubgroupId:/href="\/topics\/list\/team_id\/(\d+)"/gim,SubgroupName:/\s+(.*)<\/a><\/span>/gim,Magnet:/href="(magnet:\?xt=urn:btih:.+?)"/gim,PageUrl:/href="(.+?)"\s*target="_blank"/gim,FileSize:/<td.*>([\w\.]+B)<\/td>/gim,PublishDate:/<span style="display: none;">([\d\/ :]+)<\/span>/gim,Title:/target="_blank" ?>(.+?)<\/a>/gis,TitleReplacer:/<span class="keyword">(.*?)<\/span>/gi};async function T(e){const t=new URL(encodeURI(e.url)).searchParams,n=t.get("type")||0,a=t.get("subgroup")||0,{keyword:s,realtime:u}=new r(decodeURIComponent(t.get("keyword"))),l=encodeURI(o(h.list_url,{keyword:s,type:n<0?0:n,subgroup:a<0?0:a}));let c=await d(l),p=function(e){let t={HasMore:null!==i(e,x.HasMore,[]),Resources:[]};const n=i(e,x.Resources,[],"all");return null===n||n.forEach(e=>{t.Resources.push(O(e))}),t}(c);if(u){const e=encodeURI(o(h.index_url,{realtime:u}));c=await d(e);const t=U(c,s,p.Resources);p.Resources=t.concat(p.Resources)}return p}function N(e){const t=e.replace(/&/gi,"&");let n=i(t,R,["Id","Name"],"all");return null===n?[]:(n.forEach(e=>e.Id=parseInt(e.Id)),n.shift(),n)}function P(e){let t=i(e,S,["Id","Name"],"all");return null===t?[]:(t.forEach(e=>e.Id=parseInt(e.Id)),t.unshift({Id:0,Name:"全部"}),t)}function U(e,t,n){let r=[];const o=i(e,x.Resources,[],"all");return null===o?result:(o.forEach(e=>{let o=O(e);const a=t.split(" ").every(e=>o.Title.includes(e)),s=n.some(e=>o.PageUrl===e.PageUrl);a&&!s&&r.push(o)}),r)}function O(e){const t=i(e,x.Title,[]),n=i(e,x.TypeId,[]),r=i(e,x.TypeName,[]),o=i(e,x.SubgroupId,[]),s=i(e,x.SubgroupName,[]),u=i(e,x.Magnet,[]),l=i(e,x.PageUrl,[]),c=i(e,x.FileSize,[]),d=i(e,x.PublishDate,[]);return{Title:null===t?g:t.trim().replace(x.TitleReplacer,"$1"),TypeId:parseInt(n)||f,TypeName:r||y,SubgroupId:parseInt(o)||m,SubgroupName:s||w,Magnet:u||b,PageUrl:null===l?_:p+l,FileSize:c||I,PublishDate:null===d?v:a(d)}}var k=n(0);const M=`\n<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width,initial-scale=1" />\n <title>弹弹play资源搜索节点API - v${k.b}</title>\n</head>\n<body>\n <h1>使用说明</h1>\n <h2>GitHub - <a href="${k.a}">LussacZheng/dandanplay-resource-service</a></h2>\n</body>\n</html>\n`;const j=e=>t=>t.method.toLowerCase()===e.toLowerCase(),L=j("connect"),$=j("delete"),E=j("get"),C=j("head"),A=j("options"),D=j("patch"),z=j("post"),F=j("put"),H=j("trace"),J=e=>t=>{const n=new URL(encodeURI(t.url)).pathname;return(n.match(e)||[])[0]===n};var W=class{constructor(){this.routes=[]}handle(e,t){return this.routes.push({conditions:e,handler:t}),this}connect(e,t){return this.handle([L,J(e)],t)}delete(e,t){return this.handle([$,J(e)],t)}get(e,t){return this.handle([E,J(e)],t)}head(e,t){return this.handle([C,J(e)],t)}options(e,t){return this.handle([A,J(e)],t)}patch(e,t){return this.handle([D,J(e)],t)}post(e,t){return this.handle([z,J(e)],t)}put(e,t){return this.handle([F,J(e)],t)}trace(e,t){return this.handle([H,J(e)],t)}all(e){return this.handle([],e)}route(e){const t=this.resolve(e);return t?t.handler(e):new Response("resource not found",{status:404,statusText:"not found",headers:{"content-type":"text/plain"}})}resolve(e){return this.routes.find(t=>!(t.conditions&&(!Array.isArray(t)||t.conditions.length))||("function"==typeof t.conditions?t.conditions(e):t.conditions.every(t=>t(e))))}};async function Z(e){const t=new W;t.get("/subgroup",async()=>{const e=await async function(){return{Subgroups:N(await d(h.type_and_subgroup_url))}}();return new Response(JSON.stringify(e),u)}),t.get("/type",async()=>{const e=await async function(){return{Types:P(await d(h.type_and_subgroup_url))}}();return new Response(JSON.stringify(e),u)}),t.get("/list",async e=>{const t=await T(e);return new Response(JSON.stringify(t),u)}),t.get("/",async()=>new Response(await async function(){let e;try{e=await d("https://cdn.jsdelivr.net/gh/LussacZheng/dandanplay-resource-service@dist/web/index.html"),e=o(e,{VERSION:k.b})}catch(t){e=M}return e}(),l));return await t.route(e)}addEventListener("fetch",e=>e.respondWith(Z(e.request)))}]); 目前的缺点如下:
此外,
|
感谢你的回复,我测试过新的脚本可以实现实时搜索的功能,并且可以配合自动下载关键词功能实现资源的实时自动下载,并且如你所反映的,无法实现简繁体的转换,不过对于我来说已经很实用了,谢谢(我用的是cf-worker)。 |
|
我发现这个新的脚本不支持多个关键词搜索,以侦探已死为例,如果搜索关键词“侦探已死”+“$realtime”可以得到实时结果,但是如果进一步增加关键词比如“侦探已死”+“$realtime”+“global”就无法得到实时数据,希望可以修复一下,或者在脚本里集成realtime search的功能 |
其实是支持的,只是我忘记了在使用 修复后的 // https://github.com/LussacZheng/dandanplay-resource-service
// version: 0.0.4-alpha.1
// build: 2021-08-15 22:41 GMT+8
// wrangler: 1.19.0
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e){e.exports=JSON.parse('{"b":"0.0.4-alpha.1","a":"https://github.com/LussacZheng/dandanplay-resource-service"}')},function(e,t,n){"use strict";n.r(t);class r{constructor(e){const{keyword:t,options:n}=function(e){let t={};return{keyword:e.replace(/ ?\$(\w+)(:(\d+))?/gi,(e,n,r,o)=>(t[n]=parseInt(o)||1,"")),options:t}}(e);this.keyword=t,this.realtime=n.realtime||0}}function o(e,t){return e.replace(/\$\{(\w+)\}/gi,(e,n)=>t[n])}function a(e){const t=new Date(e).toLocaleString("default",{formatMatcher:"best fit",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hourCycle:"h23"});return new Date(t+" UTC").toISOString().substr(0,19).replace("T"," ")}function s(e,t){if(0===t.length)return e[1];let n={};return t.length>e.length-1&&t.splice(e.length-1),t.forEach((t,r)=>{n[t]=e[r+1]}),n}var i=function(e,t,n,r="first"){switch(r){case"all":return function(e,t,n){const r=e.matchAll(t),o=Array.from(r,e=>s(e,n));return 0===o.length?null:o}(e,t,n);case"last":return function(e,t,n){const r=[...e.matchAll(t)],o=r[r.length-1];return 0===r.length?null:s(o,n)}(e,t,n);default:return function(e,t,n){let r=t.exec(e);return t.lastIndex=0,null===r?null:s(r,n)}(e,t,n)}};const u={headers:{"content-type":"application/json;charset=utf-8"}},l={headers:{"content-type":"text/html;charset=utf-8"}},c={headers:{accept:"text/html;charset=utf-8","user-agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"}};async function d(e,t=c){let n;try{n=await fetch(decodeURI(e),t)}catch(e){console.error(e)}return await async function(e){const{headers:t}=e,n=t.get("content-type");return n.includes("application/json")?await e.json():(n.includes("application/text")||n.includes("text/html"),await e.text())}(n)}const p="https://share.dmhy.org",h={type_and_subgroup_url:p+"/topics/advanced-search?team_id=0&sort_id=0&orderby=",list_url:p+"/topics/list/page/1?keyword=${keyword}&sort_id=${type}&team_id=${subgroup}&order=date-desc",index_url:p+"/topics/list/page/${realtime}"},g="未能成功解析标题",f=-2,y="未能成功解析类别",m=-1,w="未知字幕组",b="magnet_not_found_未能成功解析磁力链接或磁力链接不存在",_="未能成功解析资源发布页面",I="未能成功解析资源大小",v="1970-01-01 08:00:00",R=/<option value="(\d+)">(.+?)<\/option>/gim,S=/<option value="(\d+)" style="color: [\w#]+">(.+?)<\/option>/gim,x={HasMore:/下一頁/g,Resources:/<tr class="">(.*?)<\/tr>/gis,TypeId:/href="\/topics\/list\/sort_id\/(\d+)"/gim,TypeName:/<font color=[\w#]+>(.+)<\/font>/gim,SubgroupId:/href="\/topics\/list\/team_id\/(\d+)"/gim,SubgroupName:/\s+(.*)<\/a><\/span>/gim,Magnet:/href="(magnet:\?xt=urn:btih:.+?)"/gim,PageUrl:/href="(.+?)"\s*target="_blank"/gim,FileSize:/<td.*>([\w\.]+B)<\/td>/gim,PublishDate:/<span style="display: none;">([\d\/ :]+)<\/span>/gim,Title:/target="_blank" ?>(.+?)<\/a>/gis,TitleReplacer:/<span class="keyword">(.*?)<\/span>/gi};async function T(e){const t=new URL(encodeURI(e.url)).searchParams,n=t.get("type")||0,a=t.get("subgroup")||0,{keyword:s,realtime:u}=new r(decodeURIComponent(t.get("keyword"))),l=encodeURI(o(h.list_url,{keyword:s,type:n<0?0:n,subgroup:a<0?0:a}));let c=await d(l),p=function(e){let t={HasMore:null!==i(e,x.HasMore,[]),Resources:[]};const n=i(e,x.Resources,[],"all");return null===n||n.forEach(e=>{t.Resources.push(O(e))}),t}(c);if(u){const e=encodeURI(o(h.index_url,{realtime:u}));c=await d(e);const t=U(c,s,p.Resources);p.Resources=t.concat(p.Resources)}return p}function N(e){const t=e.replace(/&/gi,"&");let n=i(t,R,["Id","Name"],"all");return null===n?[]:(n.forEach(e=>e.Id=parseInt(e.Id)),n.shift(),n)}function P(e){let t=i(e,S,["Id","Name"],"all");return null===t?[]:(t.forEach(e=>e.Id=parseInt(e.Id)),t.unshift({Id:0,Name:"全部"}),t)}function U(e,t,n){let r=[];const o=i(e,x.Resources,[],"all");return null===o?result:(o.forEach(e=>{let o=O(e);const a=t.split(" ").every(e=>o.Title.toLowerCase().includes(e.toLowerCase())),s=n.some(e=>o.PageUrl===e.PageUrl);a&&!s&&r.push(o)}),r)}function O(e){const t=i(e,x.Title,[]),n=i(e,x.TypeId,[]),r=i(e,x.TypeName,[]),o=i(e,x.SubgroupId,[]),s=i(e,x.SubgroupName,[]),u=i(e,x.Magnet,[]),l=i(e,x.PageUrl,[]),c=i(e,x.FileSize,[]),d=i(e,x.PublishDate,[]);return{Title:null===t?g:t.trim().replace(x.TitleReplacer,"$1"),TypeId:parseInt(n)||f,TypeName:r||y,SubgroupId:parseInt(o)||m,SubgroupName:s||w,Magnet:u||b,PageUrl:null===l?_:p+l,FileSize:c||I,PublishDate:null===d?v:a(d)}}var k=n(0);const M=`\n<!DOCTYPE html>\n<html lang="zh-CN">\n<head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width,initial-scale=1" />\n <title>弹弹play资源搜索节点API - v${k.b}</title>\n</head>\n<body>\n <h1>使用说明</h1>\n <h2>GitHub - <a href="${k.a}">LussacZheng/dandanplay-resource-service</a></h2>\n</body>\n</html>\n`;const j=e=>t=>t.method.toLowerCase()===e.toLowerCase(),L=j("connect"),C=j("delete"),$=j("get"),E=j("head"),A=j("options"),D=j("patch"),z=j("post"),F=j("put"),H=j("trace"),J=e=>t=>{const n=new URL(encodeURI(t.url)).pathname;return(n.match(e)||[])[0]===n};var W=class{constructor(){this.routes=[]}handle(e,t){return this.routes.push({conditions:e,handler:t}),this}connect(e,t){return this.handle([L,J(e)],t)}delete(e,t){return this.handle([C,J(e)],t)}get(e,t){return this.handle([$,J(e)],t)}head(e,t){return this.handle([E,J(e)],t)}options(e,t){return this.handle([A,J(e)],t)}patch(e,t){return this.handle([D,J(e)],t)}post(e,t){return this.handle([z,J(e)],t)}put(e,t){return this.handle([F,J(e)],t)}trace(e,t){return this.handle([H,J(e)],t)}all(e){return this.handle([],e)}route(e){const t=this.resolve(e);return t?t.handler(e):new Response("resource not found",{status:404,statusText:"not found",headers:{"content-type":"text/plain"}})}resolve(e){return this.routes.find(t=>!(t.conditions&&(!Array.isArray(t)||t.conditions.length))||("function"==typeof t.conditions?t.conditions(e):t.conditions.every(t=>t(e))))}};async function Z(e){const t=new W;t.get("/subgroup",async()=>{const e=await async function(){return{Subgroups:N(await d(h.type_and_subgroup_url))}}();return new Response(JSON.stringify(e),u)}),t.get("/type",async()=>{const e=await async function(){return{Types:P(await d(h.type_and_subgroup_url))}}();return new Response(JSON.stringify(e),u)}),t.get("/list",async e=>{const t=await T(e);return new Response(JSON.stringify(t),u)}),t.get("/",async()=>new Response(await async function(){let e;try{e=await d("https://cdn.jsdelivr.net/gh/LussacZheng/dandanplay-resource-service@dist/web/index.html"),e=o(e,{VERSION:k.b})}catch(t){e=M}return e}(),l));return await t.route(e)}addEventListener("fetch",e=>e.respondWith(Z(e.request)))}]); (其实你回复时不需要整段引用,直接评论回复,或只引用关键语句就行。这样可以减少无效信息。) |
v0.0.4-beta
获取如果你感兴趣的话,可以试用并测试一下。有任何 Bug 或不合理的地方欢迎指出。 |
感谢你对脚本的改进。 因为我只用到realtime 这个指令,所以测试beta版本了下是可以用的,建议加入简繁转换,可以更方便搜索出baha的三俗片源 |
理由cf-worker 版本暂时无法支持的原因如 文档 中所述:
为 Node.js 编写的简繁转换库有很多,但直接引用过来会导致打包出的
建议我的建议是:对于 cf-worker 版本,用户可以分析目标资源的标题,从中提取出多个具有标识性的 “英文单词” 、“罗马音单词” 、“简繁体同形的字” 来作为关键词,并搭配组合,以规避这一问题。 以你所提到的《女神宿舍的管理员》为例,该番剧可能出现的名称有:
因此不妨将 需求如果你确实需要 cf-worker 版本支持简繁体转换,这里有一个我使用 chinese-conv 库完成简繁转换并打包成的临时版本:
如你所见,由于内嵌了简繁体字符的转换字典,其代码长度急剧增加,因此我无法保证其稳定性。你可以尝试使用一段时间看看。 |
通常文件在dmhy发布的两个小时后才能通过dandanplay搜索到资源。以我们的重制人生为例,资源发布在dmhy时间为晚8:30左右,自动下载和在弹弹play里的搜索相关文件会延迟到凌晨1点左右统一发布,不知道是不是BUG。
The text was updated successfully, but these errors were encountered: