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 +103 -7
- package/lib/services/wikiBotService.d.ts +2 -0
- package/package.json +1 -1
- package/readme.md +153 -1
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
package/readme.md
CHANGED
|
@@ -1,5 +1,157 @@
|
|
|
1
1
|
# koishi-plugin-oni-sync-bot
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/koishi-plugin-oni-sync-bot)
|
|
4
|
+
[](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。
|