Skip to content

Commit 18e4162

Browse files
author
Taois
committed
feat: 更新版本,cat源完美支持本地代理功能。优化其他细节
1 parent 5882f70 commit 18e4162

File tree

16 files changed

+127
-71
lines changed

16 files changed

+127
-71
lines changed

README.md

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# drpyS(drpy-node)
22

33
nodejs作为服务端的drpy实现。全面升级异步写法
4-
~~积极开发中,每日一更~~,当前进度 `70%`
4+
~~积极开发中,每日一更~~,当前进度 `71%`
55
~~找工作中,随缘更新~~
66
上班当牛马,下班要带娃,阶段性佛系趁娃睡觉熬夜更新
77

8-
* [接口文档](docs/apidoc.md) | [小猫影视-待对接T4](https://github.com/waifu-project/movie/pull/135)
8+
* [接口文档](docs/apidoc.md) | [接口列表如定时任务](docs/apiList.md) | [小猫影视-待对接T4](https://github.com/waifu-project/movie/pull/135)
99
* [本地配置接口-动态本地](/config?pwd=$pwd)
1010
* [本地配置接口-动态外网/局域网](/config/1?pwd=$pwd)
1111
* [其他配置接口-订阅过滤](/docs/sub.md)
@@ -23,25 +23,13 @@ nodejs作为服务端的drpy实现。全面升级异步写法
2323

2424
## 更新记录
2525

26-
### 20250812
27-
28-
更新至V1.2.9
29-
30-
### 20250810
31-
32-
更新至V1.2.8
26+
### 20250813
3327

34-
### 20250808
28+
更新至V1.2.10
3529

36-
更新至V1.2.7
37-
38-
### 20250805
39-
40-
更新至V1.2.6
41-
42-
### 20250804
30+
### 20250812
4331

44-
更新至V1.2.5
32+
更新至V1.2.9
4533

4634
[点此查看完整更新记录](docs/updateRecord.md)
4735

controllers/api.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default (fastify, options, done) => {
5757

5858
// console.log(`proxyUrl:${proxyUrl}`);
5959
function getEnv(moduleName) {
60-
const proxyUrl = `${protocol}://${hostname}/proxy/${moduleName}/?do=js`;
60+
const proxyUrl = `${protocol}://${hostname}/proxy/${moduleName}/?do=${query.do||'ds'}`;
6161
const getProxyUrl = function () {
6262
return proxyUrl
6363
};
@@ -206,8 +206,9 @@ export default (fastify, options, done) => {
206206
fastify.get('/proxy/:module/*', async (request, reply) => {
207207
const moduleName = request.params.module;
208208
const query = request.query; // 获取 query 参数
209-
209+
// console.log(query);
210210
let {apiEngine, modulePath} = getApiEngine(ENGINES, moduleName, query, options);
211+
// console.log(modulePath);
211212
if (!existsSync(modulePath)) {
212213
reply.status(404).send({error: `Module ${moduleName} not found`});
213214
return;
@@ -228,7 +229,7 @@ export default (fastify, options, done) => {
228229
const fServer = fastify.server;
229230

230231
function getEnv(moduleName) {
231-
const proxyUrl = `${protocol}://${hostname}/proxy/${moduleName}/?do=js`;
232+
const proxyUrl = `${protocol}://${hostname}/proxy/${moduleName}/?do=${query.do||'ds'}`;
232233
const getProxyUrl = function () {
233234
return proxyUrl
234235
};

controllers/config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,9 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
287287
};
288288
// 添加isdr2参数到API URL
289289
if (pwd) {
290-
t4site.api += `?pwd=${pwd}&adapt=dr`;
290+
t4site.api += `?pwd=${pwd}&do=dr`;
291291
} else {
292-
t4site.api += `?adapt=dr`;
292+
t4site.api += `?do=dr`;
293293
}
294294

295295
// 处理传参源的API参数
@@ -411,7 +411,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
411411
func: async ({file, catDir, requestHost, pwd, SitesMap}) => {
412412
const baseName = path.basename(file, '.js'); // 去掉文件扩展名
413413
const extJson = path.join(catDir, baseName + '.json');
414-
let api = enable_cat === '1' ? `${requestHost}/cat/${file}` : `${requestHost}/api/${baseName}?adapt=cat`; // 使用请求的 host 地址,避免硬编码端口
414+
let api = enable_cat === '1' ? `${requestHost}/cat/${file}` : `${requestHost}/api/${baseName}?do=cat`; // 使用请求的 host 地址,避免硬编码端口
415415
let ext = existsSync(extJson) ? `${requestHost}/cat/${file}` : '';
416416

417417
if (pwd) {

controllers/cron-tasker.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {readdir, stat} from 'fs/promises';
44
import {pathToFileURL} from 'url';
55
import {CronJob} from 'cron';
66
import {validateBasicAuth} from "../utils/api_validate.js"; // 官方 cron
7+
import {toBeijingTime} from "../utils/datetime-format.js"
78

89
const scripts_exclude = ['moontv.mjs', 'kzz.mjs'];
910
const enable_tasker = Number(process.env.ENABLE_TASKER) || 0;
@@ -226,8 +227,8 @@ export default (fastify, options, done) => {
226227
name: task.name,
227228
schedule: task.schedule,
228229
status: task.status,
229-
lastRun: task.lastRun,
230-
nextRun: task.nextRun,
230+
lastRun: toBeijingTime(task.lastRun),
231+
nextRun: toBeijingTime(task.nextRun),
231232
path: task.path
232233
}));
233234

@@ -249,8 +250,8 @@ export default (fastify, options, done) => {
249250
name: task.name,
250251
schedule: task.schedule,
251252
status: task.status,
252-
lastRun: task.lastRun,
253-
nextRun: task.nextRun,
253+
lastRun: toBeijingTime(task.lastRun),
254+
nextRun: toBeijingTime(task.nextRun),
254255
path: task.path
255256
};
256257
});

controllers/docs.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import path from 'path';
22
import {existsSync, readFileSync} from 'fs';
33
import {getMimeType} from '../utils/mime-type.js';
44
import '../utils/marked.min.js';
5+
import {validateBasicAuth} from "../utils/api_validate.js";
56

67
export default (fastify, options, done) => {
7-
fastify.get('/docs/*', async (request, reply) => {
8+
fastify.get('/docs/*', {preHandler: validateBasicAuth}, async (request, reply) => {
89
const fullPath = request.params['*']; // 捕获整个路径
910
console.log(`Request received for path: ${fullPath}`);
1011
try {
@@ -29,7 +30,7 @@ export default (fastify, options, done) => {
2930
if (ext === '.md') {
3031
// 处理 Markdown 文件
3132
const markdownContent = readFileSync(resolvedPath, 'utf8');
32-
const htmlContent = marked.parse(markdownContent);
33+
const htmlContent = marked.parse(markdownContent).replaceAll('$pwd', process.env.API_PWD || '');
3334

3435
reply.type('text/html').send(`
3536
<!DOCTYPE html>

docs/apiList.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## API列表(一部分,逐步完善)
2+
3+
- 获取定时任务列表 [/tasks](/tasks)
4+
- 立即执行全部任务 [/execute-now/:taskName](/execute-now/)
5+
- 立即执行钉钉消息任务 [/execute-now/dingtalk_test](/execute-now/dingtalk_test)
6+
- 立即执行企业微信消息任务 [/execute-now/wechat_test](/execute-now/wechat_test)
7+
- 获取指定任务信息 [/tasks/:taskName](/tasks/)

docs/apidoc.md

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
| pg | number | 页码,默认 1 |
5050
| ext | string | Base64 编码的 JSON 筛选参数 |
5151
| extend | string | 扩展参数(直接字符串,根据/config路由对应sites的ext属性传递) |
52-
| adapt | string | 自定义源适配器,默认ds,可不传 |
52+
| do | string | 自定义源适配器,默认ds,可不传 |
5353

5454
#### 功能分支
5555

@@ -192,12 +192,3 @@
192192
3. `ext` 参数必须是 **Base64 编码的 JSON 字符串**,否则会报“筛选参数错误”。
193193
4. 流媒体内容可能会通过 `/mediaProxy` 重定向处理。
194194
5. 建议在请求时加上 `pg` 参数避免默认第一页。
195-
196-
## 服务特殊显式接口说明
197-
198-
- 获取定时任务列表 [/tasks](/tasks)
199-
- 立即执行全部任务 [/execute-now/:taskName](/execute-now/)
200-
- 立即执行钉钉消息任务 [/execute-now/dingtalk_test](/execute-now/dingtalk_test)
201-
- 立即执行企业微信消息任务 [/execute-now/wechat_test](/execute-now/wechat_test)
202-
- 获取指定任务信息 [/tasks/:taskName](/tasks/)
203-

docs/sub.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
* [本地配置接口-静态](/index?pwd=)
2-
* [远程订阅接口-全部](/config/1?sub=all&pwd=)
3-
* [远程订阅接口-绿色](/config/1?sub=green&pwd=)
4-
* [电视订阅接口-仅多媒体源](/config/1?sub=tv&pwd=)
5-
* [电视订阅接口-仅网盘](/config/1?sub=pan&pwd=)
1+
# 内置订阅地址
2+
3+
* [本地配置接口-静态](/index?pwd=$pwd)
4+
* [远程订阅接口-全部](/config/1?sub=all&pwd=$pwd)
5+
* [远程订阅接口-绿色](/config/1?sub=green&pwd=$pwd)
6+
* [电视订阅接口-仅多媒体源](/config/1?sub=tv&pwd=$pwd)
7+
* [电视订阅接口-仅网盘](/config/1?sub=pan&pwd=$pwd)
8+
9+
# 其他工具链接
10+
611
* [道长专用git代理](https://gh-proxy.playdreamer.cn/)

docs/updateRecord.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# drpyS更新记录
22

3+
### 20250813
4+
5+
更新至V1.2.10
6+
7+
1. 调整首页的文档超链接,定时任务从接口文档里抽出来,订阅过滤内的自动带pwd。文档 /docs 路由增加basic验证防止被盗用接口
8+
2. 定时任务 /tasks路由返回信息的lastrun和nextrun显示优化,从UTC时间改成北京时间
9+
3. 尝试支持cat源的本地代理功能,增加`getProxyUrl` 函数,T4增加 `ENV` 对象
10+
4. 去除 `adapt` 属性 改为 `do` 属性
11+
312
### 20250812
413

514
更新至V1.2.9

libs/catvod.js

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from "path";
22
import {readFile} from "fs/promises";
33
import {getSitesMap} from "../utils/sites-map.js";
4-
import {computeHash, getNowTime, deepCopy} from "../utils/utils.js";
4+
import {computeHash, deepCopy, getNowTime} from "../utils/utils.js";
55
import {fileURLToPath, pathToFileURL} from 'url';
66
import {md5} from "../libs_drpy/crypto-util.js";
77

@@ -14,11 +14,6 @@ const _config_path = path.join(__dirname, '../config');
1414
const _lib_path = path.join(__dirname, '../spider/catvod');
1515

1616

17-
const getRule = async function (filePath, env) {
18-
const moduleObject = await init(filePath, env);
19-
return JSON.stringify(moduleObject);
20-
}
21-
2217
const json2Object = function (json) {
2318
if (!json) {
2419
return {}
@@ -28,6 +23,38 @@ const json2Object = function (json) {
2823
return JSON.parse(json);
2924
}
3025

26+
const loadEsmWithHash = async function (filePath, fileHash) {
27+
const scriptUrl = `${pathToFileURL(filePath).href}?v=${fileHash}`;
28+
return await import(scriptUrl);
29+
}
30+
31+
const loadEsmWithEnv = async function (filePath, env) {
32+
const rawCode = await readFile(filePath, 'utf8');
33+
let injectedCode = rawCode;
34+
const esm_flag1 = 'export function __jsEvalReturn';
35+
const esm_flag2 = 'export default';
36+
const polyfill_code = 'var ENV={};\nvar getProxyUrl=null;\nexport const initEnv = (env)=>{ENV = env;if(env.getProxyUrl){getProxyUrl=env.getProxyUrl}};\n';
37+
if (rawCode.includes(esm_flag1)) {
38+
injectedCode = rawCode.replace(esm_flag1, `${polyfill_code}${esm_flag1}`)
39+
} else if (rawCode.includes('export default')) {
40+
injectedCode = rawCode.replace(esm_flag2, `${polyfill_code}${esm_flag2}`)
41+
}
42+
// console.log(injectedCode);
43+
// // 创建数据URI模块
44+
const dataUri = `data:text/javascript;base64,${Buffer.from(injectedCode).toString('base64')}`;
45+
const module = await import(dataUri);
46+
const initEnv = module.initEnv;
47+
if (typeof initEnv === 'function' && env) {
48+
initEnv(env);
49+
}
50+
return module
51+
}
52+
53+
const getRule = async function (filePath, env) {
54+
const moduleObject = await init(filePath, env);
55+
return JSON.stringify(moduleObject);
56+
}
57+
3158
const init = async function (filePath, env = {}, refresh) {
3259
try {
3360
const fileContent = await readFile(filePath, 'utf-8');
@@ -48,29 +75,30 @@ const init = async function (filePath, env = {}, refresh) {
4875
let hashMd5 = md5(filePath + '#pAq#' + moduleExt);
4976
if (moduleCache.has(hashMd5) && !refresh) {
5077
const cached = moduleCache.get(hashMd5);
51-
if (cached.hash === fileHash) {
78+
// 除hash外还必须保证proxyUrl实时相等,避免本地代理url的尴尬情况
79+
if (cached.hash === fileHash && cached.proxyUrl === env.proxyUrl) {
5280
return cached.moduleObject;
5381
}
5482
}
5583
log(`Loading module: ${filePath}`);
5684
let t1 = getNowTime();
57-
// const scriptUrl = pathToFileURL(filePath).href;
58-
const scriptUrl = `${pathToFileURL(filePath).href}?v=${fileHash}`;
59-
// console.log(scriptUrl);
60-
const module = await import(scriptUrl);
85+
const module = await loadEsmWithEnv(filePath, env);
86+
// console.log('module:', module);
6187
let rule;
6288
if (module && module.__jsEvalReturn && typeof module.__jsEvalReturn === 'function') {
6389
rule = module.__jsEvalReturn();
6490
} else {
6591
rule = module.default || module;
6692
}
67-
// console.log(rule);
93+
// console.log('rule:', rule);
94+
// console.log('globalThis.ENV:', globalThis.ENV);
95+
// console.log('globalThis.getProxyUrl:', globalThis.getProxyUrl);
6896
// 加载 init
6997
await rule.init(moduleExt || {});
7098
let t2 = getNowTime();
7199
const moduleObject = deepCopy(rule);
72100
moduleObject.cost = t2 - t1;
73-
moduleCache.set(hashMd5, {moduleObject, hash: fileHash});
101+
moduleCache.set(hashMd5, {moduleObject, hash: fileHash, proxyUrl: env.proxyUrl});
74102
return moduleObject;
75103
} catch (error) {
76104
console.log(`Error in catvod.init :${filePath}`, error);

0 commit comments

Comments
 (0)