Skip to content

Commit b2589ef

Browse files
author
Taois
committed
feat: 全新版本,大堆特性,性能优化,稳定性增强。
1 parent ead48fe commit b2589ef

File tree

113 files changed

+1403
-98
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+1403
-98
lines changed

controllers/config.js

Lines changed: 82 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import '../libs_drpy/jinja.js'
66
import {naturalSort, urljoin, updateQueryString} from '../utils/utils.js'
77
import {md5} from "../libs_drpy/crypto-util.js";
88
import {ENV} from "../utils/env.js";
9+
import FileHeaderManager from "../utils/fileHeaderManager.js";
910
import {extractNameFromCode} from "../utils/python.js";
1011
import {validateBasicAuth, validatePwd} from "../utils/api_validate.js";
1112
import {getSitesMap} from "../utils/sites-map.js";
@@ -81,12 +82,14 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
8182

8283
let link_jar = '';
8384
let enableRuleName = ENV.get('enable_rule_name', '0') === '1';
85+
let isLoaded = await drpy.isLoaded();
8486
// console.log('hide_adult:', ENV.get('hide_adult'));
8587
if (ENV.get('hide_adult') === '1') {
8688
valid_files = valid_files.filter(it => !(new RegExp('\\[[密]\\]|密+')).test(it));
8789
}
8890
let SitesMap = getSitesMap(configDir);
8991
// console.log(SitesMap);
92+
log(`开始生成ds的t4配置,jsDir:${jsDir},源数量: ${valid_files.length}`);
9093
const tasks = valid_files.map((file) => {
9194
return {
9295
func: async ({file, jsDir, requestHost, pwd, drpy, SitesMap, jsEncoder}) => {
@@ -100,17 +103,37 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
100103
filterable: 0, // 固定值
101104
quickSearch: 0, // 固定值
102105
};
103-
try {
104-
ruleObject = await drpy.getRuleObject(path.join(jsDir, file));
105-
} catch (e) {
106-
throw new Error(`Error parsing rule object for file: ${file}, ${e.message}`);
106+
let ruleMeta = {...ruleObject};
107+
// if (baseName.includes('抖音直播弹幕')) {
108+
const filePath = path.join(jsDir, file);
109+
const header = await FileHeaderManager.readHeader(filePath);
110+
// console.log('ds header:', header);
111+
if (!header) {
112+
try {
113+
ruleObject = await drpy.getRuleObject(filePath);
114+
} catch (e) {
115+
throw new Error(`Error parsing rule object for file: ${file}, ${e.message}`);
116+
}
117+
Object.assign(ruleMeta, {
118+
title: ruleObject.title,
119+
searchable: ruleObject.searchable,
120+
filterable: ruleObject.filterable,
121+
quickSearch: ruleObject.quickSearch,
122+
more: ruleObject.more,
123+
logo: ruleObject.logo,
124+
});
125+
// console.log('ds ruleMeta:', ruleMeta);
126+
await FileHeaderManager.writeHeader(filePath, ruleMeta);
127+
} else if (!isLoaded) {
128+
const sizeInBytes = await FileHeaderManager.getFileSize(filePath, {humanReadable: true});
129+
console.log(`Loading RuleObject: ${filePath} fileSize:${sizeInBytes}`);
107130
}
108-
ruleObject.title = enableRuleName ? ruleObject.title || baseName : baseName;
131+
ruleMeta.title = enableRuleName ? ruleMeta.title || baseName : baseName;
109132

110133
let fileSites = [];
111134
if (baseName === 'push_agent') {
112135
let key = 'push_agent';
113-
let name = `${ruleObject.title}(DS)`;
136+
let name = `${ruleMeta.title}(DS)`;
114137
fileSites.push({key, name});
115138
} else if (SitesMap.hasOwnProperty(baseName) && Array.isArray(SitesMap[baseName])) {
116139
SitesMap[baseName].forEach((it) => {
@@ -123,8 +146,8 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
123146
fileSites.push({key, name, ext});
124147
});
125148
} else {
126-
let key = `drpyS_${ruleObject.title}`;
127-
let name = `${ruleObject.title}(DS)`;
149+
let key = `drpyS_${ruleMeta.title}`;
150+
let name = `${ruleMeta.title}(DS)`;
128151
fileSites.push({key, name});
129152
}
130153

@@ -134,11 +157,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
134157
name: fileSite.name,
135158
type: 4, // 固定值
136159
api,
137-
searchable: ruleObject.searchable,
138-
filterable: ruleObject.filterable,
139-
quickSearch: ruleObject.quickSearch,
140-
more: ruleObject.more,
141-
logo: ruleObject.logo,
160+
...ruleMeta,
142161
ext: fileSite.ext || "", // 固定为空字符串
143162
};
144163
sites.push(site);
@@ -183,18 +202,36 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
183202
filterable: 0, // 固定值
184203
quickSearch: 0, // 固定值
185204
};
186-
try {
187-
// console.log('file:', path.join(dr2Dir, file));
188-
ruleObject = await drpy.getRuleObject(path.join(dr2Dir, file));
189-
} catch (e) {
190-
throw new Error(`Error parsing rule object for file: ${file}, ${e.message}`);
205+
let ruleMeta = {...ruleObject};
206+
const filePath = path.join(dr2Dir, file);
207+
const header = await FileHeaderManager.readHeader(filePath);
208+
// console.log('dr2 header:', header);
209+
if (!header) {
210+
try {
211+
ruleObject = await drpy.getRuleObject(path.join(filePath));
212+
} catch (e) {
213+
throw new Error(`Error parsing rule object for file: ${file}, ${e.message}`);
214+
}
215+
Object.assign(ruleMeta, {
216+
title: ruleObject.title,
217+
searchable: ruleObject.searchable,
218+
filterable: ruleObject.filterable,
219+
quickSearch: ruleObject.quickSearch,
220+
more: ruleObject.more,
221+
logo: ruleObject.logo,
222+
});
223+
// console.log('dr2 ruleMeta:', ruleMeta);
224+
await FileHeaderManager.writeHeader(filePath, ruleMeta);
225+
} else if (!isLoaded) {
226+
const sizeInBytes = await FileHeaderManager.getFileSize(filePath, {humanReadable: true});
227+
console.log(`Loading RuleObject: ${filePath} fileSize:${sizeInBytes}`);
191228
}
192-
ruleObject.title = enableRuleName ? ruleObject.title || baseName : baseName;
229+
ruleMeta.title = enableRuleName ? ruleMeta.title || baseName : baseName;
193230

194231
let fileSites = [];
195232
if (baseName === 'push_agent') {
196233
let key = 'push_agent';
197-
let name = `${ruleObject.title}(DR2)`;
234+
let name = `${ruleMeta.title}(DR2)`;
198235
fileSites.push({key, name, ext});
199236
} else if (SitesMap.hasOwnProperty(baseName) && Array.isArray(SitesMap[baseName])) {
200237
SitesMap[baseName].forEach((it) => {
@@ -204,8 +241,8 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
204241
fileSites.push({key, name, ext: _ext});
205242
});
206243
} else {
207-
let key = `drpy2_${ruleObject.title}`;
208-
let name = `${ruleObject.title}(DR2)`;
244+
let key = `drpy2_${ruleMeta.title}`;
245+
let name = `${ruleMeta.title}(DR2)`;
209246
fileSites.push({key, name, ext});
210247
}
211248

@@ -215,11 +252,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
215252
name: fileSite.name,
216253
type: 3, // 固定值
217254
api,
218-
searchable: ruleObject.searchable,
219-
filterable: ruleObject.filterable,
220-
quickSearch: ruleObject.quickSearch,
221-
more: ruleObject.more,
222-
logo: ruleObject.logo,
255+
...ruleMeta,
223256
ext: fileSite.ext || "", // 固定为空字符串
224257
};
225258
sites.push(site);
@@ -259,24 +292,39 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
259292
filterable: 1, // 固定值
260293
quickSearch: 1, // 固定值
261294
};
262-
const fileContent = await readFile(path.join(pyDir, file), 'utf-8');
263-
ruleObject.title = enableRuleName ? extractNameFromCode(fileContent) || baseName : baseName;
295+
let ruleMeta = {...ruleObject};
296+
const filePath = path.join(pyDir, file);
297+
const header = await FileHeaderManager.readHeader(filePath);
298+
// console.log('py header:', header);
299+
if (!header) {
300+
const fileContent = await readFile(filePath, 'utf-8');
301+
const title = extractNameFromCode(fileContent) || baseName;
302+
Object.assign(ruleMeta, {
303+
title: title,
304+
});
305+
// console.log('py ruleMeta:', ruleMeta);
306+
await FileHeaderManager.writeHeader(filePath, ruleMeta);
307+
} else if (!isLoaded) {
308+
const sizeInBytes = await FileHeaderManager.getFileSize(filePath, {humanReadable: true});
309+
console.log(`Loading RuleObject: ${filePath} fileSize:${sizeInBytes}`);
310+
}
311+
ruleMeta.title = enableRuleName ? ruleMeta.title || baseName : baseName;
264312

265313
let fileSites = [];
266314
if (baseName === 'push_agent') {
267315
let key = 'push_agent';
268-
let name = `${ruleObject.title}(hipy_t3)`;
316+
let name = `${ruleMeta.title}(hipy)`;
269317
fileSites.push({key, name, ext});
270318
} else if (SitesMap.hasOwnProperty(baseName) && Array.isArray(SitesMap[baseName])) {
271319
SitesMap[baseName].forEach((it) => {
272320
let key = `hipy_py_${it.alias}`;
273-
let name = `${it.alias}(hipy_t3)`;
321+
let name = `${it.alias}(hipy)`;
274322
let _ext = updateQueryString(ext, it.queryStr);
275323
fileSites.push({key, name, ext: _ext});
276324
});
277325
} else {
278-
let key = `hipy_py_${ruleObject.title}`;
279-
let name = `${ruleObject.title}(hipy_t3)`;
326+
let key = `hipy_py_${ruleMeta.title}`;
327+
let name = `${ruleMeta.title}(hipy)`;
280328
fileSites.push({key, name, ext});
281329
}
282330

@@ -286,11 +334,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
286334
name: fileSite.name,
287335
type: 3, // 固定值
288336
api,
289-
searchable: ruleObject.searchable,
290-
filterable: ruleObject.filterable,
291-
quickSearch: ruleObject.quickSearch,
292-
more: ruleObject.more,
293-
logo: ruleObject.logo,
337+
...ruleMeta,
294338
ext: fileSite.ext || "", // 固定为空字符串
295339
};
296340
sites.push(site);

