koishi-plugin-oni-sync-bot 0.3.3 → 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 +7 -0
- package/lib/index.js +215 -158
- package/lib/service/logspush.d.ts +16 -0
- package/lib/service/router.d.ts +9 -0
- package/lib/sync/imgSync.d.ts +29 -0
- package/lib/sync/pageSync.d.ts +29 -0
- package/lib/task/sync.d.ts +8 -0
- package/lib/wiki/querywiki.d.ts +19 -0
- package/lib/wiki/wikicore.d.ts +41 -0
- package/package.json +1 -1
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: () =>
|
|
34
|
-
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
|
|
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/
|
|
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/
|
|
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,
|
|
@@ -102,18 +123,21 @@ async function login(siteConfig) {
|
|
|
102
123
|
}
|
|
103
124
|
});
|
|
104
125
|
if (siteConfig.name === "bwiki") {
|
|
105
|
-
const cookieString = "SESSDATA=666; Domain=wiki.biligame.com; Path=/oni; HttpOnly; Secure";
|
|
126
|
+
const cookieString = "SESSDATA=666; Domain=wiki.biligame.com; Path=/oni; HttpOnly; Secure;";
|
|
106
127
|
bot.cookieJar.setCookie(cookieString, bot.options.apiUrl, (err) => {
|
|
107
128
|
if (err) console.error("Cookie 注入失败:", err);
|
|
108
129
|
});
|
|
130
|
+
bot.setRequestOptions({
|
|
131
|
+
headers: {
|
|
132
|
+
referer: "https://wiki.biligame.com/oni/"
|
|
133
|
+
}
|
|
134
|
+
});
|
|
109
135
|
}
|
|
110
136
|
await bot.login();
|
|
111
137
|
logger.info(`✅ 成功登录 ${siteConfig.name}`);
|
|
112
138
|
return bot;
|
|
113
139
|
}
|
|
114
140
|
__name(login, "login");
|
|
115
|
-
|
|
116
|
-
// src/config/index.ts
|
|
117
141
|
var userAgent = `OniSyncBot/1.0 (https://klei.vip; Charles@klei.vip)`;
|
|
118
142
|
function getSitesConfig(config) {
|
|
119
143
|
return {
|
|
@@ -135,11 +159,85 @@ function getSitesConfig(config) {
|
|
|
135
159
|
}
|
|
136
160
|
__name(getSitesConfig, "getSitesConfig");
|
|
137
161
|
|
|
138
|
-
// src/
|
|
162
|
+
// src/service/logspush.ts
|
|
163
|
+
var import_plugin_console = require("@koishijs/plugin-console");
|
|
139
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");
|
|
140
238
|
|
|
141
239
|
// src/sync/imgSync.ts
|
|
142
|
-
var
|
|
240
|
+
var import_koishi5 = require("koishi");
|
|
143
241
|
var import_node_fetch = __toESM(require("node-fetch"));
|
|
144
242
|
var import_form_data = __toESM(require("form-data"));
|
|
145
243
|
var CONFIG = {
|
|
@@ -174,7 +272,7 @@ async function getImageInfo(site, fileName) {
|
|
|
174
272
|
}
|
|
175
273
|
}
|
|
176
274
|
__name(getImageInfo, "getImageInfo");
|
|
177
|
-
async function syncSingleImage(sourceBot, targetBot, fileName
|
|
275
|
+
async function syncSingleImage(sourceBot, targetBot, fileName) {
|
|
178
276
|
if (CONFIG.IGNORED_IMAGES.includes(fileName)) {
|
|
179
277
|
logger.info(`[SyncImg] 🚫 图片 ${fileName} 在忽略列表,跳过`);
|
|
180
278
|
return { success: true, reason: "ignored" };
|
|
@@ -187,6 +285,8 @@ async function syncSingleImage(sourceBot, targetBot, fileName, config) {
|
|
|
187
285
|
return { success: false, reason: "source_missing" };
|
|
188
286
|
}
|
|
189
287
|
const targetImageInfo = await getImageInfo(targetBot, fileName);
|
|
288
|
+
logger.info(`原图片sha1: ${sourceImageInfo.sha1}`);
|
|
289
|
+
logger.info(`目标图片sha1: ${targetImageInfo.sha1}`);
|
|
190
290
|
if (targetImageInfo && targetImageInfo.sha1 === sourceImageInfo.sha1) {
|
|
191
291
|
logger.info(`[SyncImg] 🟡 图片 ${fileName} 已存在且内容一致,跳过`);
|
|
192
292
|
return { success: true, reason: "no_change" };
|
|
@@ -236,6 +336,10 @@ async function syncSingleImage(sourceBot, targetBot, fileName, config) {
|
|
|
236
336
|
throw new Error(`未知响应: ${JSON.stringify(responseData)}`);
|
|
237
337
|
}
|
|
238
338
|
} catch (error) {
|
|
339
|
+
if (error instanceof Error && error.message.includes("fileexists-no-change")) {
|
|
340
|
+
logger.info(`[SyncImg] 🟡 图片 ${fileName} 已存在且内容相同,跳过`);
|
|
341
|
+
return { success: true, reason: "no_change" };
|
|
342
|
+
}
|
|
239
343
|
const errMsg = error.message || String(error);
|
|
240
344
|
logger.error(`[SyncImg] ❌ 图片 ${fileName} 同步失败:`, errMsg);
|
|
241
345
|
return { success: false, reason: errMsg };
|
|
@@ -262,7 +366,7 @@ async function getAllImages(site) {
|
|
|
262
366
|
return allImages;
|
|
263
367
|
}
|
|
264
368
|
__name(getAllImages, "getAllImages");
|
|
265
|
-
async function syncAllImages(sourceBot, targetBot
|
|
369
|
+
async function syncAllImages(sourceBot, targetBot) {
|
|
266
370
|
try {
|
|
267
371
|
const imageList = await getAllImages(sourceBot);
|
|
268
372
|
if (imageList.length === 0) {
|
|
@@ -283,22 +387,17 @@ async function syncAllImages(sourceBot, targetBot, config) {
|
|
|
283
387
|
`
|
|
284
388
|
[SyncAllImg] 📈 进度 ${i + 1}/${imageList.length} (${progress.toFixed(1)}%)`
|
|
285
389
|
);
|
|
286
|
-
const result = await syncSingleImage(
|
|
287
|
-
sourceBot,
|
|
288
|
-
targetBot,
|
|
289
|
-
fileName,
|
|
290
|
-
config
|
|
291
|
-
);
|
|
390
|
+
const result = await syncSingleImage(sourceBot, targetBot, fileName);
|
|
292
391
|
if (!result.success) {
|
|
293
392
|
failCount++;
|
|
294
393
|
failedImages.push(fileName);
|
|
295
|
-
await (0,
|
|
394
|
+
await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_FAILED);
|
|
296
395
|
} else {
|
|
297
396
|
successCount++;
|
|
298
397
|
if (result.reason === "ignored" || result.reason === "no_change") {
|
|
299
398
|
skipCount++;
|
|
300
399
|
}
|
|
301
|
-
await (0,
|
|
400
|
+
await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
|
|
302
401
|
}
|
|
303
402
|
}
|
|
304
403
|
if (failedImages.length > 0) {
|
|
@@ -310,12 +409,7 @@ async function syncAllImages(sourceBot, targetBot, config) {
|
|
|
310
409
|
for (const fileName of failedImages) {
|
|
311
410
|
logger.info(`
|
|
312
411
|
[SyncAllImg] 🔁 重试: ${fileName}`);
|
|
313
|
-
const result = await syncSingleImage(
|
|
314
|
-
sourceBot,
|
|
315
|
-
targetBot,
|
|
316
|
-
fileName,
|
|
317
|
-
config
|
|
318
|
-
);
|
|
412
|
+
const result = await syncSingleImage(sourceBot, targetBot, fileName);
|
|
319
413
|
if (result.success) {
|
|
320
414
|
successCount++;
|
|
321
415
|
failCount--;
|
|
@@ -324,7 +418,7 @@ async function syncAllImages(sourceBot, targetBot, config) {
|
|
|
324
418
|
stillFailed.push(fileName);
|
|
325
419
|
logger.info(`[SyncAllImg] ❌ 重试失败: ${fileName}`);
|
|
326
420
|
}
|
|
327
|
-
await (0,
|
|
421
|
+
await (0, import_koishi5.sleep)(CONFIG.SYNC_INTERVAL_SUCCESS);
|
|
328
422
|
}
|
|
329
423
|
if (stillFailed.length > 0) {
|
|
330
424
|
logger.info(`
|
|
@@ -411,13 +505,13 @@ async function processPageWithStats(oldSite, newSite, pageTitle, user, stats, fa
|
|
|
411
505
|
if (!syncResult.success) {
|
|
412
506
|
stats.failCount++;
|
|
413
507
|
failedPages.push(pageTitle);
|
|
414
|
-
await (0,
|
|
508
|
+
await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
|
|
415
509
|
} else {
|
|
416
510
|
stats.successCount++;
|
|
417
511
|
if (syncResult.reason === "ignored" || syncResult.reason === "no_change") {
|
|
418
512
|
stats.skipCount++;
|
|
419
513
|
}
|
|
420
|
-
await (0,
|
|
514
|
+
await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
|
|
421
515
|
}
|
|
422
516
|
}
|
|
423
517
|
__name(processPageWithStats, "processPageWithStats");
|
|
@@ -493,11 +587,11 @@ async function syncPages(oldSite, newSite) {
|
|
|
493
587
|
stats.skipCount++;
|
|
494
588
|
}
|
|
495
589
|
logger.info(`[SyncAllPages] ✅ 页面 ${pageTitle} 重试成功`);
|
|
496
|
-
await (0,
|
|
590
|
+
await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
|
|
497
591
|
} else {
|
|
498
592
|
stillFailed.push(pageTitle);
|
|
499
593
|
logger.info(`[SyncAllPages] ❌ 页面 ${pageTitle} 再次失败`);
|
|
500
|
-
await (0,
|
|
594
|
+
await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
|
|
501
595
|
}
|
|
502
596
|
}
|
|
503
597
|
}
|
|
@@ -514,7 +608,7 @@ async function syncPages(oldSite, newSite) {
|
|
|
514
608
|
}
|
|
515
609
|
}
|
|
516
610
|
__name(syncPages, "syncPages");
|
|
517
|
-
async function incrementalUpdate(oldSite, newSite
|
|
611
|
+
async function incrementalUpdate(oldSite, newSite) {
|
|
518
612
|
try {
|
|
519
613
|
const now = /* @__PURE__ */ new Date();
|
|
520
614
|
const threeHoursAgo = new Date(now.getTime() - 3 * 60 * 60 * 1e3);
|
|
@@ -557,7 +651,7 @@ async function incrementalUpdate(oldSite, newSite, config) {
|
|
|
557
651
|
logger.info(
|
|
558
652
|
`[增量更新流程] 🖼️ 检查到图片: ${title},正在尝试转存`
|
|
559
653
|
);
|
|
560
|
-
await syncSingleImage(oldSite, newSite, fileName
|
|
654
|
+
await syncSingleImage(oldSite, newSite, fileName);
|
|
561
655
|
} else {
|
|
562
656
|
await syncSinglePage(
|
|
563
657
|
oldSite,
|
|
@@ -566,11 +660,11 @@ async function incrementalUpdate(oldSite, newSite, config) {
|
|
|
566
660
|
CONFIG2.INCREMENTAL_USER
|
|
567
661
|
);
|
|
568
662
|
}
|
|
569
|
-
await (0,
|
|
663
|
+
await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_SUCCESS);
|
|
570
664
|
} catch (error) {
|
|
571
665
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
572
666
|
logger.error(`[增量更新流程] ❌ 处理 ${title} 时出错:`, errMsg);
|
|
573
|
-
await (0,
|
|
667
|
+
await (0, import_koishi6.sleep)(CONFIG2.SYNC_INTERVAL_FAILED);
|
|
574
668
|
}
|
|
575
669
|
}
|
|
576
670
|
}
|
|
@@ -585,7 +679,7 @@ async function incrementalUpdate(oldSite, newSite, config) {
|
|
|
585
679
|
__name(incrementalUpdate, "incrementalUpdate");
|
|
586
680
|
|
|
587
681
|
// src/sync/moduleSync.ts
|
|
588
|
-
var
|
|
682
|
+
var import_koishi7 = require("koishi");
|
|
589
683
|
var CONFIG3 = {
|
|
590
684
|
MODLE_NAMESPACE: 828,
|
|
591
685
|
// 模块命名空间 (注意:这里原代码拼写为 MODLE,保留原样)
|
|
@@ -689,13 +783,13 @@ async function syncModules(oldSite, newSite) {
|
|
|
689
783
|
if (!syncResult.success) {
|
|
690
784
|
failCount++;
|
|
691
785
|
failedModules.push(moduleTitle);
|
|
692
|
-
await (0,
|
|
786
|
+
await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
|
|
693
787
|
} else {
|
|
694
788
|
successCount++;
|
|
695
789
|
if (syncResult.reason === "ignored" || syncResult.reason === "no_change") {
|
|
696
790
|
skipCount++;
|
|
697
791
|
}
|
|
698
|
-
await (0,
|
|
792
|
+
await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
|
|
699
793
|
}
|
|
700
794
|
}
|
|
701
795
|
if (failedModules.length > 0) {
|
|
@@ -720,11 +814,11 @@ async function syncModules(oldSite, newSite) {
|
|
|
720
814
|
skipCount++;
|
|
721
815
|
}
|
|
722
816
|
logger.info(`[SyncAllModules] ✅ 模块 ${moduleTitle} 重试成功`);
|
|
723
|
-
await (0,
|
|
817
|
+
await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_SUCCESS);
|
|
724
818
|
} else {
|
|
725
819
|
stillFailed.push(moduleTitle);
|
|
726
820
|
logger.info(`[SyncAllModules] ❌ 模块 ${moduleTitle} 再次失败`);
|
|
727
|
-
await (0,
|
|
821
|
+
await (0, import_koishi7.sleep)(CONFIG3.SYNC_INTERVAL_FAILED);
|
|
728
822
|
}
|
|
729
823
|
}
|
|
730
824
|
logger.info(`
|
|
@@ -750,135 +844,41 @@ async function syncModules(oldSite, newSite) {
|
|
|
750
844
|
}
|
|
751
845
|
__name(syncModules, "syncModules");
|
|
752
846
|
|
|
753
|
-
// src/
|
|
754
|
-
var
|
|
755
|
-
|
|
756
|
-
var logBuffer = [];
|
|
757
|
-
var Config = import_koishi5.Schema.object({
|
|
758
|
-
ggUsername: import_koishi5.Schema.string().description("WIKIGG 用户名").default("1"),
|
|
759
|
-
ggPassword: import_koishi5.Schema.string().description("WIKIGG 密码").default("1"),
|
|
760
|
-
bwikiusername: import_koishi5.Schema.string().description("bwiki用户名").default("1"),
|
|
761
|
-
bwikipassword: import_koishi5.Schema.string().description("bwiki密码").default("1"),
|
|
762
|
-
domain: import_koishi5.Schema.string().description("你的短链域名(必填,如:klei.vip)").default("klei.vip"),
|
|
763
|
-
main_site: import_koishi5.Schema.string().description("主站域名(必填,如:oxygennotincluded.wiki.gg)").default("oxygennotincluded.wiki.gg/zh"),
|
|
764
|
-
bwiki_site: import_koishi5.Schema.string().description("镜像站域名(必填,如:wiki.biligame.com)").default("wiki.biligame.com/oni"),
|
|
765
|
-
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")
|
|
766
850
|
});
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
__name(this, "PublicLogProvider");
|
|
770
|
-
}
|
|
771
|
-
constructor(ctx) {
|
|
772
|
-
super(ctx, "onilogs", { authority: 0 });
|
|
773
|
-
}
|
|
774
|
-
async get() {
|
|
775
|
-
return logBuffer;
|
|
776
|
-
}
|
|
777
|
-
};
|
|
778
|
-
function apply(ctx, config) {
|
|
779
|
-
const log = ctx.logger("oni-sync");
|
|
780
|
-
let ggbot;
|
|
781
|
-
let bwikibot;
|
|
782
|
-
ctx.inject(["console"], (ctx2) => {
|
|
783
|
-
ctx2.console.addEntry({
|
|
784
|
-
dev: (0, import_path.resolve)(__dirname, "../client/index.ts"),
|
|
785
|
-
prod: (0, import_path.resolve)(__dirname, "../dist")
|
|
786
|
-
});
|
|
787
|
-
});
|
|
788
|
-
ctx.plugin(PublicLogProvider);
|
|
789
|
-
const target = {
|
|
790
|
-
colors: 0,
|
|
791
|
-
record: /* @__PURE__ */ __name((record) => {
|
|
792
|
-
if (record.name !== "oni-sync") return;
|
|
793
|
-
logBuffer.push(record);
|
|
794
|
-
if (logBuffer.length > 100) {
|
|
795
|
-
logBuffer = logBuffer.slice(-100);
|
|
796
|
-
}
|
|
797
|
-
ctx.get("console")?.patch("onilogs", logBuffer);
|
|
798
|
-
}, "record")
|
|
799
|
-
};
|
|
800
|
-
import_koishi5.Logger.targets.push(target);
|
|
801
|
-
ctx.on("dispose", () => {
|
|
802
|
-
const index = import_koishi5.Logger.targets.indexOf(target);
|
|
803
|
-
if (index > -1) import_koishi5.Logger.targets.splice(index, 1);
|
|
804
|
-
});
|
|
805
|
-
ctx.model.extend("wikipages", {
|
|
806
|
-
id: "integer",
|
|
807
|
-
title: "string",
|
|
808
|
-
pinyin_full: "string",
|
|
809
|
-
// 全拼
|
|
810
|
-
pinyin_first: "string"
|
|
811
|
-
// 首字母
|
|
812
|
-
});
|
|
813
|
-
ctx.server.get("/gg/:id", async (router) => {
|
|
814
|
-
const pageId = Number(router.params.id);
|
|
815
|
-
if (isNaN(pageId)) return router.body = "❌ 无效的页面ID,必须为数字!";
|
|
816
|
-
const [page] = await ctx.database.get("wikipages", { id: pageId });
|
|
817
|
-
if (!page)
|
|
818
|
-
return router.body = `❌ 未找到ID为【${pageId}】的页面,请联系管理员更新缓存!`;
|
|
819
|
-
const targetUrl = `https://${config.main_site}/${encodeURIComponent(
|
|
820
|
-
page.title
|
|
821
|
-
)}?variant=zh`;
|
|
822
|
-
router.redirect(targetUrl);
|
|
823
|
-
});
|
|
824
|
-
ctx.server.get("/bw/: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.bwiki_site}/${encodeURIComponent(
|
|
831
|
-
page.title
|
|
832
|
-
)}`;
|
|
833
|
-
router.redirect(targetUrl);
|
|
834
|
-
});
|
|
851
|
+
function apply4(ctx, config) {
|
|
852
|
+
const log = ctx.logger("sync-task");
|
|
835
853
|
ctx.on("ready", async () => {
|
|
836
|
-
logger.info("
|
|
837
|
-
const sitesConfig = getSitesConfig(config);
|
|
838
|
-
ggbot = await login(sitesConfig.gg);
|
|
839
|
-
bwikibot = await login(sitesConfig.bwiki);
|
|
840
|
-
if (ggbot.login && bwikibot.login) {
|
|
841
|
-
logger.info("登录成功,插件已准备就绪");
|
|
842
|
-
} else {
|
|
843
|
-
logger.error("登录失败,请检查配置");
|
|
844
|
-
}
|
|
854
|
+
logger.info("定时同步任务已准备就绪");
|
|
845
855
|
ctx.cron("15 * * * *", async () => {
|
|
846
|
-
await incrementalUpdate(
|
|
856
|
+
await incrementalUpdate(ctx.wikibot.wikigg, ctx.wikibot.bwiki);
|
|
847
857
|
});
|
|
848
858
|
ctx.cron("30 8 * * 4", async () => {
|
|
849
|
-
await syncPages(
|
|
859
|
+
await syncPages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
|
|
850
860
|
logger.info("自动任务:尝试同步所有页面,从 WIKIGG 到 bwiki");
|
|
851
861
|
}).catch((err) => {
|
|
852
862
|
logger.error(`同步所有页面失败`);
|
|
853
|
-
|
|
863
|
+
ctx.logger.error(`,错误信息:${err}`);
|
|
854
864
|
});
|
|
855
865
|
});
|
|
856
866
|
ctx.cron("30 8 * * 3", async () => {
|
|
857
|
-
await syncAllImages(
|
|
867
|
+
await syncAllImages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
|
|
858
868
|
logger.info("自动任务:尝试同步所有图片,从 WIKIGG 到 bwiki");
|
|
859
869
|
}).catch((err) => {
|
|
860
870
|
logger.error(`同步所有图片失败`);
|
|
861
|
-
|
|
871
|
+
ctx.logger.error(`,错误信息:${err}`);
|
|
862
872
|
});
|
|
863
873
|
});
|
|
864
874
|
});
|
|
865
|
-
ctx.command("sync <pageTitle:string>", "同步指定页面", { authority: 2 }).action(async ({ session }, pageTitle) => {
|
|
866
|
-
await syncSinglePage(ggbot, bwikibot, pageTitle, "sync-bot").then(() => {
|
|
867
|
-
session.send(
|
|
868
|
-
`✅ 已尝试同步页面:${pageTitle},请前往控制台查看:${config.logsUrl}`
|
|
869
|
-
);
|
|
870
|
-
}).catch((err) => {
|
|
871
|
-
session.send(`❌ 同步页面失败:${pageTitle}`);
|
|
872
|
-
log.error(`,错误信息:${err}`);
|
|
873
|
-
});
|
|
874
|
-
});
|
|
875
875
|
ctx.command("sync.incrementalUpdate", "获取3h内的编辑并尝试更新", {
|
|
876
876
|
authority: 2
|
|
877
877
|
}).alias("增量更新").action(async ({ session }) => {
|
|
878
878
|
session.send(
|
|
879
879
|
`🚀 获取3h内的编辑并尝试更新,任务耗时可能较长,请前往控制台查看日志:${config.logsUrl}`
|
|
880
880
|
);
|
|
881
|
-
await incrementalUpdate(
|
|
881
|
+
await incrementalUpdate(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
|
|
882
882
|
session.send(
|
|
883
883
|
`✅ 已尝试获取三小时前的编辑并同步,请前往控制台查看:${config.logsUrl}`
|
|
884
884
|
);
|
|
@@ -893,7 +893,7 @@ function apply(ctx, config) {
|
|
|
893
893
|
session.send(
|
|
894
894
|
`🚀 开始同步所有页面,任务耗时较长,请前往控制台查看日志:${config.logsUrl}`
|
|
895
895
|
);
|
|
896
|
-
await syncPages(
|
|
896
|
+
await syncPages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
|
|
897
897
|
session.send(
|
|
898
898
|
`✅ 已尝试同步所有页面,请前往控制台查看:${config.logsUrl}`
|
|
899
899
|
);
|
|
@@ -908,7 +908,12 @@ function apply(ctx, config) {
|
|
|
908
908
|
authority: 2
|
|
909
909
|
}).action(async ({ session }, moduleTitle) => {
|
|
910
910
|
await session.send(`✅ 同步中,请前往控制台查看:${config.logsUrl}`);
|
|
911
|
-
await syncSingleModule(
|
|
911
|
+
await syncSingleModule(
|
|
912
|
+
ctx.wikibot.wikigg,
|
|
913
|
+
ctx.wikibot.bwiki,
|
|
914
|
+
moduleTitle,
|
|
915
|
+
"sync-bot"
|
|
916
|
+
).then(() => {
|
|
912
917
|
session.send(
|
|
913
918
|
`✅ 已尝试同步模块:${moduleTitle},请前往控制台查看:${config.logsUrl}`
|
|
914
919
|
);
|
|
@@ -921,7 +926,7 @@ function apply(ctx, config) {
|
|
|
921
926
|
await session.send(
|
|
922
927
|
`🚀 开始同步所有模块,任务耗时较长,请前往控制台查看:${config.logsUrl}`
|
|
923
928
|
);
|
|
924
|
-
await syncModules(
|
|
929
|
+
await syncModules(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
|
|
925
930
|
session.send(
|
|
926
931
|
`✅ 已尝试同步所有模块,请前往控制台查看:${config.logsUrl}`
|
|
927
932
|
);
|
|
@@ -937,10 +942,9 @@ function apply(ctx, config) {
|
|
|
937
942
|
`🚀 开始同步,任务可能耗时较长,请前往控制台查看:${config.logsUrl}`
|
|
938
943
|
);
|
|
939
944
|
await syncSingleImage(
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
`${imgTitle.startsWith("File:") ? "" : "File:"}${imgTitle}
|
|
943
|
-
config
|
|
945
|
+
ctx.wikibot.wikigg,
|
|
946
|
+
ctx.wikibot.bwiki,
|
|
947
|
+
`${imgTitle.startsWith("File:") ? "" : "File:"}${imgTitle}`
|
|
944
948
|
).then(() => {
|
|
945
949
|
session.send(`✅ 已尝试同步图片:${imgTitle}`);
|
|
946
950
|
}).catch((err) => {
|
|
@@ -952,7 +956,7 @@ function apply(ctx, config) {
|
|
|
952
956
|
session.send(
|
|
953
957
|
`🚀 开始同步所有图片,任务耗时较长,请前往控制台查看:${config.logsUrl}`
|
|
954
958
|
);
|
|
955
|
-
await syncAllImages(
|
|
959
|
+
await syncAllImages(ctx.wikibot.wikigg, ctx.wikibot.bwiki).then(() => {
|
|
956
960
|
session.send(
|
|
957
961
|
`✅ 已尝试同步所有图片,请前往控制台查看:${config.logsUrl}`
|
|
958
962
|
);
|
|
@@ -963,6 +967,39 @@ function apply(ctx, config) {
|
|
|
963
967
|
log.error(`同步所有图片失败,错误信息:${err}`);
|
|
964
968
|
});
|
|
965
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
|
+
});
|
|
966
1003
|
ctx.command("x <itemName>", "查询缺氧中文wiki,精准匹配+拼音模糊匹配").alias("/查wiki").action(async ({ session }, itemName = "") => {
|
|
967
1004
|
const queryKey = itemName.trim().toLowerCase();
|
|
968
1005
|
if (queryKey === "")
|
|
@@ -1062,7 +1099,7 @@ bwiki: https://${config.domain}/bw/${id}`;
|
|
|
1062
1099
|
ctx.command("update", "更新本地页面缓存(主站)", { authority: 2 }).action(async ({ session }) => {
|
|
1063
1100
|
await session.execute("update.status");
|
|
1064
1101
|
try {
|
|
1065
|
-
const res = await
|
|
1102
|
+
const res = await ctx.wikibot.wikigg.request({
|
|
1066
1103
|
action: "query",
|
|
1067
1104
|
list: "allpages",
|
|
1068
1105
|
format: "json",
|
|
@@ -1116,7 +1153,7 @@ bwiki: https://${config.domain}/bw/${id}`;
|
|
|
1116
1153
|
return "❌ 参数错误!用法:redirect <原页面名> <目标页面名>";
|
|
1117
1154
|
}
|
|
1118
1155
|
try {
|
|
1119
|
-
await
|
|
1156
|
+
await ctx.wikibot.wikigg.create(
|
|
1120
1157
|
pageName,
|
|
1121
1158
|
`#REDIRECT [[${targetPageName}]]`,
|
|
1122
1159
|
"来自qq机器人的添加重定向页面请求"
|
|
@@ -1130,7 +1167,27 @@ bwiki: https://${config.domain}/bw/${id}`;
|
|
|
1130
1167
|
}
|
|
1131
1168
|
});
|
|
1132
1169
|
}
|
|
1133
|
-
__name(
|
|
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");
|
|
1134
1191
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1135
1192
|
0 && (module.exports = {
|
|
1136
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 {};
|