koishi-plugin-oni-sync-bot 0.3.4 → 0.4.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.
package/lib/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { Context, Schema } from "koishi";
2
+ export declare const name = "oni-sync-bot";
3
+ export declare const inject: string[];
4
+ export interface Config {
5
+ }
6
+ export declare const Config: Schema<Config>;
7
+ 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: () => Config,
34
- apply: () => apply,
33
+ Config: () => Config6,
34
+ apply: () => apply5,
35
35
  inject: () => inject,
36
36
  name: () => name
37
37
  });
38
38
  module.exports = __toCommonJS(src_exports);
39
- var import_koishi5 = require("koishi");
39
+ var import_koishi10 = require("koishi");
40
40
  var import_path = require("path");
41
- var import_plugin_console = require("@koishijs/plugin-console");
42
41
 
43
- // src/utils/login.ts
42
+ // src/wiki/wikicore.ts
43
+ var import_koishi2 = require("koishi");
44
44
  var import_mwn = require("mwn");
45
45
 
46
46
  // src/utils/tools.ts
@@ -90,7 +90,28 @@ function generatePinyinInfo(text) {
90
90
  __name(generatePinyinInfo, "generatePinyinInfo");
91
91
  var logger = new import_koishi.Logger("oni-sync");
92
92
 
93
- // src/utils/login.ts
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");
94
115
  async function login(siteConfig) {
95
116
  const bot = new import_mwn.Mwn({
96
117
  apiUrl: siteConfig.api,
@@ -117,8 +138,6 @@ async function login(siteConfig) {
117
138
  return bot;
118
139
  }
119
140
  __name(login, "login");
120
-
121
- // src/config/index.ts
122
141
  var userAgent = `OniSyncBot/1.0 (https://klei.vip; Charles@klei.vip)`;
123
142
  function getSitesConfig(config) {
124
143
  return {
@@ -140,11 +159,85 @@ function getSitesConfig(config) {
140
159
  }
141
160
  __name(getSitesConfig, "getSitesConfig");
142
161
 
143
- // src/sync/pageSync.ts
162
+ // src/service/logspush.ts
163
+ var import_plugin_console = require("@koishijs/plugin-console");
144
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
+ // src/sync/pageSync.ts
237
+ var import_koishi6 = require("koishi");
145
238
 
146
239
  // src/sync/imgSync.ts
147
- var import_koishi2 = require("koishi");
240
+ var import_koishi5 = require("koishi");
148
241
  var import_node_fetch = __toESM(require("node-fetch"));
149
242
  var import_form_data = __toESM(require("form-data"));
150
243
  var CONFIG = {
@@ -179,7 +272,7 @@ async function getImageInfo(site, fileName) {
179
272
  }
180
273
  }
181
274
  __name(getImageInfo, "getImageInfo");
182
- async function syncSingleImage(sourceBot, targetBot, fileName, config) {
275
+ async function syncSingleImage(sourceBot, targetBot, fileName) {
183
276
  if (CONFIG.IGNORED_IMAGES.includes(fileName)) {
184
277
  logger.info(`[SyncImg] 🚫 图片 ${fileName} 在忽略列表,跳过`);
185
278
  return { success: true, reason: "ignored" };
@@ -273,7 +366,7 @@ async function getAllImages(site) {
273
366
  return allImages;
274
367
  }
275
368
  __name(getAllImages, "getAllImages");
276
- async function syncAllImages(sourceBot, targetBot, config) {
369
+ async function syncAllImages(sourceBot, targetBot) {
277
370
  try {
278
371
  const imageList = await getAllImages(sourceBot);
279
372
  if (imageList.length === 0) {
@@ -294,22 +387,17 @@ async function syncAllImages(sourceBot, targetBot, config) {
294
387
  `
295
388
  [SyncAllImg] 📈 进度 ${i + 1}/${imageList.length} (${progress.toFixed(1)}%)`
296
389
  );
297
- const result = await syncSingleImage(
298
- sourceBot,
299
- targetBot,
300
- fileName,
301
- config
302
- );
390
+ const result = await syncSingleImage(sourceBot, targetBot, fileName);
303
391
  if (!result.success) {
304
392
  failCount++;
305
393
  failedImages.push(fileName);
306
- await (0, import_koishi2.sleep)(CONFIG.SYNC_INTERVAL_FAILED);
394
+ await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_FAILED);
307
395
  } else {
308
396
  successCount++;
309
397
  if (result.reason === "ignored" || result.reason === "no_change") {
310
398
  skipCount++;
311
399
  }
312
- await (0, import_koishi2.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
400
+ await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
313
401
  }
314
402
  }
315
403
  if (failedImages.length > 0) {
@@ -321,12 +409,7 @@ async function syncAllImages(sourceBot, targetBot, config) {
321
409
  for (const fileName of failedImages) {
322
410
  logger.info(`
323
411
  [SyncAllImg] 🔁 重试: ${fileName}`);
324
- const result = await syncSingleImage(
325
- sourceBot,
326
- targetBot,
327
- fileName,
328
- config
329
- );
412
+ const result = await syncSingleImage(sourceBot, targetBot, fileName);
330
413
  if (result.success) {
331
414
  successCount++;
332
415
  failCount--;
@@ -335,7 +418,7 @@ async function syncAllImages(sourceBot, targetBot, config) {
335
418
  stillFailed.push(fileName);
336
419
  logger.info(`[SyncAllImg] ❌ 重试失败: ${fileName}`);
337
420
  }
338
- await (0, import_koishi2.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
421
+ await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
339
422
  }
340
423
  if (stillFailed.length > 0) {
341
424
  logger.info(`
@@ -422,13 +505,13 @@ async function processPageWithStats(oldSite, newSite, pageTitle, user, stats, fa
422
505
  if (!syncResult.success) {
423
506
  stats.failCount++;
424
507
  failedPages.push(pageTitle);
425
- await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
508
+ await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
426
509
  } else {
427
510
  stats.successCount++;
428
511
  if (syncResult.reason === "ignored" || syncResult.reason === "no_change") {
429
512
  stats.skipCount++;
430
513
  }
431
- await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
514
+ await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
432
515
  }
433
516
  }
434
517
  __name(processPageWithStats, "processPageWithStats");
@@ -504,11 +587,11 @@ async function syncPages(oldSite, newSite) {
504
587
  stats.skipCount++;
505
588
  }
506
589
  logger.info(`[SyncAllPages] ✅ 页面 ${pageTitle} 重试成功`);
507
- await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
590
+ await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
508
591
  } else {
509
592
  stillFailed.push(pageTitle);
510
593
  logger.info(`[SyncAllPages] ❌ 页面 ${pageTitle} 再次失败`);
511
- await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
594
+ await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
512
595
  }
513
596
  }
514
597
  }
@@ -525,7 +608,7 @@ async function syncPages(oldSite, newSite) {
525
608
  }
526
609
  }
527
610
  __name(syncPages, "syncPages");
528
- async function incrementalUpdate(oldSite, newSite, config) {
611
+ async function incrementalUpdate(oldSite, newSite) {
529
612
  try {
530
613
  const now = /* @__PURE__ */ new Date();
531
614
  const threeHoursAgo = new Date(now.getTime() - 3 * 60 * 60 * 1e3);
@@ -568,7 +651,7 @@ async function incrementalUpdate(oldSite, newSite, config) {
568
651
  logger.info(
569
652
  `[增量更新流程] 🖼️ 检查到图片: ${title},正在尝试转存`
570
653
  );
571
- await syncSingleImage(oldSite, newSite, fileName, config);
654
+ await syncSingleImage(oldSite, newSite, fileName);
572
655
  } else {
573
656
  await syncSinglePage(
574
657
  oldSite,
@@ -577,11 +660,11 @@ async function incrementalUpdate(oldSite, newSite, config) {
577
660
  CONFIG2.INCREMENTAL_USER
578
661
  );
579
662
  }
580
- await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
663
+ await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
581
664
  } catch (error) {
582
665
  const errMsg = error instanceof Error ? error.message : String(error);
583
666
  logger.error(`[增量更新流程] ❌ 处理 ${title} 时出错:`, errMsg);
584
- await (0, import_koishi3.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
667
+ await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
585
668
  }
586
669
  }
587
670
  }
@@ -596,7 +679,7 @@ async function incrementalUpdate(oldSite, newSite, config) {
596
679
  __name(incrementalUpdate, "incrementalUpdate");
597
680
 
598
681
  // src/sync/moduleSync.ts
599
- var import_koishi4 = require("koishi");
682
+ var import_koishi7 = require("koishi");
600
683
  var CONFIG3 = {
601
684
  MODLE_NAMESPACE: 828,
602
685
  // 模块命名空间 (注意:这里原代码拼写为 MODLE,保留原样)
@@ -700,13 +783,13 @@ async function syncModules(oldSite, newSite) {
700
783
  if (!syncResult.success) {
701
784
  failCount++;
702
785
  failedModules.push(moduleTitle);
703
- await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
786
+ await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
704
787
  } else {
705
788
  successCount++;
706
789
  if (syncResult.reason === "ignored" || syncResult.reason === "no_change") {
707
790
  skipCount++;
708
791
  }
709
- await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
792
+ await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
710
793
  }
711
794
  }
712
795
  if (failedModules.length > 0) {
@@ -731,11 +814,11 @@ async function syncModules(oldSite, newSite) {
731
814
  skipCount++;
732
815
  }
733
816
  logger.info(`[SyncAllModules] ✅ 模块 ${moduleTitle} 重试成功`);
734
- await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
817
+ await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
735
818
  } else {
736
819
  stillFailed.push(moduleTitle);
737
820
  logger.info(`[SyncAllModules] ❌ 模块 ${moduleTitle} 再次失败`);
738
- await (0, import_koishi4.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
821
+ await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
739
822
  }
740
823
  }
741
824
  logger.info(`
@@ -761,135 +844,41 @@ async function syncModules(oldSite, newSite) {
761
844
  }
762
845
  __name(syncModules, "syncModules");
763
846
 
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")
847
+ // src/task/sync.ts
848
+ var Config4 = import_koishi8.Schema.object({
849
+ logsUrl: import_koishi8.Schema.string().description("日志查看地址").default("https://klei.vip/onilogs")
777
850
  });
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
- });
851
+ function apply4(ctx, config) {
852
+ const log = ctx.logger("sync-task");
846
853
  ctx.on("ready", async () => {
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
- }
854
+ logger.info("定时同步任务已准备就绪");
856
855
  ctx.cron("15 * * * *", async () => {
857
- await incrementalUpdate(ggbot, bwikibot, config);
856
+ await incrementalUpdate(ctx.wikibot.wikigg, ctx.wikibot.bwiki);
858
857
  });
859
858
  ctx.cron("30 8 * * 4", async () => {
860
- await syncPages(ggbot, bwikibot).then(() => {
859
+ await syncPages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
861
860
  logger.info("自动任务:尝试同步所有页面,从 WIKIGG 到 bwiki");
862
861
  }).catch((err) => {
863
862
  logger.error(`同步所有页面失败`);
864
- log.error(`,错误信息:${err}`);
863
+ ctx.logger.error(`,错误信息:${err}`);
865
864
  });
866
865
  });
867
866
  ctx.cron("30 8 * * 3", async () => {
868
- await syncAllImages(ggbot, bwikibot, config).then(() => {
867
+ await syncAllImages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
869
868
  logger.info("自动任务:尝试同步所有图片,从 WIKIGG 到 bwiki");
870
869
  }).catch((err) => {
871
870
  logger.error(`同步所有图片失败`);
872
- log.error(`,错误信息:${err}`);
871
+ ctx.logger.error(`,错误信息:${err}`);
873
872
  });
874
873
  });
875
874
  });
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
- });
886
875
  ctx.command("sync.incrementalUpdate", "获取3h内的编辑并尝试更新", {
887
876
  authority: 2
888
877
  }).alias("增量更新").action(async ({ session }) => {
889
878
  session.send(
890
879
  `🚀 获取3h内的编辑并尝试更新,任务耗时可能较长,请前往控制台查看日志:${config.logsUrl}`
891
880
  );
892
- await incrementalUpdate(ggbot, bwikibot, config).then(() => {
881
+ await incrementalUpdate(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
893
882
  session.send(
894
883
  `✅ 已尝试获取三小时前的编辑并同步,请前往控制台查看:${config.logsUrl}`
895
884
  );
@@ -904,7 +893,7 @@ function apply(ctx, config) {
904
893
  session.send(
905
894
  `🚀 开始同步所有页面,任务耗时较长,请前往控制台查看日志:${config.logsUrl}`
906
895
  );
907
- await syncPages(ggbot, bwikibot).then(() => {
896
+ await syncPages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
908
897
  session.send(
909
898
  `✅ 已尝试同步所有页面,请前往控制台查看:${config.logsUrl}`
910
899
  );
@@ -919,7 +908,12 @@ function apply(ctx, config) {
919
908
  authority: 2
920
909
  }).action(async ({ session }, moduleTitle) => {
921
910
  await session.send(`✅ 同步中,请前往控制台查看:${config.logsUrl}`);
922
- await syncSingleModule(ggbot, bwikibot, moduleTitle, "sync-bot").then(() => {
911
+ await syncSingleModule(
912
+ ctx.wikibot.wikigg,
913
+ ctx.wikibot.bwiki,
914
+ moduleTitle,
915
+ "sync-bot"
916
+ ).then(() => {
923
917
  session.send(
924
918
  `✅ 已尝试同步模块:${moduleTitle},请前往控制台查看:${config.logsUrl}`
925
919
  );
@@ -932,7 +926,7 @@ function apply(ctx, config) {
932
926
  await session.send(
933
927
  `🚀 开始同步所有模块,任务耗时较长,请前往控制台查看:${config.logsUrl}`
934
928
  );
935
- await syncModules(ggbot, bwikibot).then(() => {
929
+ await syncModules(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
936
930
  session.send(
937
931
  `✅ 已尝试同步所有模块,请前往控制台查看:${config.logsUrl}`
938
932
  );
@@ -948,10 +942,9 @@ function apply(ctx, config) {
948
942
  `🚀 开始同步,任务可能耗时较长,请前往控制台查看:${config.logsUrl}`
949
943
  );
950
944
  await syncSingleImage(
951
- ggbot,
952
- bwikibot,
953
- `${imgTitle.startsWith("File:") ? "" : "File:"}${imgTitle}`,
954
- config
945
+ ctx.wikibot.wikigg,
946
+ ctx.wikibot.bwiki,
947
+ `${imgTitle.startsWith("File:") ? "" : "File:"}${imgTitle}`
955
948
  ).then(() => {
956
949
  session.send(`✅ 已尝试同步图片:${imgTitle}`);
957
950
  }).catch((err) => {
@@ -963,7 +956,7 @@ function apply(ctx, config) {
963
956
  session.send(
964
957
  `🚀 开始同步所有图片,任务耗时较长,请前往控制台查看:${config.logsUrl}`
965
958
  );
966
- await syncAllImages(ggbot, bwikibot, config).then(() => {
959
+ await syncAllImages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
967
960
  session.send(
968
961
  `✅ 已尝试同步所有图片,请前往控制台查看:${config.logsUrl}`
969
962
  );
@@ -974,6 +967,39 @@ function apply(ctx, config) {
974
967
  log.error(`同步所有图片失败,错误信息:${err}`);
975
968
  });
976
969
  });
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
+ });
977
1003
  ctx.command("x <itemName>", "查询缺氧中文wiki,精准匹配+拼音模糊匹配").alias("/查wiki").action(async ({ session }, itemName = "") => {
978
1004
  const queryKey = itemName.trim().toLowerCase();
979
1005
  if (queryKey === "")
@@ -1073,7 +1099,7 @@ bwiki: https://${config.domain}/bw/${id}`;
1073
1099
  ctx.command("update", "更新本地页面缓存(主站)", { authority: 2 }).action(async ({ session }) => {
1074
1100
  await session.execute("update.status");
1075
1101
  try {
1076
- const res = await ggbot.request({
1102
+ const res = await ctx.wikibot.wikigg.request({
1077
1103
  action: "query",
1078
1104
  list: "allpages",
1079
1105
  format: "json",
@@ -1127,7 +1153,7 @@ bwiki: https://${config.domain}/bw/${id}`;
1127
1153
  return "❌ 参数错误!用法:redirect <原页面名> <目标页面名>";
1128
1154
  }
1129
1155
  try {
1130
- await ggbot.create(
1156
+ await ctx.wikibot.wikigg.create(
1131
1157
  pageName,
1132
1158
  `#REDIRECT [[${targetPageName}]]`,
1133
1159
  "来自qq机器人的添加重定向页面请求"
@@ -1141,7 +1167,27 @@ bwiki: https://${config.domain}/bw/${id}`;
1141
1167
  }
1142
1168
  });
1143
1169
  }
1144
- __name(apply, "apply");
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");
1145
1191
  // Annotate the CommonJS export names for ESM import in node:
1146
1192
  0 && (module.exports = {
1147
1193
  Config,
@@ -0,0 +1,16 @@
1
+ import { Logger, Context, Schema } from "koishi";
2
+ export declare const name = "logspush";
3
+ export declare const usage = "\u65E5\u5FD7\u63A8\u9001";
4
+ export interface Config {
5
+ logsUrl: string;
6
+ }
7
+ export declare const Config: Schema<Config>;
8
+ declare module "@koishijs/console" {
9
+ namespace Console {
10
+ interface Services {
11
+ onilogs: DataService<Logger.Record[]>;
12
+ }
13
+ }
14
+ }
15
+ export declare let logBuffer: Logger.Record[];
16
+ export default function apply(ctx: Context, config: Config): void;
@@ -0,0 +1,9 @@
1
+ import { Context, Schema } from "koishi";
2
+ export interface Config {
3
+ main_site: string;
4
+ bwiki_site: string;
5
+ }
6
+ export declare const Config: Schema<Config>;
7
+ export declare const name = "wikirouter";
8
+ export declare const usage = "wiki\u8DEF\u7531\u91CD\u5B9A\u5411";
9
+ export default function apply(ctx: Context, config: Config): void;
@@ -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";
3
+ export declare const usage = "\u5B9A\u65F6\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,19 @@
1
+ import { Context, Schema } from "koishi";
2
+ export declare const name = "querywiki";
3
+ export declare const usage = "\u67E5\u8BE2Wiki";
4
+ export interface Config {
5
+ domain: string;
6
+ }
7
+ export declare const Config: Schema<Config>;
8
+ declare module "koishi" {
9
+ interface Tables {
10
+ wikipages: WikiPages;
11
+ }
12
+ }
13
+ export interface WikiPages {
14
+ id: number;
15
+ title: string;
16
+ pinyin_full: string;
17
+ pinyin_first: string;
18
+ }
19
+ export default function queryWiki(ctx: Context, config: Config): void;
@@ -0,0 +1,41 @@
1
+ import { Context, Schema } from "koishi";
2
+ import { Mwn } from "mwn";
3
+ export declare const name = "wikicore";
4
+ 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
+ export default function apply(ctx: Context, config: Config): void;
23
+ /**
24
+ * 登录机器人
25
+ * @param siteConfig 站点配置
26
+ * @returns 机器人实例
27
+ */
28
+ export declare function login(siteConfig: ISiteConfig): Promise<Mwn>;
29
+ export interface ISiteConfig {
30
+ name: string;
31
+ api: string;
32
+ username: string;
33
+ password: string;
34
+ userAgent: string;
35
+ }
36
+ interface ISitesConfig {
37
+ gg: ISiteConfig;
38
+ bwiki: ISiteConfig;
39
+ }
40
+ export declare function getSitesConfig(config: Config): ISitesConfig;
41
+ export {};
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.3.4",
4
+ "version": "0.4.1",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [