Skip to content

Commit c94a438

Browse files
committed
update:基础框架用法实现。极致神似drpy2用法
1 parent 6169944 commit c94a438

File tree

5 files changed

+434
-76
lines changed

5 files changed

+434
-76
lines changed

Diff for: index.js

+53-34
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,63 @@
1-
import Fastify from 'fastify'; // 使用命名导入 Fastify
2-
import path from 'path'; // 使用 Node.js 的 path 模块来处理文件路径
3-
4-
// 使用 pino-pretty 来格式化日志输出
5-
import pino from 'pino';
6-
import pinoPretty from 'pino-pretty';
7-
8-
// 创建 pino-pretty 配置
9-
const prettyPrintOptions = {
10-
colorize: true, // 启用颜色输出
11-
translateTime: 'SYS:standard', // 显示标准时间
12-
ignore: 'pid,hostname' // 忽略 pid 和 hostname
13-
};
1+
import Fastify from 'fastify';
2+
import * as drpy from './libs/drpy.js';
3+
import path from 'path';
4+
import {fileURLToPath} from 'url';
145

15-
// 创建 Fastify 实例
16-
const fastify = Fastify({
17-
logger: pino({
18-
level: 'info', // 设置日志级别
19-
prettyPrint: false // 禁用内置 prettyPrint
20-
}).child({}, {stream: pinoPretty(prettyPrintOptions)}) // 使用 pino-pretty 进行日志格式化
21-
});
6+
const fastify = Fastify({logger: true});
227

23-
// 引入封装好的库
24-
import * as drpy from './libs/drpy.js';
8+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
9+
console.log('__dirname:', __dirname);
2510

26-
// API 接口: 根据模块名加载相应的 js 文件,并调用 drpy 的方法
11+
// 动态加载模块并根据 query 执行不同逻辑
2712
fastify.get('/api/:module', async (request, reply) => {
28-
const moduleName = request.params.module; // 获取模块名,例如 '360'
29-
const modulePath = new URL(`./js/${moduleName}.js`, import.meta.url).pathname; // 获取模块路径
13+
const moduleName = request.params.module;
14+
const query = request.query; // 获取 query 参数
15+
const modulePath = path.join(__dirname, 'js', `${moduleName}.js`);
3016

3117
try {
32-
// 动态加载 js 文件
33-
const module = await import(modulePath); // 使用动态导入加载模块
34-
console.log(module)
35-
36-
// 由于 `360.js` 使用的是全局的 `rule` 变量,我们通过 `module.default` 获取
37-
const result = await drpy.init(module.rule); // 使用 `module.rule` 直接调用
38-
// 返回结果
39-
return reply.send(result);
18+
// 根据 query 参数决定执行逻辑
19+
if ('play' in query) {
20+
// 处理播放逻辑
21+
const result = await drpy.play(modulePath);
22+
return reply.send(result);
23+
}
24+
25+
if ('ac' in query && 't' in query) {
26+
// 分类逻辑
27+
const result = await drpy.cate(modulePath);
28+
return reply.send(result);
29+
}
30+
31+
if ('ac' in query && 'ids' in query) {
32+
// 详情逻辑
33+
const result = await drpy.detail(modulePath);
34+
return reply.send(result);
35+
}
36+
37+
if ('wd' in query) {
38+
// 搜索逻辑
39+
const result = await drpy.search(modulePath);
40+
return reply.send(result);
41+
}
42+
43+
if ('refresh' in query) {
44+
// 强制刷新初始化逻辑
45+
const refreshedObject = await drpy.init(modulePath, true);
46+
return reply.send(refreshedObject);
47+
}
48+
49+
// 默认逻辑,返回 home + homeVod 接口
50+
const result_home = await drpy.home(modulePath);
51+
const result_homeVod = await drpy.homeVod(modulePath);
52+
const result = {
53+
class: result_home,
54+
list: result_homeVod
55+
}
56+
reply.send(result);
57+
4058
} catch (error) {
41-
reply.status(500).send({error: `Failed to load module ${moduleName}: ${error.message}`});
59+
console.error('Error processing request:', error);
60+
reply.status(500).send({error: `Failed to process request for module ${moduleName}: ${error.message}`});
4261
}
4362
});
4463

