koishi-plugin-oni-sync-bot 0.7.0 → 0.7.2

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.
package/lib/index.js CHANGED
@@ -36,6 +36,7 @@ __export(src_exports, {
36
36
  });
37
37
  module.exports = __toCommonJS(src_exports);
38
38
  var import_koishi11 = require("koishi");
39
+ var import_path = require("path");
39
40
 
40
41
  // src/services/wikiBotService.ts
41
42
  var import_koishi2 = require("koishi");
@@ -275,23 +276,117 @@ var WikiBotService = class _WikiBotService extends import_koishi2.Service {
275
276
  }
276
277
  return { gg: ggSuccess, bwiki: bwikiSuccess };
277
278
  }
279
+ async reloginSite(site) {
280
+ const sitesConfig = this.getSitesConfig();
281
+ const siteConfig = site === "gg" ? sitesConfig.gg : sitesConfig.bwiki;
282
+ try {
283
+ const bot = await this.loginWithRetry(siteConfig);
284
+ if (site === "gg") {
285
+ this.ggbot = bot;
286
+ } else {
287
+ this.bwikibot = bot;
288
+ }
289
+ logger.info(`✅ ${siteConfig.name} 自动重新登录成功`);
290
+ } catch (error) {
291
+ const errorMsg = getErrorMessage(error);
292
+ if (site === "gg") {
293
+ this.ggbot = null;
294
+ } else {
295
+ this.bwikibot = null;
296
+ }
297
+ logger.error(`❌ ${siteConfig.name} 自动重新登录失败`, errorMsg);
298
+ throw error;
299
+ }
300
+ }
278
301
  isGGBotReady() {
279
302
  return this.ggbot !== null;
280
303
  }
281
304
  isBWikiBotReady() {
282
305
  return this.bwikibot !== null;
283
306
  }
307
+ createBotProxy(bot, site) {
308
+ const self = this;
309
+ const METHODS_TO_SKIP = /* @__PURE__ */ new Set([
310
+ "cookieJar",
311
+ "setRequestOptions"
312
+ ]);
313
+ return new Proxy(bot, {
314
+ get(target, prop) {
315
+ const originalMethod = target[prop];
316
+ if (typeof originalMethod !== "function") {
317
+ return originalMethod;
318
+ }
319
+ if (METHODS_TO_SKIP.has(prop)) {
320
+ return originalMethod.bind(target);
321
+ }
322
+ if (prop === "continuedQueryGen") {
323
+ return function(...args) {
324
+ const originalGen = originalMethod.apply(target, args);
325
+ return {
326
+ [Symbol.asyncIterator]() {
327
+ const it = originalGen[Symbol.asyncIterator]();
328
+ return {
329
+ async next() {
330
+ try {
331
+ return await it.next();
332
+ } catch (error) {
333
+ if (error.code === "assertuserfailed") {
334
+ logger.warn(
335
+ `检测到 ${site === "gg" ? "WIKIGG" : "bwiki"} 登录过期,正在自动重新登录...`
336
+ );
337
+ await self.reloginSite(site);
338
+ const newBot = site === "gg" ? self.ggbot : self.bwikibot;
339
+ if (!newBot) {
340
+ throw new Error(
341
+ `${site === "gg" ? "WIKIGG" : "bwiki"} 自动重新登录失败`
342
+ );
343
+ }
344
+ const newGen = newBot.continuedQueryGen(...args);
345
+ const newIt = newGen[Symbol.asyncIterator]();
346
+ return await newIt.next();
347
+ }
348
+ throw error;
349
+ }
350
+ }
351
+ };
352
+ }
353
+ };
354
+ };
355
+ }
356
+ return async function(...args) {
357
+ try {
358
+ return await originalMethod.apply(target, args);
359
+ } catch (error) {
360
+ if (error.code === "assertuserfailed") {
361
+ logger.warn(
362
+ `检测到 ${site === "gg" ? "WIKIGG" : "bwiki"} 登录过期,正在自动重新登录...`
363
+ );
364
+ await self.reloginSite(site);
365
+ const newBot = site === "gg" ? self.ggbot : self.bwikibot;
366
+ if (!newBot) {
367
+ throw new Error(
368
+ `${site === "gg" ? "WIKIGG" : "bwiki"} 自动重新登录失败`
369
+ );
370
+ }
371
+ return await newBot[prop].apply(newBot, args);
372
+ }
373
+ throw error;
374
+ }
375
+ };
376
+ }
377
+ });
378
+ }
284
379
  getGGBot() {
285
380
  if (!this.ggbot) {
286
381
  throw new Error("WIKIGG bot 尚未就绪,请检查登录配置或查看日志");
287
382
  }
288
- return this.ggbot;
383
+ return this.createBotProxy(this.ggbot, "gg");
289
384
  }
