koishi-plugin-best-cave 2.6.4 → 2.6.6
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/Utils.d.ts +2 -1
- package/lib/index.js +36 -17
- package/package.json +2 -2
package/lib/Utils.d.ts
CHANGED
|
@@ -44,9 +44,10 @@ export declare function getNextCaveId(ctx: Context, reusableIds: Set<number>): P
|
|
|
44
44
|
* @param session 触发操作的会话。
|
|
45
45
|
* @param config 插件配置。
|
|
46
46
|
* @param logger 日志实例。
|
|
47
|
+
* @param creationTime 统一的创建时间戳,用于生成文件名。
|
|
47
48
|
* @returns 包含数据库元素和待保存媒体列表的对象。
|
|
48
49
|
*/
|
|
49
|
-
export declare function processMessageElements(sourceElements: h[], newId: number, session: Session, config: Config, logger: Logger): Promise<{
|
|
50
|
+
export declare function processMessageElements(sourceElements: h[], newId: number, session: Session, config: Config, logger: Logger, creationTime: Date): Promise<{
|
|
50
51
|
finalElementsForDb: StoredElement[];
|
|
51
52
|
mediaToSave: {
|
|
52
53
|
sourceUrl: string;
|
package/lib/index.js
CHANGED
|
@@ -249,9 +249,8 @@ var DataManager = class {
|
|
|
249
249
|
async exportData() {
|
|
250
250
|
const fileName = "cave_export.json";
|
|
251
251
|
const cavesToExport = await this.ctx.database.get("cave", { status: "active" });
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return `成功导出 ${portableCaves.length} 条数据`;
|
|
252
|
+
await this.fileManager.saveFile(fileName, Buffer.from(JSON.stringify(cavesToExport, null, 2)));
|
|
253
|
+
return `成功导出 ${cavesToExport.length} 条数据`;
|
|
255
254
|
}
|
|
256
255
|
/**
|
|
257
256
|
* @description 从 `cave_import.json` 文件导入回声洞数据。
|
|
@@ -267,15 +266,34 @@ var DataManager = class {
|
|
|
267
266
|
} catch (error) {
|
|
268
267
|
throw new Error(`读取导入文件失败: ${error.message}`);
|
|
269
268
|
}
|
|
270
|
-
const
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
269
|
+
const allDbCaves = await this.ctx.database.get("cave", {}, { fields: ["id"] });
|
|
270
|
+
const existingIds = new Set(allDbCaves.map((c) => c.id));
|
|
271
|
+
let maxId = allDbCaves.length > 0 ? Math.max(...allDbCaves.map((c) => c.id)) : 0;
|
|
272
|
+
const nonConflictingCaves = [];
|
|
273
|
+
const conflictingCaves = [];
|
|
274
|
+
let invalidCount = 0;
|
|
275
|
+
for (const importedCave of importedCaves) {
|
|
276
|
+
if (typeof importedCave.id !== "number" || !Array.isArray(importedCave.elements)) {
|
|
277
|
+
this.logger.warn(`回声洞(${importedCave.id})无效: ${JSON.stringify(importedCave)}`);
|
|
278
|
+
invalidCount++;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
if (existingIds.has(importedCave.id)) {
|
|
282
|
+
conflictingCaves.push(importedCave);
|
|
283
|
+
} else {
|
|
284
|
+
nonConflictingCaves.push({ ...importedCave, status: "active" });
|
|
285
|
+
existingIds.add(importedCave.id);
|
|
286
|
+
maxId = Math.max(maxId, importedCave.id);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const newCavesFromConflicts = conflictingCaves.map((cave) => {
|
|
290
|
+
maxId++;
|
|
291
|
+
this.logger.info(`回声洞(${cave.id})已转移至(${maxId})`);
|
|
292
|
+
return { ...cave, maxId, status: "active" };
|
|
293
|
+
});
|
|
294
|
+
const finalCavesToUpsert = [...nonConflictingCaves, ...newCavesFromConflicts];
|
|
295
|
+
if (finalCavesToUpsert.length > 0) await this.ctx.database.upsert("cave", finalCavesToUpsert);
|
|
296
|
+
return `成功导入 ${finalCavesToUpsert.length} 条数据`;
|
|
279
297
|
}
|
|
280
298
|
};
|
|
281
299
|
|
|
@@ -439,7 +457,7 @@ async function getNextCaveId(ctx, reusableIds) {
|
|
|
439
457
|
return newId;
|
|
440
458
|
}
|
|
441
459
|
__name(getNextCaveId, "getNextCaveId");
|
|
442
|
-
async function processMessageElements(sourceElements, newId, session, config, logger2) {
|
|
460
|
+
async function processMessageElements(sourceElements, newId, session, config, logger2, creationTime) {
|
|
443
461
|
const mediaToSave = [];
|
|
444
462
|
let mediaIndex = 0;
|
|
445
463
|
const typeMap = { "img": "image", "image": "image", "video": "video", "audio": "audio", "file": "file", "text": "text", "at": "at", "forward": "forward", "reply": "reply", "face": "face" };
|
|
@@ -462,7 +480,7 @@ async function processMessageElements(sourceElements, newId, session, config, lo
|
|
|
462
480
|
if (fileIdentifier.startsWith("http")) {
|
|
463
481
|
const ext = path2.extname(segment.data.file || "") || defaultExtMap[sType];
|
|
464
482
|
const currentMediaIndex = ++mediaIndex;
|
|
465
|
-
const fileName = `${newId}_${currentMediaIndex}_${session.channelId || session.guildId}_${session.userId}${ext}`;
|
|
483
|
+
const fileName = `${newId}_${currentMediaIndex}_${session.channelId || session.guildId}_${session.userId}_${creationTime.getTime()}${ext}`;
|
|
466
484
|
mediaToSave.push({ sourceUrl: fileIdentifier, fileName });
|
|
467
485
|
fileIdentifier = fileName;
|
|
468
486
|
}
|
|
@@ -509,7 +527,7 @@ async function processMessageElements(sourceElements, newId, session, config, lo
|
|
|
509
527
|
if (fileIdentifier.startsWith("http")) {
|
|
510
528
|
const ext = path2.extname(el.attrs.file || "") || defaultExtMap[type];
|
|
511
529
|
const currentMediaIndex = ++mediaIndex;
|
|
512
|
-
const fileName = `${newId}_${
|
|
530
|
+
const fileName = `${newId}_${creationTime.getTime()}_${currentMediaIndex}_${session.userId}${ext}`;
|
|
513
531
|
mediaToSave.push({ sourceUrl: fileIdentifier, fileName });
|
|
514
532
|
fileIdentifier = fileName;
|
|
515
533
|
}
|
|
@@ -1051,7 +1069,8 @@ function apply(ctx, config) {
|
|
|
1051
1069
|
sourceElements = import_koishi3.h.parse(reply);
|
|
1052
1070
|
}
|
|
1053
1071
|
const newId = await getNextCaveId(ctx, reusableIds);
|
|
1054
|
-
const
|
|
1072
|
+
const creationTime = /* @__PURE__ */ new Date();
|
|
1073
|
+
const { finalElementsForDb, mediaToSave } = await processMessageElements(sourceElements, newId, session, config, logger, creationTime);
|
|
1055
1074
|
if (finalElementsForDb.length === 0) return "无可添加内容";
|
|
1056
1075
|
const textHashesToStore = [];
|
|
1057
1076
|
if (hashManager) {
|
|
@@ -1079,7 +1098,7 @@ function apply(ctx, config) {
|
|
|
1079
1098
|
userId: session.userId,
|
|
1080
1099
|
userName,
|
|
1081
1100
|
status: initialStatus,
|
|
1082
|
-
time:
|
|
1101
|
+
time: creationTime
|
|
1083
1102
|
});
|
|
1084
1103
|
if (hasMedia) {
|
|
1085
1104
|
handleFileUploads(ctx, config, fileManager, logger, reviewManager, newCave, mediaToSave, reusableIds, session, hashManager, textHashesToStore);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-best-cave",
|
|
3
3
|
"description": "功能强大、高度可定制的回声洞。支持丰富的媒体类型、内容查重、人工审核、用户昵称、数据迁移以及本地/S3 双重文件存储后端。",
|
|
4
|
-
"version": "2.6.
|
|
4
|
+
"version": "2.6.6",
|
|
5
5
|
"contributors": [
|
|
6
6
|
"Yis_Rime <yis_rime@outlook.com>"
|
|
7
7
|
],
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@aws-sdk/client-s3": "^3.800.0",
|
|
32
|
-
"
|
|
32
|
+
"sharp": "^0.32.1"
|
|
33
33
|
}
|
|
34
34
|
}
|