Skip to content

Commit 7a064a9

Browse files
author
Taois
committed
feat: 更新版本至v1.2.0
1 parent dfb0e3e commit 7a064a9

File tree

137 files changed

+902
-207
lines changed

Some content is hidden

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

137 files changed

+902
-207
lines changed

.env.development

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
NODE_ENV=production
1+
#NODE_ENV=production
2+
NODE_ENV=development
23

34
# just a flag
45
ENV='staging'
@@ -16,4 +17,4 @@ EPG_URL = https://iptv.crestekk.cn/epgphp/index.php?ch={name}&date={date}
1617
LOGO_URL = https://live.mxdyeah.top/logo/{name}.png
1718
LIVE_URL = 'https://livetv.wqwqwq.sbs/tv.m3u'
1819
# LIVE_URL = './lives/tv.m3u'
19-
MAX_TASK = 8
20+
MAX_TASK = 8

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ dist
132132
!README.md
133133
.idea
134134
/config/env.json
135-
/js/UC分享.js
135+
/spider/js/UC分享.js
136136
/json/UC分享.json
137137
/jx/奇奇.js
138-
/js/百忙无果[].js
138+
/spider/js/百忙无果[].js
139139
/data/settings/link_data.json
140140
/yarn.lock
141141
/custom.json

README.md

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

33
nodejs作为服务端的drpy实现。全面升级异步写法
4-
~~积极开发中,每日一更~~,当前进度 `49%`
4+
~~积极开发中,每日一更~~,当前进度 `55%`
55
找工作中,随缘更新
66

77
* [本地配置接口-动态本地](/config?pwd=)
@@ -19,69 +19,22 @@ nodejs作为服务端的drpy实现。全面升级异步写法
1919

2020
## 更新记录
2121

22-
### 20250310
23-
24-
更新至V1.1.23
25-
26-
### 20250227
27-
28-
更新至V1.1.22
29-
30-
### 20250226
31-
32-
更新至V1.1.21
33-
34-
### 20250225
35-
36-
更新至V1.1.20
37-
38-
### 20250224
39-
40-
更新至V1.1.19
41-
42-
### 20250211
43-
44-
更新至V1.1.18
45-
46-
### 20250206
22+
### 20250726
4723

48-
更新至V1.1.17
24+
更新至V1.2.0
4925

50-
### 20250123
26+
1. 支持挂载py源
5127

52-
更新至V1.1.16
53-
54-
### 20250122
55-
56-
更新至V1.1.15
57-
58-
1. ds源和dr2源增加装逼壳图标支持
59-
60-
### 20250121
61-
62-
更新至V1.1.14
63-
64-
1. 猫源ds在线配置支持接口密码
65-
2. 新增源
66-
3. 磁盘加速
67-
68-
### 20250120
69-
70-
更新至V1.1.13
71-
72-
1. 完善猫在线配置
73-
74-
### 20250117
75-
76-
本次未更新版本
28+
### 20250310
7729

