koishi-plugin-oni-sync-bot 0.4.1 → 0.6.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.
@@ -0,0 +1,14 @@
1
+ import { Config } from "../index";
2
+ export interface ISiteConfig {
3
+ name: string;
4
+ api: string;
5
+ username: string;
6
+ password: string;
7
+ userAgent: string;
8
+ }
9
+ interface ISitesConfig {
10
+ gg: ISiteConfig;
11
+ bwiki: ISiteConfig;
12
+ }
13
+ export declare function getSitesConfig(config: Config): ISitesConfig;
14
+ export {};
package/lib/index.d.ts CHANGED
@@ -1,7 +1,33 @@
1
- import { Context, Schema } from "koishi";
1
+ import { Context, Logger, Schema } from "koishi";
2
2
  export declare const name = "oni-sync-bot";
3
3
  export declare const inject: string[];
4
+ declare module "@koishijs/console" {
5
+ namespace Console {
6
+ interface Services {
7
+ onilogs: DataService<Logger.Record[]>;
8
+ }
9
+ }
10
+ }
11
+ declare module "koishi" {
12
+ interface Tables {
13
+ wikipages: WikiPages;
14
+ }
15
+ }
16
+ export interface WikiPages {
17
+ id: number;
18
+ title: string;
19
+ pinyin_full: string;
20
+ pinyin_first: string;
21
+ }
4
22
  export interface Config {
23
+ ggUsername: string;
24
+ ggPassword: string;
25
+ bwikiusername: string;
26
+ bwikipassword: string;
27
+ domain: string;
28
+ main_site: string;
29
+ bwiki_site: string;
30
+ logsUrl: string;
5
31
  }
6
32
  export declare const Config: Schema<Config>;
7
33
  export declare function apply(ctx: Context, config: Config): void;
package/lib/index.js CHANGED
@@ -30,17 +30,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- Config: () => Config6,
34
- apply: () => apply5,
33
+ Config: () => Config,
34
+ apply: () => apply,
35
35
  inject: () => inject,
36
36
  name: () => name
37
37
  });
38
38
  module.exports = __toCommonJS(src_exports);
39
- var import_koishi10 = require("koishi");
39
+ var import_koishi5 = require("koishi");
40
40
  var import_path = require("path");
41
+ var import_plugin_console = require("@koishijs/plugin-console");
41
42
 
42
- // src/wiki/wikicore.ts
43
- var import_koishi2 = require("koishi");
43
+ // src/utils/login.ts
44
44
  var import_mwn = require("mwn");
45
45
 
46
46
  // src/utils/tools.ts
