feat: destroy file cache from raw or url

This commit is contained in:
Wesley F. Young 2024-09-07 10:15:35 +08:00
parent 7a5d7dd49e
commit 897e5a6f61
3 changed files with 59 additions and 16 deletions

View File

@ -11,30 +11,39 @@ export class LaanaMessageActionHandler {
impl: LaanaActionHandler = { impl: LaanaActionHandler = {
sendMessage: async (params) => { sendMessage: async (params) => {
const { elements, fileCacheIds } = await this.laana.utils.msg.laanaMessageToRaw(params.message!, params); const { elements, fileCacheRecords } = await this.laana.utils.msg.laanaMessageToRaw(params.message!, params);
let cacheSize = 0; let cacheSize = 0;
try { try {
for (const cacheId of fileCacheIds) { for (const cacheRecord of fileCacheRecords) {
cacheSize += fs.statSync(await this.laana.utils.file.toLocalPath(cacheId)).size; cacheSize += fs.statSync(await this.laana.utils.file.toLocalPath(cacheRecord.cacheId)).size;
} }
} catch (e) { } catch (e) {
this.core.context.logger.logWarn('文件缓存大小计算失败', e); this.core.context.logger.logWarn('文件缓存大小计算失败', e);
} }
const estimatedSendMsgTimeout = const estimatedSendMsgTimeout =
cacheSize / 1024 / 256 * 1000 + // file upload time cacheSize / 1024 / 256 * 1000 + // file upload time
1000 * fileCacheIds.length + // request timeout 1000 * fileCacheRecords.length + // request timeout
10000; // fallback timeout 10000; // fallback timeout
const sentMsg = await this.core.apis.MsgApi.sendMsg(
const sentMsgOrEmpty = await this.core.apis.MsgApi.sendMsg(
await this.laana.utils.msg.laanaPeerToRaw(params.targetPeer!), await this.laana.utils.msg.laanaPeerToRaw(params.targetPeer!),
elements, elements,
true, // TODO: add 'wait complete' (bool) field true, // TODO: add 'wait complete' (bool) field
estimatedSendMsgTimeout, estimatedSendMsgTimeout,
); );
if (!sentMsg) {
fileCacheRecords.forEach(record => {
if (record.originalType !== 'cacheId') {
this.laana.utils.file.destroyCache(record.cacheId);
}
});
if (!sentMsgOrEmpty) {
throw Error('消息发送失败'); throw Error('消息发送失败');
} }
return { return {
msgId: sentMsg.msgId msgId: sentMsgOrEmpty.msgId
}; };
} }
}; };

View File

@ -83,4 +83,17 @@ export class LaanaFileUtils {
fileElementId fileElementId
}; };
} }
async destroyCache(cacheId: string) {
const cachePath = path.join(this.cacheDir, cacheId);
const stat = await fsPromises.stat(cachePath);
if (stat.isFile()) {
await fsPromises.unlink(cachePath);
} else if (stat.isSymbolicLink()) {
await fsPromises.unlink(cachePath);
await fsPromises.unlink(await fsPromises.readlink(cachePath));
} else {
throw Error('不支持的缓存类型');
}
}
} }

View File

@ -12,8 +12,14 @@ import {
import { NapCatLaanaAdapter } from '..'; import { NapCatLaanaAdapter } from '..';
import { OutgoingMessage, SendMessagePing } from '../types/action/message'; import { OutgoingMessage, SendMessagePing } from '../types/action/message';
import { Bubble, Message as LaanaMessage, Peer as LaanaPeer, Peer_Type } from '../types/entity/message'; import { Bubble, Message as LaanaMessage, Peer as LaanaPeer, Peer_Type } from '../types/entity/message';
import { File } from '../types/entity/file';
import faceConfig from '@/core/external/face_config.json'; import faceConfig from '@/core/external/face_config.json';
export type SentMessageFileCacheRecord = {
originalType: File['uri']['oneofKind'],
cacheId: string,
};
type Laana2RawConverters = { type Laana2RawConverters = {
[key in Exclude<OutgoingMessage['content']['oneofKind'], undefined>]: [key in Exclude<OutgoingMessage['content']['oneofKind'], undefined>]:
( (
@ -23,7 +29,7 @@ type Laana2RawConverters = {
params: SendMessagePing, params: SendMessagePing,
) => PromiseLike<{ ) => PromiseLike<{
elements: SendMessageElement[], elements: SendMessageElement[],
fileCacheIds: string[], fileCacheRecords: SentMessageFileCacheRecord[],
}> }>
} }
@ -51,7 +57,7 @@ export class LaanaMessageUtils {
} }
const elements: SendMessageElement[] = []; const elements: SendMessageElement[] = [];
const fileCacheIds: string[] = []; const fileCacheRecords: SentMessageFileCacheRecord[] = [];
if (msgContent.repliedMsgId) { if (msgContent.repliedMsgId) {
const replyMsg = ( const replyMsg = (
@ -155,13 +161,16 @@ export class LaanaMessageUtils {
elements.push(await this.core.apis.FileApi.createValidSendPicElement( elements.push(await this.core.apis.FileApi.createValidSendPicElement(
await this.laana.utils.file.toLocalPath(cacheId) await this.laana.utils.file.toLocalPath(cacheId)
)); ));
fileCacheIds.push(cacheId); fileCacheRecords.push({
originalType: content.image.uri.oneofKind,
cacheId,
});
} else { } else {
throw Error('未知的消息内容类型'); throw Error('未知的消息内容类型');
} }
} }
return { elements, fileCacheIds }; return { elements, fileCacheRecords };
}, },
file: async msgContent => { file: async msgContent => {
@ -173,7 +182,10 @@ export class LaanaMessageUtils {
msgContent.name, msgContent.name,
), ),
], ],
fileCacheIds: [cacheId], fileCacheRecords: [{
originalType: msgContent.file!.uri.oneofKind,
cacheId,
}],
}; };
}, },
@ -187,7 +199,10 @@ export class LaanaMessageUtils {
// TODO: add 'sub type' field // TODO: add 'sub type' field
) )
], ],
fileCacheIds: [cacheId], fileCacheRecords: [{
originalType: msgContent.image!.uri.oneofKind,
cacheId,
}],
}; };
}, },
@ -201,7 +216,7 @@ export class LaanaMessageUtils {
faceName: msgContent.displayText ?? '[商城表情]', faceName: msgContent.displayText ?? '[商城表情]',
}, },
}], }],
fileCacheIds: [], fileCacheRecords: [],
}), }),
video: async msgContent => { video: async msgContent => {
@ -213,7 +228,10 @@ export class LaanaMessageUtils {
// TODO: add file name and thumb path // TODO: add file name and thumb path
), ),
], ],
fileCacheIds: [cacheId], fileCacheRecords: [{
originalType: msgContent.uri.oneofKind,
cacheId,
}],
}; };
}, },
@ -225,7 +243,10 @@ export class LaanaMessageUtils {
await this.laana.utils.file.toLocalPath(cacheId), await this.laana.utils.file.toLocalPath(cacheId),
) )
], ],
fileCacheIds: [cacheId], fileCacheRecords: [{
originalType: msgContent.uri.oneofKind,
cacheId,
}],
}; };
}, },