controllers/decoder.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default (fastify, options, done) => {
4949
}
5050

5151
try {
52-
let result = getOriginalJs(code);
52+
let result = await getOriginalJs(code);
5353
reply.send({success: true, result});
5454
} catch (error) {
5555
reply.status(500).send({error: error.message});

docs/updateRecord.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
4. 首页配置接口链接增加动态密码注入,设置密码的场景不需要手动改?pwd=
1111
5. 配置文件生成的名称提供了选项,默认改回按文件名(可选按源里设置的名称)
1212
6. 通过全局监听器解决了由于部分源 如 `番薯动漫` 内的异步错误导致的进程崩溃问题
13+
7. 所有源增加文件头,用于后续加载过程快速生成配置,首次加载配置提速:`6500ms -> 120ms`
14+
8. 修改对应的加解密函数支持带文件头的源解密
15+
9. `getOriginalJs` 修改为异步函数
1316

1417
### 20250726
1518

index.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ import os from 'os';
55
import qs from 'qs';
66
import {fileURLToPath} from 'url';
77
import formBody from '@fastify/formbody';
8-
import {validateBasicAuth, validatePwd} from "./utils/api_validate.js";
8+
import {validateBasicAuth, validateJs, validatePwd} from "./utils/api_validate.js";
9+
// 注册控制器
10+
import {registerRoutes} from './controllers/index.js';
911

1012
const {fastify} = fastlogger;
1113

1214
// 获取当前路径
1315
const __dirname = path.dirname(fileURLToPath(import.meta.url));
1416
const PORT = 5757;
1517
const MAX_TEXT_SIZE = 0.1 * 1024 * 1024; // 设置最大文本大小为 0.1 MB
18+
const jsonDir = path.join(__dirname, 'json');
19+
const jsDir = path.join(__dirname, 'spider/js');
20+
const dr2Dir = path.join(__dirname, 'spider/js_dr2');
21+
const pyDir = path.join(__dirname, 'spider/py');
1622

1723
// 静态资源
1824
fastify.register(fastifyStatic, {
@@ -27,19 +33,22 @@ fastify.register(fastifyStatic, {
2733
});
2834

2935
fastify.register(fastifyStatic, {
30-
root: path.join(__dirname, 'json'),
36+
root: jsonDir,
3137
prefix: '/json/', // 新的访问路径前缀
3238
decorateReply: false, // 禁用 sendFile
3339
});
3440

3541
fastify.register(fastifyStatic, {
36-
root: path.join(__dirname, 'spider/js_dr2'),
42+
root: dr2Dir,
3743
prefix: '/js/', // 新的访问路径前缀
3844
decorateReply: false, // 禁用 sendFile
45+
// setHeaders: (res, path) => {
46+
// res.setHeader('Cache-Control', 'no-store'); // 禁用缓存确保每次获取最新
47+
// }
3948
});
4049

4150
fastify.register(fastifyStatic, {
42-
root: path.join(__dirname, 'spider/py'),
51+
root: pyDir,
4352
prefix: '/py/', // 新的访问路径前缀
4453
decorateReply: false, // 禁用 sendFile
4554
setHeaders: (res, path) => {
@@ -58,40 +67,39 @@ fastify.addHook('preHandler', (req, reply, done) => {
5867
if (req.raw.url.startsWith('/apps/')) {
5968
validateBasicAuth(req, reply, done);
6069
} else if (req.raw.url.startsWith('/js/') || req.raw.url.startsWith('/py/')) {
61-
validatePwd(req, reply, done).then(r => done());
70+
validatePwd(req, reply, done).then(async () => {
71+
validateJs(req, reply, dr2Dir).then(() => done());
72+
});
6273
} else {
6374
done();
6475
}
6576
});
6677

6778
// 自定义插件替换 querystring 解析行为.避免出现两个相同参数被解析成列表
68-
fastify.addHook('onRequest', async (request, reply) => {
79+
fastify.addHook('onRequest', async (req, reply) => {
6980
// 获取原始 URL 中的 query 部分
70-
const rawUrl = request.raw.url;
81+
const rawUrl = req.raw.url;
7182
const urlParts = rawUrl.split('?');
72-
const path = urlParts[0];
83+
const urlPath = urlParts[0];
7384
let rawQuery = urlParts.slice(1).join('?'); // 处理可能存在的多个 '?' 情况
7485
// log('rawQuery:', rawQuery);
7586
// 使用 qs 库解析 query 参数,确保兼容参数值中包含 '?' 的情况
76-
request.query = qs.parse(rawQuery, {
87+
req.query = qs.parse(rawQuery, {
7788
strictNullHandling: true, // 确保 `=` 被解析为空字符串
7889
arrayLimit: 100, // 自定义数组限制
7990
allowDots: false, // 禁止点号表示嵌套对象
8091
});
81-
// 如果需要,可以在这里对 request.query 进行进一步处理
92+
// 如果需要,可以在这里对 req.query 进行进一步处理
8293
});
8394

84-
// 注册控制器
85-
import {registerRoutes} from './controllers/index.js';
86-
8795
registerRoutes(fastify, {
8896
rootDir: __dirname,
8997
docsDir: path.join(__dirname, 'docs'),
9098
jxDir: path.join(__dirname, 'jx'),
91-
jsonDir: path.join(__dirname, 'json'),
92-
jsDir: path.join(__dirname, 'spider/js'),
93-
dr2Dir: path.join(__dirname, 'spider/js_dr2'),
94-
pyDir: path.join(__dirname, 'spider/py'),
99+
jsonDir: jsonDir,
100+
jsDir: jsDir,
101+
dr2Dir: dr2Dir,
102+
pyDir: pyDir,
95103
viewsDir: path.join(__dirname, 'views'),
96104
configDir: path.join(__dirname, 'config'),
97105
PORT,

0 commit comments

Comments
 (0)