Skip to content

Commit 29a03ae

Browse files
author
Taois
committed
feat: 功能优化
1. 文件头增加 lang 属性,方便区分加密情况下这个源是哪张类型,`ds` `dr2` `hipy` 2. 修复日志输出到文件在轮转时乱创文件夹问题 3. drpyS 增加 `buildQueryString` 函数
1 parent fa6a5f0 commit 29a03ae

File tree

114 files changed

+382
-148
lines changed

Some content is hidden

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

114 files changed

+382
-148
lines changed

.env.development

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ ENV='staging'
66

77

88
LOG_WITH_FILE = 1
9+
FORCE_HEADER = 0
910
# trace/debug/info/warn/error/fatal
1011
LOG_LEVEL = info
1112
COOKIE_AUTH_CODE = drpys

README.md

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

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

78
* [本地配置接口-动态本地](/config?pwd=$pwd)
89
* [本地配置接口-动态外网/局域网](/config/1?pwd=$pwd)
@@ -19,6 +20,10 @@ nodejs作为服务端的drpy实现。全面升级异步写法
1920

2021
## 更新记录
2122

23+
### 20250728
24+
25+
更新至V1.2.2
26+
2227
### 20250727
2328

2429
更新至V1.2.1

controllers/config.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
8383
let link_jar = '';
8484
let enableRuleName = ENV.get('enable_rule_name', '0') === '1';
8585
let isLoaded = await drpy.isLoaded();
86+
let forceHeader = Number(process.env.FORCE_HEADER) || 0;
8687
// console.log('hide_adult:', ENV.get('hide_adult'));
8788
if (ENV.get('hide_adult') === '1') {
8889
valid_files = valid_files.filter(it => !(new RegExp('\\[[密]\\]|密+')).test(it));
@@ -108,7 +109,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
108109
const filePath = path.join(jsDir, file);
109110
const header = await FileHeaderManager.readHeader(filePath);
110111
// console.log('ds header:', header);
111-
if (!header) {
112+
if (!header || forceHeader) {
112113
try {
113114
ruleObject = await drpy.getRuleObject(filePath);
114115
} catch (e) {
@@ -121,6 +122,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
121122
quickSearch: ruleObject.quickSearch,
122123
more: ruleObject.more,
123124
logo: ruleObject.logo,
125+
lang: 'ds',
124126
});
125127
// console.log('ds ruleMeta:', ruleMeta);
126128
await FileHeaderManager.writeHeader(filePath, ruleMeta);
@@ -209,7 +211,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
209211
const filePath = path.join(dr2Dir, file);
210212
const header = await FileHeaderManager.readHeader(filePath);
211213
// console.log('dr2 header:', header);
212-
if (!header) {
214+
if (!header || forceHeader) {
213215
try {
214216
ruleObject = await drpy.getRuleObject(path.join(filePath));
215217
} catch (e) {
@@ -222,6 +224,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
222224
quickSearch: ruleObject.quickSearch,
223225
more: ruleObject.more,
224226
logo: ruleObject.logo,
227+
lang: 'dr2',
225228
});
226229
// console.log('dr2 ruleMeta:', ruleMeta);
227230
await FileHeaderManager.writeHeader(filePath, ruleMeta);
@@ -302,11 +305,12 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
302305
const filePath = path.join(pyDir, file);
303306
const header = await FileHeaderManager.readHeader(filePath);
304307
// console.log('py header:', header);
305-
if (!header) {
308+
if (!header || forceHeader) {
306309
const fileContent = await readFile(filePath, 'utf-8');
307310
const title = extractNameFromCode(fileContent) || baseName;
308311
Object.assign(ruleMeta, {
309312
title: title,
313+
lang: 'hipy',
310314
});
311315
// console.log('py ruleMeta:', ruleMeta);
312316
await FileHeaderManager.writeHeader(filePath, ruleMeta);

controllers/fastlogger.js

Lines changed: 114 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,84 @@ import {fileURLToPath} from 'url';
66
import {createStream} from 'rotating-file-stream';
77
import dotenv from 'dotenv';
88

9-
dotenv.config(); //加载 .env 文件
9+
dotenv.config();
1010

11-
const LOG_WITH_FILE = process.env.LOG_WITH_FILE;
11+
const LOG_WITH_FILE = Number(process.env.LOG_WITH_FILE) || 0;
1212
const LOG_LEVEL = process.env.LOG_LEVEL && ['trace', 'debug', 'info', 'warn', 'error', 'fatal'].includes(process.env.LOG_LEVEL) ? process.env.LOG_LEVEL : 'info';
1313
const COOKIE_AUTH_CODE = process.env.COOKIE_AUTH_CODE || 'drpys';
1414
console.log('LOG_WITH_FILE:', LOG_WITH_FILE);
1515
console.log('LOG_LEVEL:', LOG_LEVEL);
1616
console.log('COOKIE_AUTH_CODE:', COOKIE_AUTH_CODE);
1717
let _logger = true;
18+
let logStream = null;
1819

19-
// 自定义时间戳函数,格式为 YYYY-MM-DD HH:mm:ss
20+
const __filename = fileURLToPath(import.meta.url);
21+
const __dirname = path.dirname(__filename);
22+
const logDirectory = path.join(__dirname, '../logs');
23+
24+
// 检测操作系统
25+
const isWindows = process.platform === 'win32';
26+
27+
// 自定义时间戳函数
2028
const customTimestamp = () => {
2129
const now = new Date();
22-
const yyyy = now.getFullYear();
23-
const mm = String(now.getMonth() + 1).padStart(2, '0');
24-
const dd = String(now.getDate()).padStart(2, '0');
25-
const hours = String(now.getHours()).padStart(2, '0');
26-
const minutes = String(now.getMinutes()).padStart(2, '0');
27-
const seconds = String(now.getSeconds()).padStart(2, '0');
28-
const formattedTime = `${yyyy}-${mm}-${dd} ${hours}:${minutes}:${seconds}`;
29-
return `,"time":"${formattedTime}"`; // 返回格式化后的时间戳
30+
return `,"time":"${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}"`;
31+
};
32+
33+
// 安全的文件路径生成函数
34+
const safeFileNameGenerator = (time, index) => {
35+
if (!time) return "output.log";
36+
37+
// 确保文件名中不包含路径分隔符
38+
const dateStr = `${time.getFullYear()}-${String(time.getMonth() + 1).padStart(2, '0')}-${String(time.getDate()).padStart(2, '0')}`;
39+
return `output-${dateStr}.log.${index || 1}`;
3040
};
3141

42+
3243
if (LOG_WITH_FILE) {
33-
const __filename = fileURLToPath(import.meta.url);
34-
const __dirname = path.dirname(__filename);
35-
const logDirectory = path.join(__dirname, '../logs');
3644
if (!fs.existsSync(logDirectory)) {
37-
fs.mkdirSync(logDirectory);
45+
fs.mkdirSync(logDirectory, {recursive: true});
3846
}
39-
const logStream = createStream(path.join(logDirectory, 'output.log'), {
40-
size: '500M', // 设置最大文件大小为 500MB
41-
compress: true, // 自动压缩旧的日志文件
42-
encoding: 'utf8', // 设置日志文件的编码为 utf8
43-
interval: '1d' // 每天轮转一次日志
47+
48+
// 配置选项
49+
const streamOptions = {
50+
size: '500M',
51+
// compress: isWindows ? false : 'gzip', // Windows 上禁用压缩
52+
compress: false,
53+
interval: '1d',
54+
path: logDirectory,
55+
maxFiles: 30
56+
};
57+
58+
59+
// 创建日志流
60+
logStream = createStream(safeFileNameGenerator, streamOptions);
61+
62+
// 添加错误处理
63+
logStream.on('error', (err) => {
64+
// console.error('日志流错误:', err);
65+
});
66+
67+
logStream.on('rotated', (filename) => {
68+
console.log('日志轮转完成:', filename);
4469
});
70+
4571
_logger = pino({
46-
level: LOG_LEVEL, // 设置记录的最低日志级别
72+
level: LOG_LEVEL,
4773
serializers: {
48-
req: pino.stdSerializers.req, // 标准请求序列化器
49-
res: pino.stdSerializers.res, // 标准响应序列化器
74+
req: pino.stdSerializers.req,
75+
res: pino.stdSerializers.res,
5076
},
5177
timestamp: customTimestamp,
5278
}, logStream);
79+
5380
console.log('日志输出到文件');
5481
} else {
5582
_logger = pino({
56-
level: LOG_LEVEL, // 设置记录的最低日志级别
83+
level: LOG_LEVEL,
5784
serializers: {
58-
req: pino.stdSerializers.req, // 标准请求序列化器
59-
res: pino.stdSerializers.res, // 标准响应序列化器
85+
req: pino.stdSerializers.req,
86+
res: pino.stdSerializers.res,
6087
},
6188
timestamp: customTimestamp,
6289
});
@@ -66,3 +93,64 @@ if (LOG_WITH_FILE) {
6693
export const fastify = Fastify({
6794
logger: _logger,
6895
});
96+
97+
// 安全的轮转测试端点
98+
// if (LOG_WITH_FILE && logStream) {
99+
// fastify.get('/test-rotate', async (request, reply) => {
100+
// try {
101+
// // 确保日志流可用
102+
// if (!logStream || typeof logStream.write !== 'function') {
103+
// throw new Error('日志流不可用');
104+
// }
105+
//
106+
// // 写入轮转前的日志
107+
// const preRotateLog = '--- 手动触发轮转前的测试日志 ---\n';
108+
// await new Promise((resolve, reject) => {
109+
// logStream.write(preRotateLog, 'utf8', (err) => {
110+
// if (err) reject(err);
111+
// else resolve();
112+
// });
113+
// });
114+
//
115+
// // 确保写入完成
116+
// await new Promise(resolve => setTimeout(resolve, 100));
117+
//
118+
// // 触发轮转
119+
// logStream.rotate();
120+
//
121+
// // 等待轮转完成
122+
// await new Promise((resolve) => {
123+
// logStream.once('rotated', resolve);
124+
// });
125+
//
126+
// // 确保日志流在轮转后仍然可用
127+
// if (!logStream || typeof logStream.write !== 'function') {
128+
// throw new Error('轮转后日志流不可用');
129+
// }
130+
//
131+
// // 写入轮转后的日志
132+
// const postRotateLog = '--- 手动触发轮转后的测试日志 ---\n';
133+
// await new Promise((resolve, reject) => {
134+
// logStream.write(postRotateLog, 'utf8', (err) => {
135+
// if (err) reject(err);
136+
// else resolve();
137+
// });
138+
// });
139+
//
140+
// reply.send({
141+
// status: 'success',
142+
// message: '日志轮转已手动触发',
143+
// logDirectory: path.resolve(logDirectory)
144+
// });
145+
// } catch (err) {
146+
// console.error('轮转过程中出错:', err);
147+
// reply.status(500).send({
148+
// status: 'error',
149+
// message: '轮转失败',
150+
// error: err.message
151+
// });
152+
// }
153+
// });
154+
//
155+
// console.log('测试端点已注册: GET /test-rotate');
156+
// }

docs/updateRecord.md

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

3+
### 20250728
4+
5+
更新至V1.2.2
6+
7+
1. 文件头增加 lang 属性,方便区分加密情况下这个源是哪张类型,`ds` `dr2` `hipy`
8+
2. 修复日志输出到文件在轮转时乱创文件夹问题
9+
3. drpyS 增加 `buildQueryString` 函数
10+
311
### 20250727
412

513
更新至V1.2.1

libs/drpyS.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ export async function getSandbox(env = {}) {
302302
buildUrl,
303303
keysToLowerCase,
304304
parseQueryString,
305+
buildQueryString,
305306
encodeIfContainsSpecialChars,
306307
objectToQueryString,
307308
forge

libs_drpy/drpyCustom.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,27 @@ function $require(url) {
685685
eval(request(url));
686686
}
687687

688+
//对象To字符串query
689+
globalThis.buildQueryString = function (params) {
690+
const queryArray = [];
691+
for (const key in params) {
692+
if (params.hasOwnProperty(key)) {
693+
// 处理参数值:兼容null、undefined,转为字符串并编码
694+
let value = params[key];
695+
if (value === undefined || value === null) {
696+
value = "";
697+
} else {
698+
value = value.toString();
699+
}
700+
// 编码键值(兼容ES5)
701+
const encodedKey = encodeURIComponent(key);
702+
const encodedValue = encodeURIComponent(value);
703+
queryArray.push(encodedKey + "=" + encodedValue);
704+
}
705+
}
706+
return queryArray.join("&");
707+
}
708+
688709
//字符串To对象
689710
globalThis.parseQueryString = function (query) {
690711
const params = {};

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "drpy-node",
3-
"version": "1.2.1",
3+
"version": "1.2.2",
44
"main": "index.js",
55
"type": "module",
66
"scripts": {
@@ -47,7 +47,7 @@
4747
"pinyin": "^4.0.0",
4848
"qs": "^6.13.1",
4949
"queue": "^7.0.0",
50-
"rotating-file-stream": "^3.2.5",
50+
"rotating-file-stream": "^3.2.6",
5151
"simplecc-wasm": "^1.1.0",
5252
"sync-fetch": "^0.6.0-2",
5353
"tunnel": "^0.0.6",

public/index.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</head>
99
<body>
1010
<h1 id="drpysdrpy-node">drpyS(drpy-node)</h1>
11-
<p>nodejs作为服务端的drpy实现。全面升级异步写法<br><del>积极开发中,每日一更</del>,当前进度 <code>55%</code><br>找工作中,随缘更新</p>
11+
<p>nodejs作为服务端的drpy实现。全面升级异步写法<br><del>积极开发中,每日一更</del>,当前进度 <code>60%</code><br><del>找工作中,随缘更新</del><br>上班当牛马,下班要带娃,阶段性佛系趁娃睡觉熬夜更新</p>
1212
<ul>
1313
<li><a href="/config?pwd=dzyyds">本地配置接口-动态本地</a></li>
1414
<li><a href="/config/1?pwd=dzyyds">本地配置接口-动态外网/局域网</a></li>
@@ -24,6 +24,8 @@ <h1 id="drpysdrpy-node">drpyS(drpy-node)</h1>
2424
<li><a href="/cat/index.html">在线猫ds源主页</a></li>
2525
</ul>
2626
<h2 id="更新记录">更新记录</h2>
27+
<h3 id="20250728">20250728</h3>
28+
<p>更新至V1.2.2</p>
2729
<h3 id="20250727">20250727</h3>
2830
<p>更新至V1.2.1</p>
2931
<p>全新版本,大堆特性,性能优化,稳定性增强。</p>

spider/js/16wMV[听].js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
searchable: 1,
44
filterable: 1,
55
quickSearch: 0,
6-
title: '16wMV'
6+
title: '16wMV',
7+
lang: 'ds'
78
})
89
*/
910

0 commit comments

Comments
 (0)