78-
1. 新开项目,使ds源适用于新版猫影视 [猫爪catpwd](https://github.com/CatPawApp/CatPawOpen)
30+
更新至V1.1.23
7931

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

8234
**注意事项**
8335

84-
总是有人遇到各种奇葩问题,像什么没弹幕,访问/config/1服务马上崩溃等等,能自行解决最好,解决不了我建议你使用下方安装教程 `3.道长腾讯轻量云服务器安装方案`
36+
总是有人遇到各种奇葩问题,像什么没弹幕,访问/config/1服务马上崩溃等等,能自行解决最好,解决不了我建议你使用下方安装教程
37+
`3.道长腾讯轻量云服务器安装方案`
8538
跟我一样还有问题那就不可能了,我能用你即能用
8639

8740
## 基础框架

controllers/api.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,45 @@
11
import path from 'path';
2-
import {existsSync} from 'fs';
2+
import {existsSync, watch} from 'fs';
33
import {base64Decode} from '../libs_drpy/crypto-util.js';
44
import * as drpy from '../libs/drpyS.js';
55
import {ENV} from "../utils/env.js";
66
import {validatePwd} from "../utils/api_validate.js";
77

8+
//添加JSON文件监听
9+
let jsonWatcher = null;
10+
let debounceTimers = new Map(); // 防抖计时器
11+
function startJsonWatcher(jsonDir) {
12+
if (process.env.NODE_ENV !== 'development') return;
13+
14+
try {
15+
jsonWatcher = watch(jsonDir, {recursive: true}, (eventType, filename) => {
16+
if (filename && filename.endsWith('.json')) {
17+
// 清除之前的计时器
18+
if (debounceTimers.has(filename)) {
19+
clearTimeout(debounceTimers.get(filename));
20+
}
21+
22+
// 设置新的防抖计时器
23+
const timer = setTimeout(() => {
24+
console.log(`${filename}文件已${eventType},即将清除所有模块缓存`);
25+
drpy.clearAllCache();
26+
debounceTimers.delete(filename);
27+
}, 100); // 100ms防抖延迟
28+
29+
debounceTimers.set(filename, timer);
30+
}
31+
});
32+
33+
console.log(`start json file hot reload success,listening path: ${jsonDir}`);
34+
} catch (error) {
35+
console.error('start json file listening failed with error:', error);
36+
}
37+
}
38+
839
export default (fastify, options, done) => {
40+
// 启动JSON监听
41+
startJsonWatcher(options.jsonDir);
42+
943
// 动态加载模块并根据 query 执行不同逻辑
1044
fastify.route({
1145
method: ['GET', 'POST'], // 同时支持 GET 和 POST

controllers/config.js

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import {readdirSync, readFileSync, writeFileSync, existsSync} from 'fs';
2+
import {readFile} from 'fs/promises';
23
import path from 'path';
34
import * as drpy from '../libs/drpyS.js';
45
import '../libs_drpy/jinja.js'
56
import {naturalSort, urljoin, updateQueryString} from '../utils/utils.js'
67
import {md5} from "../libs_drpy/crypto-util.js";
78
import {ENV} from "../utils/env.js";
9+
import {extractNameFromCode} from "../utils/python.js";
810
import {validateBasicAuth, validatePwd} from "../utils/api_validate.js";
911
import {getSitesMap} from "../utils/sites-map.js";
1012
import {getParsesDict} from "../utils/file.js";
@@ -16,7 +18,9 @@ const {jsEncoder} = drpy;
1618
async function generateSiteJSON(options, requestHost, sub, pwd) {
1719
const jsDir = options.jsDir;
1820
const dr2Dir = options.dr2Dir;
21+
const pyDir = options.pyDir;
1922
const configDir = options.configDir;
23+
const jsonDir = options.jsonDir;
2024
const subFilePath = options.subFilePath;
2125
const rootDir = options.rootDir;
2226

@@ -48,6 +52,33 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
4852
}
4953
}
5054
let sites = [];
55+
56+
//以下为自定义APP模板部分
57+
try {
58+
const templateConfigPath = path.join(jsonDir, './App模板配置.json');
59+
if (existsSync(templateConfigPath)) {
60+
const templateContent = readFileSync(templateConfigPath, 'utf-8');
61+
const templateConfig = JSON.parse(templateContent);
62+
sites = Object.entries(templateConfig).filter(([key]) => valid_files.includes(`${key}[模板].js`))
63+
.flatMap(([key, config]) =>
64+
Object.entries(config)
65+
.filter(([name]) => name !== "示例")
66+
.map(([name]) => ({
67+
key: `drpyS_${name}_${key}`,
68+
name: `${name}[M](${key.replace('App', '').toUpperCase()})`,
69+
type: 4,
70+
api: `${requestHost}/api/${key}[模板]${pwd ? `?pwd=${pwd}` : ''}`,
71+
searchable: 1,
72+
filterable: 1,
73+
quickSearch: 0,
74+
ext: `../json/App模板配置.json$${name}`
75+
})));
76+
}
77+
} catch (e) {
78+
console.error('读取App模板配置失败:', e.message);
79+
}
80+
//以上为自定义APP[模板]配置自动添加代码
81+
5182
let link_jar = '';
5283
// console.log('hide_adult:', ENV.get('hide_adult'));
5384
if (ENV.get('hide_adult') === '1') {
@@ -73,6 +104,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
73104
} catch (e) {
74105
throw new Error(`Error parsing rule object for file: ${file}, ${e.message}`);
75106
}
107+
ruleObject.title = ruleObject.title || baseName;
76108

77109
let fileSites = [];
78110
if (baseName === 'push_agent') {
@@ -90,8 +122,8 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
90122
fileSites.push({key, name, ext});
91123
});
92124
} else {
93-
let key = `drpyS_${baseName}`;
94-
let name = `${baseName}(DS)`;
125+
let key = `drpyS_${ruleObject.title}`;
126+
let name = `${ruleObject.title}(DS)`;
95127
fileSites.push({key, name});
96128
}
97129

@@ -156,6 +188,7 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
156188
} catch (e) {
157189
throw new Error(`Error parsing rule object for file: ${file}, ${e.message}`);
158190
}
191+
ruleObject.title = ruleObject.title || baseName;
159192

