-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathxbpq.js
More file actions
216 lines (199 loc) · 6.65 KB
/
xbpq.js
File metadata and controls
216 lines (199 loc) · 6.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/**
* XBPQ (小白盘棋) 模块
*
* 提供视频源规则的加载、缓存和执行功能
* 支持首页、分类、详情、搜索、播放等核心功能
*
* 主要功能:
* - 规则文件的动态加载和缓存
* - 视频源的各种操作接口
* - 模块生命周期管理
*
* @author drpy-node
* @version 1.0.0
*/
import {computeHash, deepCopy} from "../utils/utils.js";
import {readFile} from "fs/promises";
import {md5} from "../libs_drpy/crypto-util.js";
// 模块缓存,用于存储已加载的模块以提高性能
const moduleCache = new Map();
/**
* 获取规则的JSON字符串表示
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量和配置
* @returns {Promise<string>} 规则对象的JSON字符串
*/
const getRule = async function (filePath, env) {
const moduleObject = await init(filePath, env);
return JSON.stringify(moduleObject);
}
/**
* 将JSON字符串或对象转换为JavaScript对象
*
* @param {string|Object} json - JSON字符串或对象
* @returns {Object} 转换后的JavaScript对象
*/
const json2Object = function (json) {
if (!json) {
return {}
} else if (json && typeof json === 'object') {
return json
}
return JSON.parse(json);
}
/**
* 初始化模块
*
* 加载指定路径的规则文件,支持缓存机制以提高性能
* 如果文件内容未变化且缓存存在,则直接返回缓存的模块对象
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量,包含ext等配置
* @param {boolean} refresh - 是否强制刷新缓存
* @returns {Promise<Object>} 初始化后的模块对象
* @throws {Error} 当模块初始化失败时抛出错误
*/
const init = async function (filePath, env = {}, refresh) {
try {
// 读取文件内容并计算哈希值用于缓存验证
const fileContent = await readFile(filePath, 'utf-8');
const fileHash = computeHash(fileContent);
let moduleExt = env.ext || '';
let hashMd5 = md5(filePath + '#pAq#' + moduleExt);
// 检查缓存是否存在且有效
if (moduleCache.has(hashMd5) && !refresh) {
const cached = moduleCache.get(hashMd5);
if (cached.hash === fileHash) {
return cached.moduleObject;
}
}
log(`Loading module: ${filePath}`);
let rule = {};
// 初始化规则模块
await rule.init(moduleExt || {});
const moduleObject = deepCopy(rule);
// 将模块对象存入缓存
moduleCache.set(hashMd5, {moduleObject, hash: fileHash});
return moduleObject;
} catch (error) {
console.log(`Error in xbpq.init :${filePath}`, error);
throw new Error(`Failed to initialize module:${error.message}`);
}
}
/**
* 获取首页数据
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {number} filter - 过滤器参数,默认为1
* @returns {Promise<Object>} 首页数据对象
*/
const home = async function (filePath, env, filter = 1) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.home(filter));
}
/**
* 获取首页推荐视频数据
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @returns {Promise<Object>} 首页推荐视频数据对象
*/
const homeVod = async function (filePath, env) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.homeVod());
}
/**
* 获取分类页面数据
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {string} tid - 分类ID
* @param {number} pg - 页码,默认为1
* @param {number} filter - 过滤器参数,默认为1
* @param {Object} extend - 扩展参数,默认为空对象
* @returns {Promise<Object>} 分类页面数据对象
*/
const category = async function (filePath, env, tid, pg = 1, filter = 1, extend = {}) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.category(tid, pg, filter, extend));
}
/**
* 获取视频详情数据
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {string} ids - 视频ID列表
* @returns {Promise<Object>} 视频详情数据对象
*/
const detail = async function (filePath, env, ids) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.detail(ids));
}
/**
* 执行搜索操作
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {string} wd - 搜索关键词
* @param {number} quick - 快速搜索标志,默认为0
* @param {number} pg - 页码,默认为1
* @returns {Promise<Object>} 搜索结果数据对象
*/
const search = async function (filePath, env, wd, quick = 0, pg = 1) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.search(wd, quick, pg));
}
/**
* 获取播放地址
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {string} flag - 播放标志
* @param {string} id - 播放ID
* @param {Array} flags - 播放标志列表
* @returns {Promise<Object>} 播放地址数据对象
*/
const play = async function (filePath, env, flag, id, flags) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.play(flag, id, flags));
}
/**
* 代理请求处理
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {Object} params - 代理参数
* @returns {Promise<Object>} 代理响应数据对象
*/
const proxy = async function (filePath, env, params) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.proxy(params));
}
/**
* 执行自定义动作
*
* @param {string} filePath - 规则文件路径
* @param {Object} env - 环境变量
* @param {string} action - 动作名称
* @param {*} value - 动作参数值
* @returns {Promise<Object>} 动作执行结果数据对象
*/
const action = async function (filePath, env, action, value) {
const moduleObject = await init(filePath, env);
return json2Object(await moduleObject.action(action, value));
}
// 导出所有API方法
export default {
getRule, // 获取规则
init, // 初始化模块
home, // 首页数据
homeVod, // 首页推荐
category, // 分类数据
detail, // 详情数据
search, // 搜索功能
play, // 播放地址
proxy, // 代理请求
action, // 自定义动作
}