koishi-plugin-minecraft-notifier 1.5.1 → 1.7.0
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/git-platform-helper.d.ts +64 -0
- package/lib/index.cjs +251 -117
- package/lib/index.d.ts +3 -0
- package/lib/prompt-const.d.ts +2 -1
- package/lib/translation-fetcher.d.ts +9 -1
- package/package.json +1 -1
- package/lib/gitee-helper.d.ts +0 -19
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { AxiosResponse } from 'axios';
|
|
2
|
+
import { Context } from 'koishi';
|
|
3
|
+
/**
|
|
4
|
+
* Git 平台类型
|
|
5
|
+
*/
|
|
6
|
+
export declare enum GitPlatform {
|
|
7
|
+
GITEE = "gitee",
|
|
8
|
+
GITCODE = "gitcode"
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 操作结果类型
|
|
12
|
+
*/
|
|
13
|
+
interface OperationResult {
|
|
14
|
+
success: boolean;
|
|
15
|
+
data?: AxiosResponse;
|
|
16
|
+
error?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 文件上传参数
|
|
20
|
+
*/
|
|
21
|
+
interface FileUploadParams {
|
|
22
|
+
owner: string;
|
|
23
|
+
repo: string;
|
|
24
|
+
path: string;
|
|
25
|
+
content: string;
|
|
26
|
+
message: string;
|
|
27
|
+
token: string;
|
|
28
|
+
branch?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 上传或更新 Gitee 仓库中的文本文件
|
|
32
|
+
* @param ctx - Koishi 上下文
|
|
33
|
+
* @param owner - 仓库所有者用户名
|
|
34
|
+
* @param repo - 仓库名称
|
|
35
|
+
* @param path - 文件路径(例如 'docs/update.txt')
|
|
36
|
+
* @param content - 文件内容(纯文本字符串,会自动 Base64 编码)
|
|
37
|
+
* @param message - Commit 消息
|
|
38
|
+
* @param token - Gitee Personal Access Token
|
|
39
|
+
* @param branch - 分支名(默认 'master')
|
|
40
|
+
* @returns Promise<OperationResult>
|
|
41
|
+
*/
|
|
42
|
+
export declare function upsertFileToGitee(ctx: Context, owner: string, repo: string, path: string, content: string, message: string, token: string, branch?: string): Promise<OperationResult>;
|
|
43
|
+
/**
|
|
44
|
+
* 上传或更新 GitCode 仓库中的文本文件
|
|
45
|
+
* @param ctx - Koishi 上下文
|
|
46
|
+
* @param owner - 仓库所有者用户名
|
|
47
|
+
* @param repo - 仓库名称
|
|
48
|
+
* @param path - 文件路径(例如 'docs/update.txt')
|
|
49
|
+
* @param content - 文件内容(纯文本字符串,会自动 Base64 编码)
|
|
50
|
+
* @param message - Commit 消息
|
|
51
|
+
* @param token - GitCode Personal Access Token
|
|
52
|
+
* @param branch - 分支名(默认 'master')
|
|
53
|
+
* @returns Promise<OperationResult>
|
|
54
|
+
*/
|
|
55
|
+
export declare function upsertFileToGitCode(ctx: Context, owner: string, repo: string, path: string, content: string, message: string, token: string, branch?: string): Promise<OperationResult>;
|
|
56
|
+
/**
|
|
57
|
+
* 通用上传函数(可指定平台)
|
|
58
|
+
* @param ctx - Koishi 上下文
|
|
59
|
+
* @param platform - Git 平台类型
|
|
60
|
+
* @param params - 上传参数
|
|
61
|
+
* @returns Promise<OperationResult>
|
|
62
|
+
*/
|
|
63
|
+
export declare function upsertFileToGit(ctx: Context, platform: GitPlatform, params: FileUploadParams): Promise<OperationResult>;
|
|
64
|
+
export {};
|
package/lib/index.cjs
CHANGED
|
@@ -63,26 +63,94 @@ function createBotTextMsgNode(bot, content) {
|
|
|
63
63
|
// src/translation-fetcher.ts
|
|
64
64
|
var import_axios = __toESM(require("axios"), 1);
|
|
65
65
|
var cheerio = __toESM(require("cheerio"), 1);
|
|
66
|
-
async function
|
|
66
|
+
async function fetchGitCodeTranslations(ctx, owner, repo, path3, token, branch = "master") {
|
|
67
|
+
try {
|
|
68
|
+
const url = `https://api.gitcode.com/api/v5/repos/${owner}/${repo}/contents/${path3}`;
|
|
69
|
+
const response = await import_axios.default.get(url, {
|
|
70
|
+
params: { ref: branch, access_token: token },
|
|
71
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
72
|
+
});
|
|
73
|
+
if (!response.data?.content) {
|
|
74
|
+
ctx.logger("translation-extractor").warn(
|
|
75
|
+
"GitCode file has no content"
|
|
76
|
+
);
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
const content = Buffer.from(response.data.content, "base64").toString(
|
|
80
|
+
"utf-8"
|
|
81
|
+
);
|
|
82
|
+
return parseTranslationContent(content);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
ctx.logger("translation-extractor").warn(
|
|
85
|
+
"Failed to fetch GitCode translations:",
|
|
86
|
+
error.response?.data || error.message
|
|
87
|
+
);
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function parseTranslationContent(content) {
|
|
92
|
+
const translations = [];
|
|
93
|
+
try {
|
|
94
|
+
const parsed = JSON.parse(content);
|
|
95
|
+
if (Array.isArray(parsed)) {
|
|
96
|
+
for (const item of parsed) {
|
|
97
|
+
if (item.english && item.chinese) {
|
|
98
|
+
translations.push({
|
|
99
|
+
english: item.english.trim(),
|
|
100
|
+
chinese: item.chinese.trim()
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} else if (typeof parsed === "object") {
|
|
105
|
+
for (const [english, chinese] of Object.entries(parsed)) {
|
|
106
|
+
if (typeof chinese === "string") {
|
|
107
|
+
translations.push({
|
|
108
|
+
english: english.trim(),
|
|
109
|
+
chinese: chinese.trim()
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return translations;
|
|
115
|
+
} catch {
|
|
116
|
+
const lines = content.split("\n");
|
|
117
|
+
for (const line of lines) {
|
|
118
|
+
const trimmed = line.trim();
|
|
119
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("//")) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (trimmed.includes(":")) {
|
|
123
|
+
const [english, chinese] = trimmed.split(":").map((s) => s.trim());
|
|
124
|
+
if (english && chinese) {
|
|
125
|
+
translations.push({ english, chinese });
|
|
126
|
+
}
|
|
127
|
+
} else if (trimmed.includes(",")) {
|
|
128
|
+
const [english, chinese] = trimmed.split(",").map((s) => s.trim());
|
|
129
|
+
if (english && chinese) {
|
|
130
|
+
translations.push({ english, chinese });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return translations;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function fetchWikiTranslations(ctx) {
|
|
67
138
|
try {
|
|
68
139
|
const response = await import_axios.default.get(
|
|
69
140
|
"https://zh.minecraft.wiki/w/Minecraft_Wiki:%E8%AF%91%E5%90%8D%E6%A0%87%E5%87%86%E5%8C%96"
|
|
70
141
|
);
|
|
71
142
|
const html = response.data;
|
|
72
143
|
const $ = cheerio.load(html);
|
|
73
|
-
const
|
|
144
|
+
const translations = [];
|
|
74
145
|
$(".data-table").each((index, table) => {
|
|
75
146
|
const rows = $(table).find("tr");
|
|
76
|
-
let headers = null;
|
|
77
147
|
let englishCol = -1;
|
|
78
148
|
let chineseCol = -1;
|
|
79
149
|
rows.each((rowIndex, row) => {
|
|
80
150
|
const cells = $(row).find("td, th");
|
|
81
151
|
if (rowIndex === 0) {
|
|
82
|
-
headers = [];
|
|
83
152
|
cells.each((colIndex, cell) => {
|
|
84
153
|
const headerText = $(cell).text().trim();
|
|
85
|
-
headers.push(headerText);
|
|
86
154
|
if (headerText.includes("\u82F1\u6587") || headerText.includes("English")) {
|
|
87
155
|
englishCol = colIndex;
|
|
88
156
|
}
|
|
@@ -96,26 +164,62 @@ async function extractTranslations(ctx, searchStr) {
|
|
|
96
164
|
const english = $(cells[englishCol]).text().trim();
|
|
97
165
|
const chinese = $(cells[chineseCol]).text().trim();
|
|
98
166
|
if (english && chinese) {
|
|
99
|
-
|
|
100
|
-
matches.push({ english, chinese });
|
|
101
|
-
}
|
|
167
|
+
translations.push({ english, chinese });
|
|
102
168
|
}
|
|
103
169
|
}
|
|
104
170
|
});
|
|
105
171
|
});
|
|
172
|
+
return translations;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
ctx.logger("translation-extractor").warn(
|
|
175
|
+
"Failed to fetch Wiki translations:",
|
|
176
|
+
error
|
|
177
|
+
);
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async function extractTranslations(ctx, cfg, searchStr) {
|
|
182
|
+
try {
|
|
183
|
+
const [wikiTranslations, gitcodeTranslations] = await Promise.all([
|
|
184
|
+
fetchWikiTranslations(ctx),
|
|
185
|
+
cfg.gitcodeApiToken && cfg.gitcodeOwner && cfg.gitcodeRepo ? fetchGitCodeTranslations(
|
|
186
|
+
ctx,
|
|
187
|
+
cfg.gitcodeOwner,
|
|
188
|
+
cfg.gitcodeRepo,
|
|
189
|
+
"Translations.json",
|
|
190
|
+
cfg.gitcodeApiToken
|
|
191
|
+
) : Promise.resolve([])
|
|
192
|
+
]);
|
|
193
|
+
const translationMap = /* @__PURE__ */ new Map();
|
|
194
|
+
for (const { english, chinese } of gitcodeTranslations) {
|
|
195
|
+
translationMap.set(english.toLowerCase(), chinese);
|
|
196
|
+
}
|
|
197
|
+
for (const { english, chinese } of wikiTranslations) {
|
|
198
|
+
translationMap.set(english.toLowerCase(), chinese);
|
|
199
|
+
}
|
|
200
|
+
const lowerSearchStr = searchStr.toLowerCase();
|
|
201
|
+
const matches = [];
|
|
202
|
+
for (const [englishLower, chinese] of translationMap.entries()) {
|
|
203
|
+
if (lowerSearchStr.includes(englishLower)) {
|
|
204
|
+
const originalEnglish = [...wikiTranslations, ...gitcodeTranslations].find(
|
|
205
|
+
(t) => t.english.toLowerCase() === englishLower
|
|
206
|
+
)?.english || englishLower;
|
|
207
|
+
matches.push({ english: originalEnglish, chinese });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
106
210
|
return matches.map(({ english, chinese }) => `${english}: ${chinese}`).join("\n");
|
|
107
211
|
} catch (error) {
|
|
108
|
-
ctx.logger("
|
|
109
|
-
"Failed to
|
|
212
|
+
ctx.logger("translation-extractor").warn(
|
|
213
|
+
"Failed to extract translations:",
|
|
110
214
|
error
|
|
111
215
|
);
|
|
112
|
-
return;
|
|
216
|
+
return "";
|
|
113
217
|
}
|
|
114
218
|
}
|
|
115
219
|
|
|
116
220
|
// src/prompt-const.ts
|
|
117
|
-
async function getSustemPrompt(ctx, searchStr) {
|
|
118
|
-
const translations = await extractTranslations(ctx, searchStr);
|
|
221
|
+
async function getSustemPrompt(ctx, cfg, searchStr) {
|
|
222
|
+
const translations = await extractTranslations(ctx, cfg, searchStr);
|
|
119
223
|
return `
|
|
120
224
|
# Role: Minecraft Update Log JSON Summarization Specialist
|
|
121
225
|
|
|
@@ -137,7 +241,7 @@ async function getSustemPrompt(ctx, searchStr) {
|
|
|
137
241
|
|
|
138
242
|
2. Localization and Format Governance
|
|
139
243
|
- Chinese Composition: Use fluent Chinese throughout, retaining necessary English proper nouns.
|
|
140
|
-
- Terminology Standards: Use community/official translations; retain English terms for internal mechanisms to prevent mistranslation
|
|
244
|
+
- Terminology Standards: Use community/official translations; retain English terms for internal mechanisms to prevent mistranslation.
|
|
141
245
|
- Emoji Selection: Choose intuitive, non-duplicated emojis for subcategories to enhance recognition and readability.
|
|
142
246
|
|
|
143
247
|
## Rules
|
|
@@ -146,7 +250,8 @@ async function getSustemPrompt(ctx, searchStr) {
|
|
|
146
250
|
- Chinese Output: Use fluent Chinese for all entries unless the English term is untranslatable proprietary nomenclature.
|
|
147
251
|
- Concise Sentences: Keep each entry under \u201Cgeneral\u201D and \u201Citems\u201D within 50-100 characters, ensuring complete and readable meaning.
|
|
148
252
|
- Accurate Categorization: Strictly map to five major categories, avoiding cross-classification or overly broad descriptions.
|
|
149
|
-
- Terminology Standards: Use standardized translations below whenever possible; e.g.,
|
|
253
|
+
- Terminology Standards: Use standardized translations below whenever possible; e.g.,
|
|
254
|
+
${translations}
|
|
150
255
|
|
|
151
256
|
2. Behavioral Guidelines:
|
|
152
257
|
- Merge Similar Updates: Consolidate duplicate or highly similar updates into a single entry, highlighting core changes.
|
|
@@ -165,7 +270,7 @@ async function getSustemPrompt(ctx, searchStr) {
|
|
|
165
270
|
- Step 1: Parse the original text, extract all changes, and preliminarily label them as new additions, optimizations, balancing, fixes, or technical changes.
|
|
166
271
|
- Step 2: Create subcategories (2-6 per category) based on thematic clustering and scope of impact; assign unique emojis to each subcategory.
|
|
167
272
|
- Step 3: Assign remaining scattered entries to general; merge and deduplicate redundant or similar content.
|
|
168
|
-
- Step 4: Perform Chinese localization and terminology proofreading; retain necessary English proper nouns. Example: Lunge \u2192 \u7A81\u8FDB;
|
|
273
|
+
- Step 4: Perform Chinese localization and terminology proofreading; retain necessary English proper nouns. Example: Lunge \u2192 \u7A81\u8FDB;
|
|
169
274
|
- Step 5: Build JSON, validating structure keys, subcategory names, Emoji uniqueness, entry length, and deduplication.
|
|
170
275
|
- Expected result: Produce structured JSON containing only five major categories, with concise Chinese entries, logical grouping, standardized spacing, unique Emojis, and readiness for group chats and publishing.
|
|
171
276
|
|
|
@@ -206,7 +311,7 @@ async function getSustemPrompt(ctx, searchStr) {
|
|
|
206
311
|
|
|
207
312
|
2. Localization and Format Governance
|
|
208
313
|
- Chinese Composition: Use fluent Chinese throughout, retaining necessary English proper nouns.
|
|
209
|
-
- Terminology Standards: Use community/official translations; retain English terms for internal mechanisms to prevent mistranslation
|
|
314
|
+
- Terminology Standards: Use community/official translations; retain English terms for internal mechanisms to prevent mistranslation.
|
|
210
315
|
- Emoji Selection: Choose intuitive, non-duplicated emojis for subcategories to enhance recognition and readability.
|
|
211
316
|
|
|
212
317
|
## Rules
|
|
@@ -234,7 +339,7 @@ async function getSustemPrompt(ctx, searchStr) {
|
|
|
234
339
|
- Step 1: Parse the original text, extract all changes, and preliminarily label them as new additions, optimizations, balancing, fixes, or technical changes.
|
|
235
340
|
- Step 2: Create subcategories (2-6 per category) based on thematic clustering and scope of impact; assign unique emojis to each subcategory.
|
|
236
341
|
- Step 3: Assign remaining scattered entries to general; merge and deduplicate redundant or similar content.
|
|
237
|
-
- Step 4: Perform Chinese localization and terminology proofreading; retain necessary English proper nouns. Example: Lunge \u2192 \u7A81\u8FDB
|
|
342
|
+
- Step 4: Perform Chinese localization and terminology proofreading; retain necessary English proper nouns. Example: Lunge \u2192 \u7A81\u8FDB;.
|
|
238
343
|
- Step 5: Build JSON, validating structure keys, subcategory names, Emoji uniqueness, entry length, and deduplication.
|
|
239
344
|
- Expected result: Produce structured JSON containing only five major categories, with concise Chinese entries, logical grouping, standardized spacing, unique Emojis, and readiness for group chats and publishing.
|
|
240
345
|
|
|
@@ -304,58 +409,45 @@ var import_autocorrect_node = require("autocorrect-node");
|
|
|
304
409
|
var import_node_fs = require("node:fs");
|
|
305
410
|
var import_node_path = __toESM(require("node:path"), 1);
|
|
306
411
|
|
|
307
|
-
// src/
|
|
412
|
+
// src/git-platform-helper.ts
|
|
308
413
|
var import_axios2 = __toESM(require("axios"), 1);
|
|
309
|
-
|
|
414
|
+
var PLATFORM_CONFIG = {
|
|
415
|
+
["gitee" /* GITEE */]: {
|
|
416
|
+
baseUrl: "https://gitee.com/api/v5",
|
|
417
|
+
name: "Gitee"
|
|
418
|
+
},
|
|
419
|
+
["gitcode" /* GITCODE */]: {
|
|
420
|
+
baseUrl: "https://api.gitcode.com/api/v5",
|
|
421
|
+
name: "GitCode"
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
async function upsertFileToGitPlatform(ctx, platform, params) {
|
|
425
|
+
const {
|
|
426
|
+
owner,
|
|
427
|
+
repo,
|
|
428
|
+
path: path3,
|
|
429
|
+
content,
|
|
430
|
+
message,
|
|
431
|
+
token,
|
|
432
|
+
branch = "master"
|
|
433
|
+
} = params;
|
|
434
|
+
const config = PLATFORM_CONFIG[platform];
|
|
435
|
+
const loggerName = `${platform}-uploader`;
|
|
310
436
|
const base64Content = Buffer.from(content, "utf-8").toString("base64");
|
|
311
|
-
const checkUrl =
|
|
437
|
+
const checkUrl = `${config.baseUrl}/repos/${owner}/${repo}/contents/${path3}`;
|
|
312
438
|
let fileSha = null;
|
|
313
439
|
try {
|
|
314
|
-
const checkResponse = await import_axios2.default.get(checkUrl
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
} else {
|
|
322
|
-
ctx.logger("minecraft-notifier").warn(
|
|
323
|
-
`Unexpected status code when checking file: ${checkResponse.status}`
|
|
324
|
-
);
|
|
325
|
-
throw new Error(`Unexpected status: ${checkResponse.status}`);
|
|
440
|
+
const checkResponse = await import_axios2.default.get(checkUrl, {
|
|
441
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
442
|
+
params: { ref: branch, access_token: token }
|
|
443
|
+
});
|
|
444
|
+
if (checkResponse.status === 200 && checkResponse.data?.sha) {
|
|
445
|
+
fileSha = checkResponse.data.sha;
|
|
326
446
|
}
|
|
327
447
|
} catch (checkError) {
|
|
328
|
-
if (checkError.response?.status
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
const createResponse = await import_axios2.default.post(
|
|
332
|
-
createUrl2,
|
|
333
|
-
{
|
|
334
|
-
access_token: token,
|
|
335
|
-
content: base64Content,
|
|
336
|
-
message,
|
|
337
|
-
branch
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
headers: {
|
|
341
|
-
"Content-Type": "application/json"
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
);
|
|
345
|
-
return { success: true, data: createResponse };
|
|
346
|
-
} catch (createError) {
|
|
347
|
-
ctx.logger("minecraft-notifier").warn(
|
|
348
|
-
"Gitee Create Error:",
|
|
349
|
-
createError.response?.data || createError.message
|
|
350
|
-
);
|
|
351
|
-
return {
|
|
352
|
-
success: false,
|
|
353
|
-
error: createError.response?.data?.message || createError.message
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
} else {
|
|
357
|
-
ctx.logger("minecraft-notifier").warn(
|
|
358
|
-
"Gitee Check Error:",
|
|
448
|
+
if (checkError.response?.status !== 404) {
|
|
449
|
+
ctx.logger(loggerName).warn(
|
|
450
|
+
`${config.name} Check Error:`,
|
|
359
451
|
checkError.response?.data || checkError.message
|
|
360
452
|
);
|
|
361
453
|
return {
|
|
@@ -364,64 +456,62 @@ async function upsertFileToGitee(ctx, owner, repo, path3, content, message, toke
|
|
|
364
456
|
};
|
|
365
457
|
}
|
|
366
458
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
message,
|
|
377
|
-
branch
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
headers: {
|
|
381
|
-
"Content-Type": "application/json"
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
);
|
|
385
|
-
return { success: true, data: updateResponse };
|
|
386
|
-
} catch (updateError) {
|
|
387
|
-
ctx.logger("minecraft-notifier").warn(
|
|
388
|
-
"Gitee Update Error:",
|
|
389
|
-
updateError.response?.data || updateError.message
|
|
390
|
-
);
|
|
391
|
-
return {
|
|
392
|
-
success: false,
|
|
393
|
-
error: updateError.response?.data?.message || updateError.message
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
const createUrl = `https://gitee.com/api/v5/repos/${owner}/${repo}/contents/${path3}`;
|
|
459
|
+
const apiUrl = `${config.baseUrl}/repos/${owner}/${repo}/contents/${path3}`;
|
|
460
|
+
const requestBody = {
|
|
461
|
+
access_token: token,
|
|
462
|
+
content: base64Content,
|
|
463
|
+
message,
|
|
464
|
+
branch,
|
|
465
|
+
...fileSha && { sha: fileSha }
|
|
466
|
+
// 如果存在 SHA,则添加到请求体
|
|
467
|
+
};
|
|
398
468
|
try {
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
content: base64Content,
|
|
404
|
-
message,
|
|
405
|
-
branch
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
headers: {
|
|
409
|
-
"Content-Type": "application/json"
|
|
410
|
-
}
|
|
469
|
+
const response = fileSha ? await import_axios2.default.put(apiUrl, requestBody, {
|
|
470
|
+
headers: {
|
|
471
|
+
"Content-Type": "application/json",
|
|
472
|
+
Authorization: `Bearer ${token}`
|
|
411
473
|
}
|
|
412
|
-
)
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
474
|
+
}) : await import_axios2.default.post(apiUrl, requestBody, {
|
|
475
|
+
headers: {
|
|
476
|
+
"Content-Type": "application/json",
|
|
477
|
+
Authorization: `Bearer ${token}`
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
return { success: true, data: response };
|
|
481
|
+
} catch (error) {
|
|
482
|
+
const operation = fileSha ? "Update" : "Create";
|
|
483
|
+
ctx.logger(loggerName).warn(
|
|
484
|
+
`${config.name} ${operation} Error:`,
|
|
485
|
+
error.response?.data || error.message
|
|
418
486
|
);
|
|
419
487
|
return {
|
|
420
488
|
success: false,
|
|
421
|
-
error:
|
|
489
|
+
error: error.response?.data?.message || error.message
|
|
422
490
|
};
|
|
423
491
|
}
|
|
424
492
|
}
|
|
493
|
+
async function upsertFileToGitee(ctx, owner, repo, path3, content, message, token, branch = "master") {
|
|
494
|
+
return upsertFileToGitPlatform(ctx, "gitee" /* GITEE */, {
|
|
495
|
+
owner,
|
|
496
|
+
repo,
|
|
497
|
+
path: path3,
|
|
498
|
+
content,
|
|
499
|
+
message,
|
|
500
|
+
token,
|
|
501
|
+
branch
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
async function upsertFileToGitCode(ctx, owner, repo, path3, content, message, token, branch = "master") {
|
|
505
|
+
return upsertFileToGitPlatform(ctx, "gitcode" /* GITCODE */, {
|
|
506
|
+
owner,
|
|
507
|
+
repo,
|
|
508
|
+
path: path3,
|
|
509
|
+
content,
|
|
510
|
+
message,
|
|
511
|
+
token,
|
|
512
|
+
branch
|
|
513
|
+
});
|
|
514
|
+
}
|
|
425
515
|
|
|
426
516
|
// src/xaml-generator.ts
|
|
427
517
|
function generateXaml(summary, version) {
|
|
@@ -572,10 +662,12 @@ async function exportXaml(ctx, cfg, summary, version) {
|
|
|
572
662
|
"master"
|
|
573
663
|
).then((result) => {
|
|
574
664
|
if (result.success) {
|
|
575
|
-
ctx.logger("minecraft-notifier").info(
|
|
665
|
+
ctx.logger("minecraft-notifier").info(
|
|
666
|
+
"Upsert successful of gitee."
|
|
667
|
+
);
|
|
576
668
|
} else {
|
|
577
669
|
ctx.logger("minecraft-notifier").warn(
|
|
578
|
-
"Upsert failed:",
|
|
670
|
+
"Upsert failed of gitee:",
|
|
579
671
|
result.error
|
|
580
672
|
);
|
|
581
673
|
}
|
|
@@ -591,6 +683,39 @@ async function exportXaml(ctx, cfg, summary, version) {
|
|
|
591
683
|
"master"
|
|
592
684
|
);
|
|
593
685
|
}
|
|
686
|
+
if (cfg.gitcodeApiToken && cfg.gitcodeOwner && cfg.gitcodeRepo) {
|
|
687
|
+
await upsertFileToGitCode(
|
|
688
|
+
ctx,
|
|
689
|
+
cfg.gitcodeOwner,
|
|
690
|
+
cfg.gitcodeRepo,
|
|
691
|
+
"Custom.xaml",
|
|
692
|
+
xaml,
|
|
693
|
+
`feat: update PCL HomePage XAML for version ${version}`,
|
|
694
|
+
cfg.gitcodeApiToken,
|
|
695
|
+
"master"
|
|
696
|
+
).then((result) => {
|
|
697
|
+
if (result.success) {
|
|
698
|
+
ctx.logger("minecraft-notifier").info(
|
|
699
|
+
"Upsert successful of gitcode."
|
|
700
|
+
);
|
|
701
|
+
} else {
|
|
702
|
+
ctx.logger("minecraft-notifier").warn(
|
|
703
|
+
"Upsert failed of gitcode:",
|
|
704
|
+
result.error
|
|
705
|
+
);
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
await upsertFileToGitCode(
|
|
709
|
+
ctx,
|
|
710
|
+
cfg.gitcodeOwner,
|
|
711
|
+
cfg.gitcodeRepo,
|
|
712
|
+
"Custom.xaml.ini",
|
|
713
|
+
version,
|
|
714
|
+
`feat: update PCL HomePage XAML INI for version ${version}`,
|
|
715
|
+
cfg.gitcodeApiToken,
|
|
716
|
+
"master"
|
|
717
|
+
);
|
|
718
|
+
}
|
|
594
719
|
return fullXamlPath;
|
|
595
720
|
}
|
|
596
721
|
|
|
@@ -702,6 +827,7 @@ ${updateContent}
|
|
|
702
827
|
role: "system",
|
|
703
828
|
content: await getSustemPrompt(
|
|
704
829
|
ctx,
|
|
830
|
+
cfg,
|
|
705
831
|
updateContent.toLowerCase()
|
|
706
832
|
)
|
|
707
833
|
},
|
|
@@ -912,7 +1038,10 @@ var Config = import_koishi.Schema.object({
|
|
|
912
1038
|
notifyChannel: import_koishi.Schema.array(String).default([]).description("\u7528\u4E8E\u63A5\u6536\u66F4\u65B0\u901A\u77E5\u7684\u9891\u9053 ID \u5217\u8868"),
|
|
913
1039
|
giteeApiToken: import_koishi.Schema.string().role("secret").default("").description("Gitee API \u8BBF\u95EE\u4EE4\u724C\uFF0C\u7528\u4E8E\u4E0A\u4F20 XAML \u6587\u4EF6"),
|
|
914
1040
|
giteeOwner: import_koishi.Schema.string().default("").description("Gitee \u4ED3\u5E93\u6240\u6709\u8005\u7528\u6237\u540D"),
|
|
915
|
-
giteeRepo: import_koishi.Schema.string().default("").description("Gitee \u4ED3\u5E93\u540D\u79F0")
|
|
1041
|
+
giteeRepo: import_koishi.Schema.string().default("").description("Gitee \u4ED3\u5E93\u540D\u79F0"),
|
|
1042
|
+
gitcodeApiToken: import_koishi.Schema.string().role("secret").default("").description("GitCode API \u8BBF\u95EE\u4EE4\u724C\uFF0C\u7528\u4E8E\u4E0A\u4F20 XAML \u6587\u4EF6"),
|
|
1043
|
+
gitcodeOwner: import_koishi.Schema.string().default("").description("GitCode \u4ED3\u5E93\u6240\u6709\u8005\u7528\u6237\u540D"),
|
|
1044
|
+
gitcodeRepo: import_koishi.Schema.string().default("").description("GitCode \u4ED3\u5E93\u540D\u79F0")
|
|
916
1045
|
});
|
|
917
1046
|
function apply(ctx, cfg) {
|
|
918
1047
|
ctx.database.extend(
|
|
@@ -1014,6 +1143,11 @@ function apply(ctx, cfg) {
|
|
|
1014
1143
|
await checkNewVersionArticle(ctx, cfg);
|
|
1015
1144
|
}
|
|
1016
1145
|
);
|
|
1146
|
+
ctx.command("mc.trigger.gitcode", "\u624B\u52A8\u89E6\u53D1 AI \u66F4\u65B0\u65E5\u5FD7\u603B\u7ED3\u751F\u6210").action(
|
|
1147
|
+
async () => {
|
|
1148
|
+
return await getSustemPrompt(ctx, cfg, "jab attack");
|
|
1149
|
+
}
|
|
1150
|
+
);
|
|
1017
1151
|
ctx.setInterval(async () => {
|
|
1018
1152
|
try {
|
|
1019
1153
|
await loadData();
|
package/lib/index.d.ts
CHANGED
|
@@ -37,6 +37,9 @@ export interface Config {
|
|
|
37
37
|
giteeApiToken?: string;
|
|
38
38
|
giteeOwner?: string;
|
|
39
39
|
giteeRepo?: string;
|
|
40
|
+
gitcodeApiToken?: string;
|
|
41
|
+
gitcodeOwner?: string;
|
|
42
|
+
gitcodeRepo?: string;
|
|
40
43
|
}
|
|
41
44
|
export declare const Config: Schema<Config>;
|
|
42
45
|
export declare function apply(ctx: Context, cfg: Config & {
|
package/lib/prompt-const.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
import { Context } from 'koishi';
|
|
2
|
-
|
|
2
|
+
import { Config } from './index';
|
|
3
|
+
/**
|
|
4
|
+
* 提取所有翻译(从 Wiki 和 GitCode)
|
|
5
|
+
* @param ctx - Koishi 上下文
|
|
6
|
+
* @param cfg - 配置选项
|
|
7
|
+
* @param searchStr - 搜索字符串
|
|
8
|
+
* @returns Promise<string> 格式化的翻译结果
|
|
9
|
+
*/
|
|
10
|
+
export declare function extractTranslations(ctx: Context, cfg: Config, searchStr: string): Promise<string>;
|
package/package.json
CHANGED
package/lib/gitee-helper.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { AxiosResponse } from 'axios';
|
|
2
|
-
import { Context } from 'koishi';
|
|
3
|
-
/**
|
|
4
|
-
* 上传或更新 Gitee 仓库中的文本文件(如果不存在则创建,如果存在则更新)
|
|
5
|
-
* @param ctx
|
|
6
|
-
* @param owner - 仓库所有者用户名
|
|
7
|
-
* @param repo - 仓库名称
|
|
8
|
-
* @param path - 文件路径(例如 'docs/update.txt')
|
|
9
|
-
* @param content - 文件内容(纯文本字符串,会自动 Base64 编码)
|
|
10
|
-
* @param message - Commit 消息
|
|
11
|
-
* @param token - Gitee Personal Access Token
|
|
12
|
-
* @param branch - 分支名(默认 'master')
|
|
13
|
-
* @returns Promise<{ success: boolean; data?: AxiosResponse; error?: string }>
|
|
14
|
-
*/
|
|
15
|
-
export declare function upsertFileToGitee(ctx: Context, owner: string, repo: string, path: string, content: string, message: string, token: string, branch?: string): Promise<{
|
|
16
|
-
success: boolean;
|
|
17
|
-
data?: AxiosResponse;
|
|
18
|
-
error?: string;
|
|
19
|
-
}>;
|