160193
let fileSites = [];
161194
if (baseName === 'push_agent') {
@@ -170,8 +203,8 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
170203
fileSites.push({key, name, ext: _ext});
171204
});
172205
} else {
173-
let key = `drpy2_${baseName}`;
174-
let name = `${baseName}(DR2)`;
206+
let key = `drpy2_${ruleObject.title}`;
207+
let name = `${ruleObject.title}(DR2)`;
175208
fileSites.push({key, name, ext});
176209
}
177210

@@ -200,6 +233,77 @@ async function generateSiteJSON(options, requestHost, sub, pwd) {
200233

201234
}
202235

236+
// 根据用户是否启用py源去生成对应配置
237+
if (ENV.get('enable_py', '1') === '1') {
238+
const py_files = readdirSync(pyDir);
239+
let py_valid_files = py_files.filter((file) => file.endsWith('.py') && !file.startsWith('_')); // 筛选出不是 "_" 开头的 .py 文件
240+
// log(py_valid_files);
241+
log(`开始生成python的t3配置,pyDir:${pyDir},源数量: ${py_valid_files.length}`);
242+
243+
const py_tasks = py_valid_files.map((file) => {
244+
return {
245+
func: async ({file, pyDir, requestHost, pwd, SitesMap}) => {
246+
const baseName = path.basename(file, '.py'); // 去掉文件扩展名
247+
const extJson = path.join(pyDir, baseName + '.json');
248+
let api = `${requestHost}/py/${file}`;
249+
let ext = existsSync(extJson) ? `${requestHost}/py/${file}` : '';
250+
if (pwd) {
251+
api += `?pwd=${pwd}`;
252+
if (ext) {
253+
ext += `?pwd=${pwd}`;
254+
}
255+
}
256+
let ruleObject = {
257+
searchable: 1, // 固定值
258+
filterable: 1, // 固定值
259+
quickSearch: 1, // 固定值
260+
};
261+
const fileContent = await readFile(path.join(pyDir, file), 'utf-8');
262+
ruleObject.title = extractNameFromCode(fileContent) || baseName;
263+
264+
let fileSites = [];
265+
if (baseName === 'push_agent') {
266+
let key = 'push_agent';
267+
let name = `${ruleObject.title}(hipy_t3)`;
268+
fileSites.push({key, name, ext});
269+
} else if (SitesMap.hasOwnProperty(baseName) && Array.isArray(SitesMap[baseName])) {
270+
SitesMap[baseName].forEach((it) => {
271+
let key = `hipy_py_${it.alias}`;
272+
let name = `${it.alias}(hipy_t3)`;
273+
let _ext = updateQueryString(ext, it.queryStr);
274+
fileSites.push({key, name, ext: _ext});
275+
});
276+
} else {
277+
let key = `hipy_py_${ruleObject.title}`;
278+
let name = `${ruleObject.title}(hipy_t3)`;
279+
fileSites.push({key, name, ext});
280+
}
281+
282+
fileSites.forEach((fileSite) => {
283+
const site = {
284+
key: fileSite.key,
285+
name: fileSite.name,
286+
type: 3, // 固定值
287+
api,
288+
searchable: ruleObject.searchable,
289+
filterable: ruleObject.filterable,
290+
quickSearch: ruleObject.quickSearch,
291+
more: ruleObject.more,
292+
logo: ruleObject.logo,
293+
ext: fileSite.ext || "", // 固定为空字符串
294+
};
295+
sites.push(site);
296+
});
297+
},
298+
param: {file, pyDir, requestHost, pwd, SitesMap},
299+
id: file,
300+
};
301+
});
302+
303+
await batchExecute(py_tasks, listener);
304+
305+
}
306+
203307
// 根据用户是否启用挂载数据源去生成对应配置
204308
if (ENV.get('enable_link_data', '0') === '1') {
205309
log(`开始挂载外部T4数据`);

0 commit comments

Comments
 (0)