@@ -90,28 +90,7 @@ function generatePinyinInfo(text) {
90
90
  __name(generatePinyinInfo, "generatePinyinInfo");
91
91
  var logger = new import_koishi.Logger("oni-sync");
92
92
 
93
- // src/wiki/wikicore.ts
94
- var Config = import_koishi2.Schema.object({
95
- ggUsername: import_koishi2.Schema.string().description("WIKIGG 用户名").default("1"),
96
- ggPassword: import_koishi2.Schema.string().description("WIKIGG 密码").default("1"),
97
- bwikiusername: import_koishi2.Schema.string().description("bwiki用户名").default("1"),
98
- bwikipassword: import_koishi2.Schema.string().description("bwiki密码").default("1"),
99
- domain: import_koishi2.Schema.string().description("你的短链域名(必填,如:klei.vip)").default("klei.vip"),
100
- logsUrl: import_koishi2.Schema.string().description("日志查看地址").default("https://klei.vip/onilogs")
101
- });
102
- function apply(ctx, config) {
103
- const sitesConfig = getSitesConfig(config);
104
- ctx.on("ready", async () => {
105
- const wikiggBot = await login(sitesConfig.gg);
106
- const bwikiBot = await login(sitesConfig.bwiki);
107
- ctx.wikibot = { wikigg: wikiggBot, bwiki: bwikiBot };
108
- });
109
- ctx.on("dispose", () => {
110
- logger.warn("⚠️ 插件已卸载,ctx.wikibot清除...");
111
- ctx.wikibot = void 0;
112
- });
113
- }
114
- __name(apply, "apply");
93
+ // src/utils/login.ts
115
94
  async function login(siteConfig) {
116
95
  const bot = new import_mwn.Mwn({
117
96
  apiUrl: siteConfig.api,
@@ -138,6 +117,8 @@ async function login(siteConfig) {
138
117
  return bot;
139
118
  }
140
119
  __name(login, "login");
120
+
121
+ // src/config/index.ts
141
122
  var userAgent = `OniSyncBot/1.0 (https://klei.vip; Charles@klei.vip)`;
142
123
  function getSitesConfig(config) {
143
124
  return {
@@ -159,85 +140,11 @@ function getSitesConfig(config) {
159
140
  }
160
141
  __name(getSitesConfig, "getSitesConfig");
161
142
 
162
- // src/service/logspush.ts
163
- var import_plugin_console = require("@koishijs/plugin-console");
164
- var import_koishi3 = require("koishi");
165
- var Config2 = import_koishi3.Schema.object({
166
- logsUrl: import_koishi3.Schema.string().description("日志查看地址").default("https://klei.vip/onilogs")
167
- });
168
- var logBuffer = [];
169
- var PublicLogProvider = class extends import_plugin_console.DataService {
170
- static {
171
- __name(this, "PublicLogProvider");
172
- }
173
- constructor(ctx) {
174
- super(ctx, "onilogs", { authority: 0 });
175
- }
176
- async get() {
177
- return logBuffer;
178
- }
179
- };
180
- function apply2(ctx, config) {
181
- ctx.plugin(PublicLogProvider);
182
- const target = {
183
- colors: 0,
184
- record: /* @__PURE__ */ __name((record) => {
185
- if (record.name !== "oni-sync") return;
186
- logBuffer.push(record);
187
- if (logBuffer.length > 30) {
188
- logBuffer = logBuffer.slice(-30);
189
- }
190
- ctx.get("console")?.patch("onilogs", logBuffer);
191
- }, "record")
192
- };
193
- import_koishi3.Logger.targets.push(target);
194
- ctx.on("dispose", () => {
195
- const index = import_koishi3.Logger.targets.indexOf(target);
196
- if (index > -1) import_koishi3.Logger.targets.splice(index, 1);
197
- });
198
- }
199
- __name(apply2, "apply");
200
-
201
- // src/service/router.ts
202
- var import_koishi4 = require("koishi");
203
- var Config3 = import_koishi4.Schema.object({
204
- main_site: import_koishi4.Schema.string().description("主站域名(必填,如:oxygennotincluded.wiki.gg)").default("oxygennotincluded.wiki.gg/zh"),
205
- bwiki_site: import_koishi4.Schema.string().description("镜像站域名(必填,如:wiki.biligame.com)").default("wiki.biligame.com/oni")
206
- });
207
- function apply3(ctx, config) {
208
- ctx.server.get("/gg/:id", async (router) => {
209
- const pageId = Number(router.params.id);
210
- if (isNaN(pageId)) return router.body = "❌ 无效的页面ID,必须为数字!";
211
- const [page] = await ctx.database.get("wikipages", { id: pageId });
212
- if (!page)
213
- return router.body = `❌ 未找到ID为【${pageId}】的页面,请联系管理员更新缓存!`;
214
- const targetUrl = `https://${config.main_site}/${encodeURIComponent(
215
- page.title
216
- )}?variant=zh`;
217
- router.redirect(targetUrl);
218
- });
219
- ctx.server.get("/bw/:id", async (router) => {
220
- const pageId = Number(router.params.id);
221
- if (isNaN(pageId)) return router.body = "❌ 无效的页面ID,必须为数字!";
222
- const [page] = await ctx.database.get("wikipages", { id: pageId });
223
- if (!page)
224
- return router.body = `❌ 未找到ID为【${pageId}】的页面,请联系管理员更新缓存!`;
225
- const targetUrl = `https://${config.bwiki_site}/${encodeURIComponent(
226
- page.title
227
- )}`;
228
- router.redirect(targetUrl);
229
- });
230
- }
231
- __name(apply3, "apply");
232
-
233
- // src/task/sync.ts
234
- var import_koishi8 = require("koishi");
235
-
236
143
  // src/sync/pageSync.ts
237
- var import_koishi6 = require("koishi");
144
+ var import_koishi3 = require("koishi");
238
145
 
239
146
  // src/sync/imgSync.ts
240
- var import_koishi5 = require("koishi");
147
+ var import_koishi2 = require("koishi");
241
148
  var import_node_fetch = __toESM(require("node-fetch"));
242
149
  var import_form_data = __toESM(require("form-data"));
243
150
  var CONFIG = {
@@ -272,7 +179,7 @@ async function getImageInfo(site, fileName) {
272
179
  }
273
180
  }
274
181
  __name(getImageInfo, "getImageInfo");
275
- async function syncSingleImage(sourceBot, targetBot, fileName) {
182
+ async function syncSingleImage(sourceBot, targetBot, fileName, config) {
276
183
  if (CONFIG.IGNORED_IMAGES.includes(fileName)) {
277
184
  logger.info(`[SyncImg] 🚫 图片 ${fileName} 在忽略列表,跳过`);
278
185
  return { success: true, reason: "ignored" };
@@ -366,7 +273,7 @@ async function getAllImages(site) {
366
273
  return allImages;
367
274
  }
368
275
  __name(getAllImages, "getAllImages");
369
- async function syncAllImages(sourceBot, targetBot) {
276
+ async function syncAllImages(sourceBot, targetBot, config) {
370
277
  try {
371
278
  const imageList = await getAllImages(sourceBot);
372
279
  if (imageList.length === 0) {
@@ -387,17 +294,22 @@ async function syncAllImages(sourceBot, targetBot) {
387
294
  `
388
295
  [SyncAllImg] 📈 进度 ${i + 1}/${imageList.length} (${progress.toFixed(1)}%)`
389
296
  );
390
- const result = await syncSingleImage(sourceBot, targetBot, fileName);
297
+ const result = await syncSingleImage(
298
+ sourceBot,
299
+ targetBot,
300
+ fileName,
301
+ config
302
+ );
391
303
  if (!result.success) {
392
304
  failCount++;
393
305
  failedImages.push(fileName);
394
- await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_FAILED);
306
+ await (0, import_koishi2.sleep)(CONFIG.SYNC_INTERVAL_FAILED);
395
307
  } else {
396
308
  successCount++;
397
309
  if (result.reason === "ignored" || result.reason === "no_change") {
398
310
  skipCount++;
399
311
  }
400
- await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
312
+ await (0, import_koishi2.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
401
313
  }
402
314
  }
403
315
  if (failedImages.length > 0) {
@@ -409,7 +321,12 @@ async function syncAllImages(sourceBot, targetBot) {
409
321
  for (const fileName of failedImages) {
410
322
  logger.info(`
411
323
  [SyncAllImg] 🔁 重试: ${fileName}`);
412
- const result = await syncSingleImage(sourceBot, targetBot, fileName);
324
+ const result = await syncSingleImage(
325
+ sourceBot,
326
+ targetBot,
327
+ fileName,
328
+ config
329
+ );
413
330
  if (result.success) {
414
331
  successCount++;
415
332
  failCount--;
@@ -418,7 +335,7 @@ async function syncAllImages(sourceBot, targetBot) {
418
335
  stillFailed.push(fileName);
419
336
  logger.info(`[SyncAllImg] ❌ 重试失败: ${fileName}`);
420
337
  }
421
- await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
338
+ await (0, import_koishi2.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
422
339
  }
423
340
  if (stillFailed.length > 0) {
424
341
  logger.info(`
@@ -505,13 +422,13 @@ async function processPageWithStats(oldSite, newSite, pageTitle, user, stats, fa
505
422
  if (!syncResult.success) {
506
423
  stats.failCount++;
507
424
  failedPages.push(pageTitle);
508
- await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
425
+ await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
509
426
  } else {
510
427
  stats.successCount++;
511
428
  if (syncResult.reason === "ignored" || syncResult.reason === "no_change") {
512
429
  stats.skipCount++;
513
430
  }
514
- await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
431
+ await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
515
432
  }
516
433
  }
517
434
  __name(processPageWithStats, "processPageWithStats");
@@ -587,11 +504,11 @@ async function syncPages(oldSite, newSite) {
587
504
  stats.skipCount++;
588
505
  }
589
506
  logger.info(`[SyncAllPages] ✅ 页面 ${pageTitle} 重试成功`);
590
- await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
507
+ await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
591
508
  } else {
592
509
  stillFailed.push(pageTitle);
593
510
  logger.info(`[SyncAllPages] ❌ 页面 ${pageTitle} 再次失败`);
594
- await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
511
+ await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
595
512
  }
596
513
  }
597
514
  }
@@ -608,7 +525,7 @@ async function syncPages(oldSite, newSite) {
608
525
  }
609
526
  }
610
527
  __name(syncPages, "syncPages");
611
- async function incrementalUpdate(oldSite, newSite) {
528
+ async function incrementalUpdate(oldSite, newSite, config) {
612
529
  try {
613
530
  const now = /* @__PURE__ */ new Date();
614
531
  const threeHoursAgo = new Date(now.getTime() - 3 * 60 * 60 * 1e3);
@@ -651,7 +568,7 @@ async function incrementalUpdate(oldSite, newSite) {
651
568
  logger.info(
652
569
  `[增量更新流程] 🖼️ 检查到图片: ${title},正在尝试转存`
653
570
  );
654
- await syncSingleImage(oldSite, newSite, fileName);
571
+ await syncSingleImage(oldSite, newSite, fileName, config);
655
572
  } else {
656
573
  await syncSinglePage(
657
574
  oldSite,
@@ -660,11 +577,11 @@ async function incrementalUpdate(oldSite, newSite) {
660
577
  CONFIG2.INCREMENTAL_USER
661
578
  );
662
579
  }
663
- await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
580
+ await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
664
581
  } catch (error) {
665
582
  const errMsg = error instanceof Error ? error.message : String(error);
666
583
  logger.error(`[增量更新流程] ❌ 处理 ${title} 时出错:`, errMsg);
667
- await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
584
+ await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
668
585
  }
669
586
  }
670
587
  }
@@ -679,7 +596,7 @@ async function incrementalUpdate(oldSite, newSite) {
679
596
  __name(incrementalUpdate, "incrementalUpdate");
680
597
 
681
598
  // src/sync/moduleSync.ts
682
- var import_koishi7 = require("koishi");
599
+ var import_koishi4 = require("koishi");
683
600
  var CONFIG3 = {
684
601
  MODLE_NAMESPACE: 828,
685
602
  // 模块命名空间 (注意:这里原代码拼写为 MODLE,保留原样)
@@ -783,13 +700,13 @@ async function syncModules(oldSite, newSite) {
783
700
  if (!syncResult.success) {
784
701
  failCount++;
785
702
  failedModules.push(moduleTitle);
786
- await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
703
+ await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
787
704
  } else {
788
705
  successCount++;
789
706
  if (syncResult.reason === "ignored" || syncResult.reason === "no_change") {
790
707
  skipCount++;
791
708
  }
792
- await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
709
+ await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
793
710
  }
794
711
  }
795
712
  if (failedModules.length > 0) {
@@ -814,11 +731,11 @@ async function syncModules(oldSite, newSite) {
814
731
  skipCount++;
815
732
  }
816
733
  logger.info(`[SyncAllModules] ✅ 模块 ${moduleTitle} 重试成功`);
817
- await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
734
+ await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
818
735
  } else {
819
736
  stillFailed.push(moduleTitle);
820
737
  logger.info(`[SyncAllModules] ❌ 模块 ${moduleTitle} 再次失败`);
821
- await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
738
+ await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
822
739
  }
823
740
  }
824
741
  logger.info(`
@@ -844,41 +761,135 @@ async function syncModules(oldSite, newSite) {
844
761
  }
845
762
  __name(syncModules, "syncModules");
846
763
 
847
- // src/task/sync.ts
848
- var Config4 = import_koishi8.Schema.object({
849
- logsUrl: import_koishi8.Schema.string().description("日志查看地址").default("https://klei.vip/onilogs")
764
+ // src/index.ts
765
+ var name = "oni-sync-bot";
766
+ var inject = ["console", "database", "server", "cron"];
767
+ var logBuffer = [];
768
+ var Config = import_koishi5.Schema.object({
769
+ ggUsername: import_koishi5.Schema.string().description("WIKIGG 用户名").default("1"),
770
+ ggPassword: import_koishi5.Schema.string().description("WIKIGG 密码").default("1"),
771
+ bwikiusername: import_koishi5.Schema.string().description("bwiki用户名").default("1"),
772
+ bwikipassword: import_koishi5.Schema.string().description("bwiki密码").default("1"),
773
+ domain: import_koishi5.Schema.string().description("你的短链域名(必填,如:klei.vip)").default("klei.vip"),
774
+ main_site: import_koishi5.Schema.string().description("主站域名(必填,如:oxygennotincluded.wiki.gg)").default("oxygennotincluded.wiki.gg/zh"),
775
+ bwiki_site: import_koishi5.Schema.string().description("镜像站域名(必填,如:wiki.biligame.com)").default("wiki.biligame.com/oni"),
776
+ logsUrl: import_koishi5.Schema.string().description("日志查看地址").default("https://klei.vip/onilogs")
850
777
  });
851
- function apply4(ctx, config) {
852
- const log = ctx.logger("sync-task");
778
+ var PublicLogProvider = class extends import_plugin_console.DataService {
779
+ static {
780
+ __name(this, "PublicLogProvider");
781
+ }
782
+ constructor(ctx) {
783
+ super(ctx, "onilogs", { authority: 0 });
784
+ }
785
+ async get() {
786
+ return logBuffer;
787
+ }
788
+ };
789
+ function apply(ctx, config) {
790
+ const log = ctx.logger("oni-sync");
791
+ let ggbot;
792
+ let bwikibot;
793
+ ctx.inject(["console"], (ctx2) => {
794
+ ctx2.console.addEntry({
795
+ dev: (0, import_path.resolve)(__dirname, "../client/index.ts"),
796
+ prod: (0, import_path.resolve)(__dirname, "../dist")
797
+ });
798
+ });
799
+ ctx.plugin(PublicLogProvider);
800
+ const target = {
801
+ colors: 0,
802
+ record: /* @__PURE__ */ __name((record) => {
803
+ if (record.name !== "oni-sync") return;
804
+ logBuffer.push(record);
805
+ if (logBuffer.length > 100) {
806
+ logBuffer = logBuffer.slice(-100);
807
+ }
808
+ ctx.get("console")?.patch("onilogs", logBuffer);
809
+ }, "record")
810
+ };
811
+ import_koishi5.Logger.targets.push(target);
812
+ ctx.on("dispose", () => {
813
+ const index = import_koishi5.Logger.targets.indexOf(target);
814
+ if (index > -1) import_koishi5.Logger.targets.splice(index, 1);
815
+ });
816
+ ctx.model.extend("wikipages", {
817
+ id: "integer",
818
+ title: "string",
819
+ pinyin_full: "string",
820
+ // 全拼
821
+ pinyin_first: "string"
822
+ // 首字母
823
+ });
824
+ ctx.server.get("/gg/:id", async (router) => {
825
+ const pageId = Number(router.params.id);
826
+ if (isNaN(pageId)) return router.body = "❌ 无效的页面ID,必须为数字!";
827
+ const [page] = await ctx.database.get("wikipages", { id: pageId });
828
+ if (!page)
829
+ return router.body = `❌ 未找到ID为【${pageId}】的页面,请联系管理员更新缓存!`;
830
+ const targetUrl = `https://${config.main_site}/${encodeURIComponent(
831
+ page.title
832
+ )}?variant=zh`;
833
+ router.redirect(targetUrl);
834
+ });
835
+ ctx.server.get("/bw/:id", async (router) => {
836
+ const pageId = Number(router.params.id);
837
+ if (isNaN(pageId)) return router.body = "❌ 无效的页面ID,必须为数字!";
838
+ const [page] = await ctx.database.get("wikipages", { id: pageId });
839
+ if (!page)
840
+ return router.body = `❌ 未找到ID为【${pageId}】的页面,请联系管理员更新缓存!`;
841
+ const targetUrl = `https://${config.bwiki_site}/${encodeURIComponent(
842
+ page.title
843
+ )}`;
844
+ router.redirect(targetUrl);
845
+ });
853
846
  ctx.on("ready", async () => {
854
- logger.info("定时同步任务已准备就绪");
847
+ logger.info("初始化中...");
848
+ const sitesConfig = getSitesConfig(config);
849
+ ggbot = await login(sitesConfig.gg);
850
+ bwikibot = await login(sitesConfig.bwiki);
851
+ if (ggbot.login && bwikibot.login) {
852
+ logger.info("登录成功,插件已准备就绪");
853
+ } else {
854
+ logger.error("登录失败,请检查配置");
855
+ }
855
856
  ctx.cron("15 * * * *", async () => {
856
- await incrementalUpdate(ctx.wikibot.wikigg, ctx.wikibot.bwiki);
857
+ await incrementalUpdate(ggbot, bwikibot, config);
857
858
  });
858
859
  ctx.cron("30 8 * * 4", async () => {
859
- await syncPages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
860
+ await syncPages(ggbot, bwikibot).then(() => {
860
861
  logger.info("自动任务:尝试同步所有页面,从 WIKIGG 到 bwiki");
861
862
  }).catch((err) => {
862
863
  logger.error(`同步所有页面失败`);
863
- ctx.logger.error(`,错误信息:${err}`);
864
+ log.error(`,错误信息:${err}`);
864
865
  });
865
866
  });
866
867
  ctx.cron("30 8 * * 3", async () => {
867
- await syncAllImages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
868
+ await syncAllImages(ggbot, bwikibot, config).then(() => {
868
869
  logger.info("自动任务:尝试同步所有图片,从 WIKIGG 到 bwiki");
869
870
  }).catch((err) => {
870
871
  logger.error(`同步所有图片失败`);
871
- ctx.logger.error(`,错误信息:${err}`);
872
+ log.error(`,错误信息:${err}`);
872
873
  });
873
874
  });
874
875
  });
876
+ ctx.command("sync <pageTitle:string>", "同步指定页面", { authority: 2 }).action(async ({ session }, pageTitle) => {
877
+ await syncSinglePage(ggbot, bwikibot, pageTitle, "sync-bot").then(() => {
878
+ session.send(
879
+ `✅ 已尝试同步页面:${pageTitle},请前往控制台查看:${config.logsUrl}`
880
+ );
881
+ }).catch((err) => {
882
+ session.send(`❌ 同步页面失败:${pageTitle}`);
883
+ log.error(`,错误信息:${err}`);
884
+ });
885
+ });
875
886
  ctx.command("sync.incrementalUpdate", "获取3h内的编辑并尝试更新", {
876
887
  authority: 2
877
888
  }).alias("增量更新").action(async ({ session }) => {
878
889
  session.send(
879
890
  `🚀 获取3h内的编辑并尝试更新,任务耗时可能较长,请前往控制台查看日志:${config.logsUrl}`
880
891
  );
881
- await incrementalUpdate(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
892
+ await incrementalUpdate(ggbot, bwikibot, config).then(() => {
882
893
  session.send(
883
894
  `✅ 已尝试获取三小时前的编辑并同步,请前往控制台查看:${config.logsUrl}`
884
895
  );
@@ -893,7 +904,7 @@ function apply4(ctx, config) {
893
904
  session.send(
894
905
  `🚀 开始同步所有页面,任务耗时较长,请前往控制台查看日志:${config.logsUrl}`
895
906
  );
896
- await syncPages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
907
+ await syncPages(ggbot, bwikibot).then(() => {
897
908
  session.send(
898
909
  `✅ 已尝试同步所有页面,请前往控制台查看:${config.logsUrl}`
899
910
  );
@@ -908,12 +919,7 @@ function apply4(ctx, config) {
908
919
  authority: 2
909
920
  }).action(async ({ session }, moduleTitle) => {
910
921
  await session.send(`✅ 同步中,请前往控制台查看:${config.logsUrl}`);
911
- await syncSingleModule(
912
- ctx.wikibot.wikigg,
913
- ctx.wikibot.bwiki,
914
- moduleTitle,
915
- "sync-bot"
916
- ).then(() => {
922
+ await syncSingleModule(ggbot, bwikibot, moduleTitle, "sync-bot").then(() => {
917
923
  session.send(
918
924
  `✅ 已尝试同步模块:${moduleTitle},请前往控制台查看:${config.logsUrl}`
919
925
  );
@@ -926,7 +932,7 @@ function apply4(ctx, config) {
926
932
  await session.send(
927
933
  `🚀 开始同步所有模块,任务耗时较长,请前往控制台查看:${config.logsUrl}`
928
934
  );
929
- await syncModules(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
935
+ await syncModules(ggbot, bwikibot).then(() => {
930
936
  session.send(
931
937
  `✅ 已尝试同步所有模块,请前往控制台查看:${config.logsUrl}`
932
938
  );
@@ -942,9 +948,10 @@ function apply4(ctx, config) {
942
948
  `🚀 开始同步,任务可能耗时较长,请前往控制台查看:${config.logsUrl}`
943
949
  );
944
950
  await syncSingleImage(
945
- ctx.wikibot.wikigg,
946
- ctx.wikibot.bwiki,
947
- `${imgTitle.startsWith("File:") ? "" : "File:"}${imgTitle}`
951
+ ggbot,
952
+ bwikibot,
953
+ `${imgTitle.startsWith("File:") ? "" : "File:"}${imgTitle}`,
954
+ config
948
955
  ).then(() => {
949
956
  session.send(`✅ 已尝试同步图片:${imgTitle}`);
950
957
  }).catch((err) => {
@@ -956,7 +963,7 @@ function apply4(ctx, config) {
956
963
  session.send(
957
964
  `🚀 开始同步所有图片,任务耗时较长,请前往控制台查看:${config.logsUrl}`
958
965
  );
959
- await syncAllImages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
966
+ await syncAllImages(ggbot, bwikibot, config).then(() => {
960
967
  session.send(
961
968
  `✅ 已尝试同步所有图片,请前往控制台查看:${config.logsUrl}`
962
969
  );
@@ -967,46 +974,13 @@ function apply4(ctx, config) {
967
974
  log.error(`同步所有图片失败,错误信息:${err}`);
968
975
  });
969
976
  });
970
- ctx.command("sync <pageTitle:string>", "同步指定页面", { authority: 2 }).action(async ({ session }, pageTitle) => {
971
- await syncSinglePage(
972
- ctx.wikibot.wikigg,
973
- ctx.wikibot.bwiki,
974
- pageTitle,
975
- "sync-bot"
976
- ).then(() => {
977
- session.send(
978
- `✅ 已尝试同步页面:${pageTitle},请前往控制台查看:${config.logsUrl}`
979
- );
980
- }).catch((err) => {
981
- session.send(`❌ 同步页面失败:${pageTitle}`);
982
- log.error(`,错误信息:${err}`);
983
- });
984
- });
985
- }
986
- __name(apply4, "apply");
987
-
988
- // src/wiki/querywiki.ts
989
- var import_koishi9 = require("koishi");
990
- var Config5 = import_koishi9.Schema.object({
991
- domain: import_koishi9.Schema.string().description("你的短链域名(必填,如:klei.vip)").default("klei.vip")
992
- });
993
- function queryWiki(ctx, config) {
994
- const log = ctx.logger("querywiki");
995
- ctx.model.extend("wikipages", {
996
- id: "integer",
997
- title: "string",
998
- pinyin_full: "string",
999
- // 全拼
1000
- pinyin_first: "string"
1001
- // 首字母
1002
- });
1003
977
  ctx.command("x <itemName>", "查询缺氧中文wiki,精准匹配+拼音模糊匹配").alias("/查wiki").action(async ({ session }, itemName = "") => {
1004
978
  const queryKey = itemName.trim().toLowerCase();
1005
979
  if (queryKey === "")
1006
980
  return `以下是使用说明:
1007
981
  原站点: https://${config.domain}/gg/88888888
1008
982
 
1009
- bwiki: https://${config.domain}/hj/88888888`;
983
+ bwiki: https://${config.domain}/bw/88888888`;
1010
984
  if (queryKey === "火箭计算器") {
1011
985
  return "请前往以下站点使用火箭计算器工具:\n\nhttps://klei.vip/calculator\n\n(注:该工具正在测试阶段,数据可能不够准确,仅供参考)";
1012
986
  }
@@ -1099,7 +1073,7 @@ bwiki: https://${config.domain}/bw/${id}`;
1099
1073
  ctx.command("update", "更新本地页面缓存(主站)", { authority: 2 }).action(async ({ session }) => {
1100
1074
  await session.execute("update.status");
1101
1075
  try {
1102
- const res = await ctx.wikibot.wikigg.request({
1076
+ const res = await ggbot.request({
1103
1077
  action: "query",
1104
1078
  list: "allpages",
1105
1079
  format: "json",
@@ -1153,7 +1127,7 @@ bwiki: https://${config.domain}/bw/${id}`;
1153
1127
  return "❌ 参数错误!用法:redirect <原页面名> <目标页面名>";
1154
1128
  }
1155
1129
  try {
1156
- await ctx.wikibot.wikigg.create(
1130
+ await ggbot.create(
1157
1131
  pageName,
1158
1132
  `#REDIRECT [[${targetPageName}]]`,
1159
1133
  "来自qq机器人的添加重定向页面请求"
@@ -1167,27 +1141,7 @@ bwiki: https://${config.domain}/bw/${id}`;
1167
1141
  }
1168
1142
  });
1169
1143
  }
1170
- __name(queryWiki, "queryWiki");
1171
-
1172
- // src/index.ts
1173
- var name = "oni-sync-bot";
1174
- var inject = ["console", "database", "server", "cron"];
1175
- var Config6 = import_koishi10.Schema.object({});
1176
- function apply5(ctx, config) {
1177
- const log = ctx.logger("oni-sync");
1178
- ctx.inject(["console"], (ctx2) => {
1179
- ctx2.console.addEntry({
1180
- dev: (0, import_path.resolve)(__dirname, "../client/index.ts"),
1181
- prod: (0, import_path.resolve)(__dirname, "../dist")
1182
- });
1183
- });
1184
- ctx.plugin(apply, config);
1185
- ctx.plugin(apply2, config);
1186
- ctx.plugin(apply3, config);
1187
- ctx.plugin(apply4, config);
1188
- ctx.plugin(queryWiki, config);
1189
- }
1190
- __name(apply5, "apply");
1144
+ __name(apply, "apply");
1191
1145
  // Annotate the CommonJS export names for ESM import in node:
1192
1146
  0 && (module.exports = {
1193
1147
  Config,
@@ -1,4 +1,5 @@
1
1
  import { Mwn } from "mwn";
2
+ import { Config } from "../index";
2
3
  export declare const CONFIG: {
3
4
  IGNORED_IMAGES: any[];
4
5
  SYNC_INTERVAL_SUCCESS: number;
@@ -18,12 +19,12 @@ declare function getImageInfo(site: Mwn, fileName: string): Promise<ImageInfo |
18
19
  /**
19
20
  * 同步单个图片
20
21
  */
21
- declare function syncSingleImage(sourceBot: Mwn, targetBot: Mwn, fileName: string): Promise<{
22
+ declare function syncSingleImage(sourceBot: Mwn, targetBot: Mwn, fileName: string, config: Config): Promise<{
22
23
  success: boolean;
23
24
  reason?: string;
24
25
  }>;
25
26
  /**
26
27
  * 批量同步所有图片(带失败重试)
27
28
  */
28
- declare function syncAllImages(sourceBot: Mwn, targetBot: Mwn): Promise<void>;
29
+ declare function syncAllImages(sourceBot: Mwn, targetBot: Mwn, config: Config): Promise<void>;
29
30
  export { syncSingleImage, syncAllImages, getImageInfo };
@@ -0,0 +1,21 @@
1
+ import { Mwn } from "mwn";
2
+ /**
3
+ * 同步单个模块
4
+ * @param oldSite 原站点
5
+ * @param newSite 新站点
6
+ * @param moduleTitle 模块标题
7
+ * @param user 触发同步的用户
8
+ * @returns
9
+ */
10
+ declare function syncSingleModule(oldSite: Mwn, newSite: Mwn, moduleTitle: string, user?: string): Promise<{
11
+ success: boolean;
12
+ reason?: string;
13
+ }>;
14
+ /**
15
+ * 批量同步所有模块
16
+ * @param oldSite 原站点
17
+ * @param newSite 新站点
18
+ * @returns
19
+ */
20
+ declare function syncModules(oldSite: Mwn, newSite: Mwn): Promise<void>;
21
+ export { syncSingleModule, syncModules };
@@ -1,4 +1,5 @@
1
1
  import { Mwn } from "mwn";
2
+ import { Config } from "../index";
2
3
  /**
3
4
  * 单页面同步
4
5
  * @param oldSite 源站点机器人实例
@@ -25,5 +26,5 @@ declare function syncPages(oldSite: Mwn, newSite: Mwn): Promise<void>;
25
26
  * @param newSite 目标站点机器人实例
26
27
  * @param config KOISHI用户配置的项
27
28
  */
28
- declare function incrementalUpdate(oldSite: Mwn, newSite: Mwn): Promise<void>;
29
+ declare function incrementalUpdate(oldSite: Mwn, newSite: Mwn, config: Config): Promise<void>;
29
30
  export { syncSinglePage, syncPages, incrementalUpdate };
@@ -0,0 +1,29 @@
1
+ import { Mwn } from "mwn";
2
+ export declare const CONFIG: {
3
+ IGNORED_IMAGES: any[];
4
+ SYNC_INTERVAL_SUCCESS: number;
5
+ SYNC_INTERVAL_FAILED: number;
6
+ UPLOAD_COMMENT: string;
7
+ UPLOAD_TEXT: string;
8
+ };
9
+ interface ImageInfo {
10
+ url: string;
11
+ sha1: string;
12
+ size?: number;
13
+ }
14
+ /**
15
+ * 获取图片的原始URL和SHA1
16
+ */
17
+ declare function getImageInfo(site: Mwn, fileName: string): Promise<ImageInfo | null>;
18
+ /**
19
+ * 同步单个图片
20
+ */
21
+ declare function syncSingleImage(sourceBot: Mwn, targetBot: Mwn, fileName: string): Promise<{
22
+ success: boolean;
23
+ reason?: string;
24
+ }>;
25
+ /**
26
+ * 批量同步所有图片(带失败重试)
27
+ */
28
+ declare function syncAllImages(sourceBot: Mwn, targetBot: Mwn): Promise<void>;
29
+ export { syncSingleImage, syncAllImages, getImageInfo };
@@ -0,0 +1,29 @@
1
+ import { Mwn } from "mwn";
2
+ /**
3
+ * 单页面同步
4
+ * @param oldSite 源站点机器人实例
5
+ * @param newSite 目标站点机器人实例
6
+ * @param pageTitle 同步的标题
7
+ * @param user 触发更改的用户
8
+ * @returns success: boolean;reason: string;
9
+ }
10
+ */
11
+ declare function syncSinglePage(oldSite: Mwn, newSite: Mwn, pageTitle: string, user: string): Promise<{
12
+ success: boolean;
13
+ reason: string;
14
+ }>;
15
+ /**
16
+ * 同步所有页面
17
+ * @param oldSite 源站点机器人实例
18
+ * @param newSite 目标站点机器人实例
19
+ * @returns null
20
+ */
21
+ declare function syncPages(oldSite: Mwn, newSite: Mwn): Promise<void>;
22
+ /**
23
+ * 增量更新
24
+ * @param oldSite 源站点机器人实例
25
+ * @param newSite 目标站点机器人实例
26
+ * @param config KOISHI用户配置的项
27
+ */
28
+ declare function incrementalUpdate(oldSite: Mwn, newSite: Mwn): Promise<void>;
29
+ export { syncSinglePage, syncPages, incrementalUpdate };
@@ -0,0 +1,8 @@
1
+ import { Context, Schema } from "koishi";
2
+ export declare const name = "synctask_imgs";
3
+ export declare const usage = "\u56FE\u7247\u540C\u6B65\u4EFB\u52A1";
4
+ export interface Config {
5
+ logsUrl: string;
6
+ }
7
+ export declare const Config: Schema<Config>;
8
+ export default function apply(ctx: Context, config: Config): void;
@@ -0,0 +1,8 @@
1
+ import { Context, Schema } from "koishi";
2
+ export declare const name = "synctask";
3
+ export declare const usage = "\u540C\u6B65\u4EFB\u52A1";
4
+ export interface Config {
5
+ logsUrl: string;
6
+ }
7
+ export declare const Config: Schema<Config>;
8
+ export default function apply(ctx: Context, config: Config): void;
@@ -0,0 +1,49 @@
1
+ import { Context, Schema } from "koishi";
2
+ import { DataService } from "@koishijs/plugin-console";
3
+ export declare const name = "synctask_modules";
4
+ export declare const usage = "\u540C\u6B65\u6A21\u5757";
5
+ export declare const inject: string[];
6
+ interface IModuleData {
7
+ pageid: number;
8
+ pageTitle: string;
9
+ user: string;
10
+ lastEditTime: Date;
11
+ syncStatus: boolean;
12
+ }
13
+ export interface Config {
14
+ logsUrl: string;
15
+ syncCron?: string;
16
+ concurrency?: number;
17
+ requestDelay?: number;
18
+ }
19
+ declare module "@koishijs/plugin-console" {
20
+ namespace Console {
21
+ interface Services {
22
+ moduleManager: ModuleManagerService;
23
+ }
24
+ }
25
+ interface Events {
26
+ "module-sync/update"(payload: {
27
+ pageid: number;
28
+ operator?: string;
29
+ }): Promise<{
30
+ success: boolean;
31
+ }>;
32
+ "module-sync/trigger"(): Promise<{
33
+ success: boolean;
34
+ message: string;
35
+ }>;
36
+ }
37
+ }
38
+ declare module "koishi" {
39
+ interface Tables {
40
+ moduleinfo: IModuleData;
41
+ }
42
+ }
43
+ declare class ModuleManagerService extends DataService<IModuleData[]> {
44
+ constructor(ctx: Context);
45
+ get(): Promise<import("minato").FlatPick<IModuleData, any>[]>;
46
+ }
47
+ export declare const Config: Schema<Config>;
48
+ export default function apply(ctx: Context, config: Config): void;
49
+ export {};
@@ -0,0 +1,8 @@
1
+ import { Context, Schema } from "koishi";
2
+ export declare const name = "synctask_pages";
3
+ export declare const usage = "\u9875\u9762\u540C\u6B65\u4EFB\u52A1";
4
+ export interface Config {
5
+ logsUrl: string;
6
+ }
7
+ export declare const Config: Schema<Config>;
8
+ export default function apply(ctx: Context, config: Config): void;
@@ -0,0 +1,8 @@
1
+ import { Mwn } from "mwn";
2
+ import { ISiteConfig } from "../config";
3
+ /**
4
+ * 登录机器人
5
+ * @param siteConfig 站点配置
6
+ * @returns 机器人实例
7
+ */
8
+ export declare function login(siteConfig: ISiteConfig): Promise<Mwn>;
@@ -1,24 +1,8 @@
1
- import { Context, Schema } from "koishi";
2
1
  import { Mwn } from "mwn";
2
+ import { Config } from "..";
3
+ import { Context } from "koishi";
3
4
  export declare const name = "wikicore";
4
5
  export declare const usage = "wikicore";
5
- declare module "koishi" {
6
- interface Context {
7
- wikibot: {
8
- wikigg: Mwn;
9
- bwiki: Mwn;
10
- };
11
- }
12
- }
13
- export interface Config {
14
- ggUsername: string;
15
- ggPassword: string;
16
- bwikiusername: string;
17
- bwikipassword: string;
18
- domain: string;
19
- logsUrl: string;
20
- }
21
- export declare const Config: Schema<Config>;
22
6
  export default function apply(ctx: Context, config: Config): void;
23
7
  /**
24
8
  * 登录机器人
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.4.1",
4
+ "version": "0.6.2",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [