yz-yuki-plugin 2.0.1 → 2.0.2-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +8 -7
  3. package/lib/apps/bilibili.js +52 -20
  4. package/lib/apps/help.js +3 -0
  5. package/lib/apps/version.js +3 -0
  6. package/lib/apps/weibo.js +34 -16
  7. package/lib/components/dynamic/Account.js +2 -0
  8. package/lib/components/dynamic/Content.js +2 -0
  9. package/lib/components/dynamic/Footer.js +1 -0
  10. package/lib/components/dynamic/ForwardContent.js +2 -0
  11. package/lib/components/dynamic/LogoText.js +2 -0
  12. package/lib/components/dynamic/MainPage.js +1 -0
  13. package/lib/components/help/Help.js +1 -0
  14. package/lib/components/loginQrcode/Page.js +1 -0
  15. package/lib/index.js +53 -2
  16. package/lib/models/bilibili/bilibili.api.d.ts +3 -0
  17. package/lib/models/bilibili/bilibili.api.js +9 -0
  18. package/lib/models/bilibili/bilibili.get.web.data.d.ts +3 -0
  19. package/lib/models/bilibili/bilibili.get.web.data.js +4 -0
  20. package/lib/models/bilibili/bilibili.models.d.ts +37 -0
  21. package/lib/models/bilibili/bilibili.models.js +71 -19
  22. package/lib/models/bilibili/bilibili.query.d.ts +24 -0
  23. package/lib/models/bilibili/bilibili.query.js +69 -11
  24. package/lib/models/bilibili/bilibili.task.d.ts +41 -0
  25. package/lib/models/bilibili/bilibili.task.js +77 -34
  26. package/lib/models/bilibili/bilibili.wbi.d.ts +6 -0
  27. package/lib/models/bilibili/bilibili.wbi.js +16 -3
  28. package/lib/models/version/version.d.ts +10 -0
  29. package/lib/models/version/version.js +12 -1
  30. package/lib/models/weibo/weibo.api.d.ts +1 -0
  31. package/lib/models/weibo/weibo.api.js +2 -0
  32. package/lib/models/weibo/weibo.get.web.data.d.ts +3 -0
  33. package/lib/models/weibo/weibo.get.web.data.js +3 -0
  34. package/lib/models/weibo/weibo.query.d.ts +20 -0
  35. package/lib/models/weibo/weibo.query.js +63 -6
  36. package/lib/models/weibo/weibo.task.d.ts +49 -0
  37. package/lib/models/weibo/weibo.task.js +84 -34
  38. package/lib/utils/config.d.ts +50 -0
  39. package/lib/utils/config.js +55 -2
  40. package/lib/utils/image.d.ts +11 -0
  41. package/lib/utils/image.js +15 -0
  42. package/lib/utils/paths.js +7 -7
  43. package/lib/utils/puppeteer.render.d.ts +15 -0
  44. package/lib/utils/puppeteer.render.js +37 -15
  45. package/package.json +6 -5
@@ -5,6 +5,9 @@ import lodash from 'lodash';
5
5
  import path from 'path';
6
6
  import { _paths } from './paths.js';
7
7
 
8
+ /**
9
+ * Config 类用于管理配置文件的读取和监听
10
+ */
8
11
  class Config {
9
12
  versionPath;
10
13
  defaultConfigPath;
@@ -14,13 +17,17 @@ class Config {
14
17
  watcher;
15
18
  constructor() {
16
19
  this.versionPath = path.join(_paths.pluginPath, 'CHANGELOG.md');
20
+ /** 默认设置 */
17
21
  this.defaultConfigPath = path.join(_paths.pluginPath, 'defaultConfig');
18
22
  this.defaultConfig = {};
23
+ /** 用户设置 */
19
24
  this.userConfigPath = path.join(_paths.pluginPath, 'config');
20
25
  this.userConfig = {};
26
+ /** 监听文件 */
21
27
  this.watcher = {};
22
28
  this.initConfigFiles();
23
29
  }
30
+ /** 操作并创建配置文件到指定目录 */
24
31
  initConfigFiles() {
25
32
  const configFiles = [
26
33
  {
@@ -54,6 +61,13 @@ class Config {
54
61
  }
55
62
  }
56
63
  }
64
+ /**
65
+ * 通用获取配置文件数据方法
66
+ * @param typeDir 配置文件目录类型对应路径 defaultConfig: defaultConfig 或 config: yunzai/data/yuki-plugin/config
67
+ * @param appDir 配置app目录
68
+ * @param functionName 配置文件名称,不包含.yaml后缀
69
+ * @returns {object} 配置数据
70
+ */
57
71
  getConfigData(typeDir, appDir, functionName) {
58
72
  const configFilePath = this.getConfigFilePath(typeDir, appDir, functionName);
59
73
  const key = `${typeDir}_${appDir}_${functionName}`;
@@ -63,6 +77,13 @@ class Config {
63
77
  this.watch(configFilePath, typeDir, appDir, functionName);
64
78
  return this[key];
65
79
  }
80
+ /**
81
+ * 获取配置文件路径
82
+ * @param typeDir 配置文件目录类型对应路径 defaultConfig: defaultConfig 或 config: yunzai/data/yuki-plugin/config
83
+ * @param appDir 配置app目录
84
+ * @param functionName 配置文件名称,不包含.yaml后缀
85
+ * @returns {string} 配置文件路径
86
+ */
66
87
  getConfigFilePath(typeDir, appDir, functionName) {
67
88
  if (typeDir === "defaultConfig") {
68
89
  return path.join(_paths.pluginPath, `${typeDir}`, `${appDir}`, `${functionName}.yaml`);
@@ -71,6 +92,13 @@ class Config {
71
92
  return path.join(_paths.botYukiData, `${typeDir}`, `${appDir}`, `${functionName}.yaml`);
72
93
  }
73
94
  }
95
+ /**
96
+ * 监听配置文件的变化
97
+ * @param configFilePath 文件路径
98
+ * @param typeDir 配置文件目录类型对应路径 defaultConfig: defaultConfig 或 config: yunzai/data/yuki-plugin/config
99
+ * @param appDir 配置app目录
100
+ * @param functionName 配置文件名称,不包含.yaml后缀
101
+ */
74
102
  watch(configFilePath, typeDir, appDir, functionName) {
75
103
  const key = `${typeDir}_${appDir}_${functionName}`;
76
104
  if (this.watcher[key])
@@ -85,14 +113,31 @@ class Config {
85
113
  });
86
114
  this.watcher[key] = watcher;
87
115
  }
116
+ /**
117
+ * 获取默认配置
118
+ * @param appDir 配置app目录
119
+ * @param functionName 配置文件名称,不包含.yaml后缀
120
+ */
88
121
  getDefaultConfig(appDir, functionName) {
89
122
  return this.getConfigData("defaultConfig", appDir, functionName);
90
123
  }
124
+ /**
125
+ * 获取用户配置
126
+ * @param appDir 配置app目录
127
+ * @param functionName 配置文件名称,不包含.yaml后缀
128
+ */
91
129
  getUserConfig(appDir, functionName) {
92
130
  const userConfigData = this.getConfigData("config", appDir, functionName);
93
131
  const defaultConfigData = this.getDefaultConfig(appDir, functionName);
94
132
  return lodash.merge({}, defaultConfigData, userConfigData);
95
133
  }
134
+ /**
135
+ * 保存配置文件
136
+ * @param typeDir 插件为起始的配置文件目录
137
+ * @param appDir 配置app目录
138
+ * @param functionName 配置文件名称,不包含.yaml后缀
139
+ * @param data 配置数据
140
+ */
96
141
  saveConfig(typeDir, appDir, functionName, data) {
97
142
  const filePath = this.getConfigFilePath(typeDir, appDir, functionName);
98
143
  if (lodash.isEmpty(data)) {
@@ -103,11 +148,19 @@ class Config {
103
148
  fs.writeFileSync(filePath, yamlContent, "utf8");
104
149
  }
105
150
  }
151
+ /**
152
+ * 更新并保存配置项
153
+ * @param appDir 配置app目录
154
+ * @param functionName 配置文件名称,不包含.yaml后缀
155
+ * @param key 配置项的键
156
+ * @param value 配置项的值
157
+ */
106
158
  updateConfigItem(appDir, functionName, key, value) {
107
159
  const config = this.getUserConfig(appDir, functionName);
108
- config[key] = value;
109
- this.saveConfig("config", appDir, functionName, config);
160
+ config[key] = value; // 更新配置项
161
+ this.saveConfig("config", appDir, functionName, config); // 保存更新后的配置
110
162
  }
163
+ /** 读取CHANGELOG.md文件,获取最新版本号*/
111
164
  getLatestVersion() {
112
165
  const content = fs.readFileSync(this.versionPath, 'utf-8');
113
166
  const versionPattern = /#\s(\d+\.\d+\.\d+)/g;
@@ -1,7 +1,18 @@
1
1
  import { Picture, ComponentCreateOpsionType } from 'react-puppeteer';
2
2
  import { ScreenshotOptions } from '@/utils/puppeteer.render';
3
3
  export declare class Image extends Picture {
4
+ /**
5
+ * 初始化运行Puppeteer
6
+ */
4
7
  constructor();
8
+ /**
9
+ * @param uid 唯一标识符
10
+ * @param page 组件名称
11
+ * @param props 传入的组件参数
12
+ * @param ComponentCreateOpsion 组件创建选项
13
+ * @param ScreenshotOptions 截图选项
14
+ * @returns {false | {img: buffer[]}}
15
+ */
5
16
  renderPage<T = any>(uid: number | string, page: string, props?: T, ScreenshotOptions?: ScreenshotOptions, ComponentCreateOpsion?: ComponentCreateOpsionType): Promise<false | {
6
17
  img: Buffer[];
7
18
  }>;
@@ -3,14 +3,28 @@ import { Component, Picture, Puppeteer } from 'react-puppeteer';
3
3
  import { YukiPuppeteerRender } from './puppeteer.render.js';
4
4
  import * as index from '../components/index.js';
5
5
 
6
+ // 初始化 组件渲染对象
6
7
  const com = new Component();
7
8
  const yukiPuppeteerRender = new YukiPuppeteerRender();
8
9
  class Image extends Picture {
10
+ /**
11
+ * 初始化运行Puppeteer
12
+ */
9
13
  constructor() {
14
+ // 继承实例
10
15
  super();
16
+ // start
11
17
  this.Pup = new Puppeteer();
12
18
  this.Pup.start();
13
19
  }
20
+ /**
21
+ * @param uid 唯一标识符
22
+ * @param page 组件名称
23
+ * @param props 传入的组件参数
24
+ * @param ComponentCreateOpsion 组件创建选项
25
+ * @param ScreenshotOptions 截图选项
26
+ * @returns {false | {img: buffer[]}}
27
+ */
14
28
  async renderPage(uid, page, props = {}, ScreenshotOptions, ComponentCreateOpsion) {
15
29
  const Page = index[page];
16
30
  return yukiPuppeteerRender.yukiScreenshot(com.compile({
@@ -21,6 +35,7 @@ class Image extends Picture {
21
35
  }), ScreenshotOptions);
22
36
  }
23
37
  }
38
+ // 初始化 图片生成对象
24
39
  var Image$1 = new Image();
25
40
 
26
41
  export { Image, Image$1 as default };
@@ -6,13 +6,13 @@ const thisFilePath = dirname(fileURLToPath(import.meta.url));
6
6
  const pluginPath = join(thisFilePath, '..', '..');
7
7
  const pluginName = basename(pluginPath);
8
8
  const _paths = {
9
- root: _path,
10
- botData: join(_path, 'data'),
11
- botYukiData: join(_path, 'data/yuki-plugin'),
12
- botTempPath: join(_path, 'temp'),
13
- pluginPath,
14
- pluginResources: join(pluginPath, 'resources'),
15
- pluginName,
9
+ root: _path, // Bot根目录
10
+ botData: join(_path, 'data'), // BotData目录
11
+ botYukiData: join(_path, 'data/yuki-plugin'), // yuki-Data目录
12
+ botTempPath: join(_path, 'temp'), // Bot缓存目录
13
+ pluginPath, // yuki-plugin根目录
14
+ pluginResources: join(pluginPath, 'resources'), // yuki-plugin资源目录
15
+ pluginName, // 插件所在文件夹名称
16
16
  };
17
17
 
18
18
  export { _paths, pluginName };
@@ -17,6 +17,21 @@ export type ScreenshotOptions = {
17
17
  saveHtmlfile?: boolean;
18
18
  };
19
19
  export declare class YukiPuppeteerRender extends Puppeteer {
20
+ /**
21
+ * 截图并返回buffer
22
+ * @param htmlPath 绝对路径
23
+ * @param tab 截图元素位 默认 body
24
+ * @param type 图片类型,默认png
25
+ * @param quality 清晰度,默认100
26
+ * @param timeout 响应检查,默认120000
27
+ * @param isSplit 是否分割图片 booelan,默认undefined,如果为undefined则截取整个页面为一张图片,如果为true则按照 pageSplitHeight 高度分割全部页面,如果为false则截取页面的第一个默认pageSplitHeight高度的页面
28
+ * @param pageSplitHeight 分割图片高度,默认 8000。
29
+ * @param pageWidth 页面宽度,默认 900
30
+ * @param addStyle 额外的 CSS 样式 示例 '.ql-editor { max-height: 100% !important; overflow-x: hidden; }'
31
+ * @param header 请求头 { [key: string]: string },示例:{ 'referer': 'https://space.bilibili.com' }
32
+ * @param modelName 调用模块名称,默认yuki-plugin
33
+ * @returns {false | {img: buffer[]}}
34
+ */
20
35
  yukiScreenshot(htmlPath: string, Options?: ScreenshotOptions): Promise<false | {
21
36
  img: Buffer[];
22
37
  }>;
@@ -3,12 +3,28 @@ import fs__default from 'fs';
3
3
  import path from 'path';
4
4
  import { _paths } from './paths.js';
5
5
 
6
+ // 该文件是 yuki-plugin 插件的截图类,继承了 Puppeteer 类,重写了 screenshot 方法,实现了截图的额外功能。
6
7
  class YukiPuppeteerRender extends Puppeteer {
8
+ /**
9
+ * 截图并返回buffer
10
+ * @param htmlPath 绝对路径
11
+ * @param tab 截图元素位 默认 body
12
+ * @param type 图片类型,默认png
13
+ * @param quality 清晰度,默认100
14
+ * @param timeout 响应检查,默认120000
15
+ * @param isSplit 是否分割图片 booelan,默认undefined,如果为undefined则截取整个页面为一张图片,如果为true则按照 pageSplitHeight 高度分割全部页面,如果为false则截取页面的第一个默认pageSplitHeight高度的页面
16
+ * @param pageSplitHeight 分割图片高度,默认 8000。
17
+ * @param pageWidth 页面宽度,默认 900
18
+ * @param addStyle 额外的 CSS 样式 示例 '.ql-editor { max-height: 100% !important; overflow-x: hidden; }'
19
+ * @param header 请求头 { [key: string]: string },示例:{ 'referer': 'https://space.bilibili.com' }
20
+ * @param modelName 调用模块名称,默认yuki-plugin
21
+ * @returns {false | {img: buffer[]}}
22
+ */
7
23
  async yukiScreenshot(htmlPath, Options) {
8
24
  if (!(await this.isStart()))
9
25
  return false;
10
26
  let name = Options?.modelName ?? 'yuki-plugin';
11
- let pageHeight = Options?.pageSplitHeight ?? 8000;
27
+ let pageHeight = Options?.pageSplitHeight ?? 8000; // 分割图片高度,默认 8000
12
28
  try {
13
29
  const page = await this.browser?.newPage().catch(err => {
14
30
  logger.error(err);
@@ -19,6 +35,7 @@ class YukiPuppeteerRender extends Puppeteer {
19
35
  width: Options?.pageWidth ?? 900,
20
36
  height: 7500
21
37
  });
38
+ // 设置请求 Header
22
39
  if (Options?.header) {
23
40
  await page.setExtraHTTPHeaders(Options.header);
24
41
  }
@@ -26,21 +43,24 @@ class YukiPuppeteerRender extends Puppeteer {
26
43
  const element = await page.$(Options?.tab ?? 'body');
27
44
  if (!element)
28
45
  return false;
29
- const boundingBox = await element.boundingBox();
30
- const num = Options?.isSplit ? Math.ceil(boundingBox.height / pageHeight) : 1;
31
- pageHeight = Math.round(boundingBox.height / num);
46
+ const boundingBox = await element.boundingBox(); // 获取内容区域的边界框信息
47
+ const num = Options?.isSplit ? Math.ceil(boundingBox.height / pageHeight) : 1; // 根据是否需要分片,计算分片数量,默认为 1
48
+ pageHeight = Math.round(boundingBox.height / num); //动态调整分片高度,防止过短影响观感。
32
49
  await page.setViewport({
33
50
  width: boundingBox.width + 50,
34
51
  height: pageHeight + 100
35
52
  });
53
+ // 根据 style 的值来修改 CSS 样式
36
54
  if (Options?.addStyle) {
37
55
  await page.addStyleTag({
38
56
  content: Options.addStyle,
39
57
  });
40
58
  }
59
+ // 禁止 GIF 动图播放
41
60
  await page.addStyleTag({
42
61
  content: `img[src$=".gif"] {animation-play-state: paused !important;}`
43
62
  });
63
+ // 是否保存 html 文件
44
64
  if (Options?.saveHtmlfile === true) {
45
65
  const htmlContent = await page.content();
46
66
  const Dir = path.join(_paths.root, `/temp/html/yuki-plugin/${name}/`);
@@ -57,30 +77,31 @@ class YukiPuppeteerRender extends Puppeteer {
57
77
  for (let i = 1; i <= num; i++) {
58
78
  if (i > 1) {
59
79
  await page.evaluate(pageHeight => {
60
- window.scrollBy(0, pageHeight);
80
+ window.scrollBy(0, pageHeight); // 在页面上下文中执行滚动操作
61
81
  }, pageHeight);
62
- await new Promise((resolve) => setTimeout(resolve, 500));
82
+ await new Promise((resolve) => setTimeout(resolve, 500)); // 等待一段时间,确保页面加载完成
63
83
  }
64
84
  let renderOptions = Options?.SOptions ?? { type: 'png' };
65
85
  const screenshotOptions = {
66
86
  ...renderOptions,
67
87
  clip: {
68
88
  x: 0,
69
- y: pageHeight * (i - 1),
70
- width: Math.round(boundingBox.width),
71
- height: Math.min(pageHeight, boundingBox.height - pageHeight * (i - 1)),
89
+ y: pageHeight * (i - 1), // 根据分片序号计算截图区域的起始位置
90
+ width: Math.round(boundingBox.width), // 截图区域的宽度与内容区域宽度一致
91
+ height: Math.min(pageHeight, boundingBox.height - pageHeight * (i - 1)), // 截图区域的高度取决于内容区域剩余的高度或者默认的分片高度
72
92
  },
73
93
  };
74
94
  buff = await element.screenshot(screenshotOptions).catch(err => {
75
95
  logger.error('[puppeteer]', 'screenshot', err);
76
96
  return false;
77
- });
78
- numSun++;
97
+ }); // 对指定区域进行截图
98
+ numSun++; // 增加截图次数
79
99
  if (buff !== false) {
80
100
  let imgBuff = !Buffer.isBuffer(buff) ? Buffer.from(buff) : buff;
81
- const kb = (imgBuff?.length / 1024).toFixed(2) + "kb";
82
- logger.mark(`[图片生成][${name}][${numSun}次] ${kb} ${logger.green(`${Date.now() - start}ms`)}`);
83
- ret.push(imgBuff);
101
+ /** 计算图片大小 */
102
+ const kb = (imgBuff?.length / 1024).toFixed(2) + "kb"; // 计算图片大小
103
+ logger.mark(`[图片生成][${name}][${numSun}次] ${kb} ${logger.green(`${Date.now() - start}ms`)}`); // 记录日志
104
+ ret.push(imgBuff); // 将截图结果添加到数组中
84
105
  }
85
106
  else {
86
107
  logger.error(`[puppeteer]`, '截图失败');
@@ -90,8 +111,9 @@ class YukiPuppeteerRender extends Puppeteer {
90
111
  logger.error(`[图片生成][${name}] 图片生成为空`);
91
112
  return false;
92
113
  }
114
+ // 关闭页面
93
115
  await page.close().catch(err => logger.error(err));
94
- return { img: ret };
116
+ return { img: ret }; // 返回图像数组
95
117
  }
96
118
  catch (err) {
97
119
  logger.error('[puppeteer] newPage', err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yz-yuki-plugin",
3
- "version": "2.0.1",
3
+ "version": "2.0.2-1",
4
4
  "description": "优纪插件,yunzaijs 关于 微博推送、B站推送 等功能的拓展插件",
5
5
  "author": "snowtafir",
6
6
  "type": "module",
@@ -17,7 +17,8 @@
17
17
  "css-app": "tailwindcss -i ./src/input.css -o ./public/output.css",
18
18
  "css-dev": "tailwindcss -i ./src/input.css -o ./public/output.css --watch",
19
19
  "css-m": "tailwindcss -i ./src/input.css -o ./public/output.css -m",
20
- "format": "prettier --write ."
20
+ "format": "prettier --write .",
21
+ "check-format": "git diff --exit-code"
21
22
  },
22
23
  "dependencies": {
23
24
  "axios": "^1.7.3",
@@ -33,7 +34,7 @@
33
34
  "qrcode": "^1.5.4",
34
35
  "react": "^18.3.1",
35
36
  "react-dom": "^18.3.1",
36
- "react-puppeteer": "1.0.3",
37
+ "react-puppeteer": "^1.0.3",
37
38
  "redis": "^4.7.0",
38
39
  "yaml": "^2.5.0",
39
40
  "yarn": "^1.19.1"
@@ -84,9 +85,9 @@
84
85
  "rollup-plugin-ignore": "^1.0.10",
85
86
  "tailwindcss": "^3.4.9",
86
87
  "ts-node": "^10.9.2",
87
- "tsx": "^4.18.0",
88
+ "tsx": "^4.19.0",
88
89
  "typescript": "^5.5.4",
89
- "yunzai": "^1.0.6",
90
+ "yunzai": "^1.1.3",
90
91
  "yunzai-mys": "^1.0.5"
91
92
  },
92
93
  "files": [