290
385
  getBWikiBot() {
291
386
  if (!this.bwikibot) {
292
387
  throw new Error("bwiki bot 尚未就绪,请检查登录配置或查看日志");
293
388
  }
294
- return this.bwikibot;
389
+ return this.createBotProxy(this.bwikibot, "bwiki");
295
390
  }
296
391
  };
297
392
  ((WikiBotService2) => {
@@ -306,7 +401,6 @@ var WikiBotService = class _WikiBotService extends import_koishi2.Service {
306
401
  // src/plugins/consoleLogProvider.ts
307
402
  var import_koishi3 = require("koishi");
308
403
  var import_plugin_console = require("@koishijs/plugin-console");
309
- var import_path = require("path");
310
404
  var logBuffer = [];
311
405
  var PublicLogProvider = class extends import_plugin_console.DataService {
312
406
  static {
@@ -325,10 +419,6 @@ var ConsoleLogProvider = class {
325
419
  }
326
420
  static inject = ["console"];
327
421
  constructor(ctx) {
328
- ctx.console.addEntry({
329
- dev: (0, import_path.resolve)(__dirname, "../../client/index.ts"),
330
- prod: (0, import_path.resolve)(__dirname, "../../dist")
331
- });
332
422
  ctx.plugin(PublicLogProvider);
333
423
  const target = {
334
424
  colors: 0,
@@ -1591,6 +1681,12 @@ function apply(ctx, config) {
1591
1681
  ctx.plugin(SyncCommands, config);
1592
1682
  ctx.plugin(QueryCommands, config);
1593
1683
  ctx.plugin(UpdateCommands, config);
1684
+ ctx.inject(["console"], (ctx2) => {
1685
+ ctx2.console.addEntry({
1686
+ dev: (0, import_path.resolve)(__dirname, "../client/index.ts"),
1687
+ prod: (0, import_path.resolve)(__dirname, "../dist")
1688
+ });
1689
+ });
1594
1690
  }
1595
1691
  __name(apply, "apply");
1596
1692
  // Annotate the CommonJS export names for ESM import in node:
@@ -32,8 +32,10 @@ export declare class WikiBotService extends Service {
32
32
  gg: boolean;
33
33
  bwiki: boolean;
34
34
  }>;
35
+ private reloginSite;
35
36
  isGGBotReady(): boolean;
36
37
  isBWikiBotReady(): boolean;
38
+ private createBotProxy;
37
39
  getGGBot(): Mwn;
38
40
  getBWikiBot(): Mwn;
39
41
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-oni-sync-bot",
3
3
  "description": "缺氧Wiki站镜像点同步-测试",
4
- "version": "0.7.0",
4
+ "version": "0.7.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -1,5 +1,157 @@
1
1
  # koishi-plugin-oni-sync-bot
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/koishi-plugin-oni-sync-bot?style=flat-square)](https://www.npmjs.com/package/koishi-plugin-oni-sync-bot)
4
+ [![Koishi](https://img.shields.io/badge/koishi-plugin-42b983?style=flat-square)](https://koishi.chat)
4
5
 
5
- 缺氧Wiki站镜像点同步-测试
6
+ 缺氧 Wiki 站镜像点同步插件 - 自动同步两个缺氧 Wiki 站点的内容。
7
+
8
+ ## 功能特性
9
+
10
+ - 🚀 **自动登录** - 支持 WIKIGG 和 bwiki 双站点登录
11
+ - 🔄 **自动重连** - 登录过期时自动重新登录并重试
12
+ - 📄 **页面同步** - 单个页面同步到目标站点
13
+ - 📦 **模块同步** - 批量同步指定前缀的页面
14
+ - 🖼️ **图片同步** - 同步页面引用的图片文件
15
+ - 🔍 **页面查询** - 查询页面历史版本和当前版本
16
+ - 📊 **日志控制台** - 可视化日志查看和管理
17
+ - ⚡ **增量更新** - 定时检测并同步最近修改的内容
18
+
19
+ ## 安装
20
+
21
+ ```bash
22
+ npm install koishi-plugin-oni-sync-bot
23
+ # 或
24
+ yarn add koishi-plugin-oni-sync-bot
25
+ ```
26
+
27
+ ## 配置
28
+
29
+ 在 Koishi 控制台中配置以下参数:
30
+
31
+ | 参数 | 说明 | 默认值 |
32
+ | --------------- | ------------- | ------ |
33
+ | `ggUsername` | WIKIGG 用户名 | 1 |
34
+ | `ggPassword` | WIKIGG 密码 | 1 |
35
+ | `bwikiusername` | bwiki 用户名 | 1 |
36
+ | `bwikipassword` | bwiki 密码 | 1 |
37
+
38
+ ## 命令列表
39
+
40
+ ### 同步命令
41
+
42
+ | 命令 | 说明 |
43
+ | -------------------- | ---------------------- |
44
+ | `sync.page <标题>` | 同步单个页面到 bwiki |
45
+ | `sync.gg <标题>` | 同步单个页面到 WIKIGG |
46
+ | `sync.module <前缀>` | 同步指定前缀的所有页面 |
47
+ | `sync.img <标题>` | 同步页面引用的图片 |
48
+
49
+ ### 管理命令
50
+
51
+ | 命令 | 说明 |
52
+ | --------- | ---------------------- |
53
+ | `relogin` | 手动重新登录两个机器人 |
54
+
55
+ ## 使用示例
56
+
57
+ ### 同步单个页面
58
+
59
+ ```
60
+ /sync.page 缺氧
61
+ ```
62
+
63
+ ### 同步模块
64
+
65
+ ```
66
+ /sync.module 缺氧:
67
+ ```
68
+
69
+ ### 同步图片
70
+
71
+ ```
72
+ /sync.img 电解器.png
73
+ ```
74
+
75
+ ### 手动重新登录
76
+
77
+ ```
78
+ /relogin
79
+ ```
80
+
81
+ ## 控制台功能
82
+
83
+ 插件提供了可视化的控制台界面:
84
+
85
+ - 📋 **日志查看** - 按级别(全部/信息/警告/错误)筛选日志
86
+ - 🔍 **搜索功能** - 快速搜索日志内容
87
+ - ⏬ **自动滚动** - 新日志自动滚动到底部
88
+ - 🎯 **一键滚动** - 手动跳转到顶部或底部
89
+
90
+ ## 技术特性
91
+
92
+ - ✅ **TypeScript** - 完整的类型支持
93
+ - 🎯 **面向对象** - 基于类的插件架构
94
+ - 🔌 **服务化设计** - 核心功能封装为独立服务
95
+ - 🧩 **模块化** - 功能拆分为独立子插件
96
+ - 🔄 **自动重试** - 登录失败自动重试
97
+ - 🔐 **自动重连** - 登录过期自动重新登录
98
+
99
+ ## 项目结构
100
+
101
+ ```
102
+ koishi-plugin-oni-sync-bot/
103
+ ├── src/
104
+ │ ├── services/ # 服务层
105
+ │ │ └── wikiBotService.ts # Wiki 机器人服务
106
+ │ ├── plugins/ # 插件层
107
+ │ │ ├── command.ts # 基础命令插件
108
+ │ │ ├── queryCommands.ts # 查询命令插件
109
+ │ │ ├── syncCommands.ts # 同步命令插件
110
+ │ │ ├── updateCommands.ts # 更新命令插件
111
+ │ │ └── consoleLogProvider.ts # 日志控制台插件
112
+ │ ├── sync/ # 同步逻辑
113
+ │ │ ├── pageSync.ts # 页面同步
114
+ │ │ ├── moduleSync.ts # 模块同步
115
+ │ │ └── imgSync.ts # 图片同步
116
+ │ ├── utils/ # 工具函数
117
+ │ │ └── tools.ts # 通用工具
118
+ │ ├── config/ # 配置
119
+ │ │ └── index.ts # 配置定义
120
+ │ ├── client/ # 前端
121
+ │ │ ├── page.vue # 日志页面
122
+ │ │ └── index.ts # 入口
123
+ │ └── index.ts # 主入口
124
+ ├── package.json
125
+ └── tsconfig.json
126
+ ```
127
+
128
+ ## 开发
129
+
130
+ ```bash
131
+ # 创建KOISHI项目
132
+ yarn create koishi
133
+
134
+ # 克隆项目
135
+ git clone <repository-url>
136
+
137
+ # 安装依赖
138
+ yarn install
139
+
140
+ # 构建
141
+ yarn build
142
+
143
+ # 开发模式
144
+ yarn dev
145
+ ```
146
+
147
+ ## License
148
+
149
+ MIT License
150
+
151
+ ## 贡献
152
+
153
+ 欢迎提交 Issue 和 Pull Request!
154
+
155
+ ## 支持
156
+
157
+ 如有问题,请在 GitHub 上提交 Issue。