Diff for: js/360.js

+39-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,46 @@
11
// js/360.js
2-
export var rule = {
2+
3+
var rule = {
34
title: '标题1',
45
description: '这是描述',
56
category: '视频',
6-
一级:async (req)=>{
7+
class_parse: async () => {
8+
console.log('执行了分类获取')
9+
return [
10+
{type_id: '1', type_name: '电影'},
11+
{type_id: '2', type_name: '电视剧'},
12+
{type_id: '3', type_name: '综艺'},
13+
{type_id: '4', type_name: '动漫'},
14+
]
15+
},
16+
预处理: async () => {
17+
console.log('执行了预处理')
18+
rule.title = '360影视'
19+
},
20+
推荐: async () => {
21+
sleepSync(2000);
22+
console.log('进入了推荐')
23+
// return '这是推荐:' + rule.title
24+
return [
25+
{vod_name: '测试电影1', vod_pic: '1.png', vod_remarks: '测试描述1', vod_id: 'http://www.1.com'},
26+
{vod_name: '测试电影2', vod_pic: '2.png', vod_remarks: '测试描述2', vod_id: 'http://www.2.com'},
27+
]
28+
},
29+
一级: async () => {
30+
// await sleep(200);
31+
sleepSync(200);
732
let html = await req('123');
8-
// console.log(html);
9-
return html
33+
console.log('title:', rule.title);
34+
console.log('html:' + html);
35+
return html + '\n' + '这是一级:' + rule.title
36+
},
37+
二级: async () => {
38+
return '这是二级:' + rule.title
39+
},
40+
搜索: async () => {
41+
return '这是搜索:' + rule.title
42+
},
43+
lazy: async () => {
44+
return '这是播放:' + rule.title
1045
},
1146
};

Diff for: libs/drpy.js

+82-38
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,107 @@
1-
// drpy.js: 封装模块,包含处理逻辑
1+
import * as utils from '../utils/utils.js'; // 使用 import 引入工具类
2+
import {readFile} from 'fs/promises';
3+
import vm from 'vm'; // Node.js 的 vm 模块
24

3-
import * as utils from '../utils/utils.js'; // 使用 import 引入工具类
4-
const { req } = await import('../utils/req.js');
5+
const {req} = await import('../utils/req.js');
6+
const {sleep, sleepSync} = await import('../utils/utils.js');
7+
8+
// 缓存已初始化的模块
9+
const moduleCache = new Map();
10+
11+
/**
12+
* 初始化模块:加载并执行模块文件,存储初始化后的 rule 对象
13+
* 如果存在 `预处理` 属性且为函数,会在缓存前执行
14+
* @param {string} filePath - 模块文件路径
15+
* @param refresh 强制清除缓存
16+
* @returns {Promise<object>} - 返回初始化后的模块对象
17+
*/
18+
export async function init(filePath, refresh) {
19+
if (moduleCache.has(filePath) && !refresh) {
20+
console.log(`Module ${filePath} already initialized, returning cached instance.`);
21+
return moduleCache.get(filePath);
22+
}
523

6-
export async function init(rule) {
7-
// 假设我们传入的 moduleObject 是 js/360.js 中的 rule 对象
8-
const moduleObject = utils.deepCopy(rule)
924
try {
10-
// 读取并修改传入的对象
11-
if (moduleObject && moduleObject.title) {
12-
moduleObject.title += ' (drpy)'; // 修改 title 属性
13-
}
25+
let t1 = utils.getNowTime();
26+
// 读取 JS 文件的内容
27+
const fileContent = await readFile(filePath, 'utf-8');
1428

15-
// 你可以根据需要修改其他属性
16-
if (moduleObject && moduleObject.description) {
17-
moduleObject.description += ' [Modified]';
18-
}
19-
const title = moduleObject.title
20-
console.log(moduleObject)
21-
const titleLength = utils.getTitleLength(title); // 使用 utils.js 中的方法
29+
// 创建一个沙箱上下文,注入需要的全局变量和函数
30+
const sandbox = {
31+
console,
32+
req,
33+
sleep,
34+
sleepSync,
35+
utils,
36+
rule: {}, // 用于存放导出的 rule 对象
37+
};
38+
39+
// 创建一个上下文
40+
const context = vm.createContext(sandbox);
2241

42+
// 执行文件内容,将其放入沙箱中
43+
const script = new vm.Script(fileContent);
44+
script.runInContext(context);
2345

24-
Object.assign(moduleObject, {
25-
message: `Module initialized with title: ${title}`,
26-
titleLength: titleLength
27-
})
46+
// 访问沙箱中的 rule 对象
47+
const moduleObject = utils.deepCopy(sandbox.rule);
2848

29-
console.log(typeof moduleObject.一级)
30-
if( typeof moduleObject.一级 === 'function'){
31-
let html = await moduleObject.一级(req)
32-
console.log(html)
33-
moduleObject.html = html
49+
// 检查并执行 `预处理` 方法
50+
if (typeof moduleObject.预处理 === 'function') {
51+
console.log('Executing preprocessing...');
52+
await moduleObject.预处理();
3453
}
3554

36-
// 返回修改后的对象
55+
// 缓存初始化后的模块
56+
moduleCache.set(filePath, moduleObject);
57+
58+
let t2 = utils.getNowTime();
59+
moduleObject.cost = t2 - t1;
60+
3761
return moduleObject;
3862
} catch (error) {
3963
console.error('Error in drpy.init:', error);
4064
throw new Error('Failed to initialize module');
4165
}
4266
}
4367

44-
// 其他方法可以依照需求继续添加
45-
export async function home() {
46-
return {message: 'Home method'};
68+
/**
69+
* 调用模块的指定方法
70+
* @param {string} filePath - 模块文件路径
71+
* @param {string} method - 要调用的属性方法名称
72+
* @returns {Promise<any>} - 方法调用的返回值
73+
*/
74+
async function invokeMethod(filePath, method) {
75+
const moduleObject = await init(filePath); // 确保模块已初始化
76+
if (moduleObject[method] && typeof moduleObject[method] === 'function') {
77+
return await moduleObject[method](); // 调用对应的方法
78+
} else {
79+
throw new Error(`Method ${method} not found in module ${filePath}`);
80+
}
81+
}
82+
83+
// 各种接口调用方法
84+
85+
export async function home(filePath) {
86+
return await invokeMethod(filePath, 'class_parse');
87+
}
88+
89+
export async function homeVod(filePath) {
90+
return await invokeMethod(filePath, '推荐');
4791
}
4892

49-
export async function cate() {
50-
return {message: 'Cate method'};
93+
export async function cate(filePath) {
94+
return await invokeMethod(filePath, '一级');
5195
}
5296

53-
export async function detail() {
54-
return {message: 'Detail method'};
97+
export async function detail(filePath) {
98+
return await invokeMethod(filePath, '二级');
5599
}
56100

57-
export async function play() {
58-
return {message: 'Play method'};
101+
export async function search(filePath) {
102+
return await invokeMethod(filePath, '搜索');
59103
}
60104

61-
export async function search() {
62-
return {message: 'Search method'};
105+
export async function play(filePath) {
106+
return await invokeMethod(filePath, 'lazy');
63107
}

Diff for: utils/utils.js

+20
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,24 @@ export function getTitleLength(title) {
77
return title.length; // 返回标题长度
88
}
99

10+
export function getNowTime() {
11+
return (new Date()).getTime()
12+
}
13+
14+
export async function sleep(ms) {
15+
// 模拟异步请求
16+
return new Promise((resolve) => {
17+
setTimeout(() => {
18+
resolve();
19+
}, ms);
20+
});
21+
}
22+
23+
export function sleepSync(ms) {
24+
const end = Date.now() + ms; // 获取当前时间并计算结束时间
25+
while (Date.now() < end) {
26+
// 阻塞式等待,直到时间到达
27+
}
28+
}
29+
1030
export const deepCopy = cloneDeep

0 commit comments

Comments
 (0)