From 5f30e4c2524b4b0ae11c68df748f99dc8e50ccf3 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Fri, 6 Sep 2024 20:39:27 +0800 Subject: [PATCH] feat: file by element id --- src/laana-v0.2.0/utils/file.ts | 47 +++++++++++++++++++++++++++---- src/laana-v0.2.0/utils/message.ts | 12 ++++---- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/laana-v0.2.0/utils/file.ts b/src/laana-v0.2.0/utils/file.ts index 8ab77544..003e1350 100644 --- a/src/laana-v0.2.0/utils/file.ts +++ b/src/laana-v0.2.0/utils/file.ts @@ -1,4 +1,4 @@ -import { NapCatCore } from '@/core'; +import { ChatType, FileElement, NapCatCore } from '@/core'; import { NapCatLaanaAdapter } from '..'; import { File as LaanaFile } from '../types/entity/file'; import path from 'path'; @@ -18,10 +18,6 @@ export class LaanaFileUtils { async resolveCacheIdFromLaanaFile(laanaFile: LaanaFile) { if (laanaFile.uri.oneofKind === 'cacheId') { - const cacheFilePath = path.join(this.cacheDir, laanaFile.uri.cacheId); - if (!fs.existsSync(cacheFilePath)) { - throw Error(`请求的缓存不存在: ${laanaFile.uri.cacheId}`); - } return laanaFile.uri.cacheId; } else if (laanaFile.uri.oneofKind === 'url') { return this.createCacheFromUrl(laanaFile.uri.url); @@ -32,7 +28,24 @@ export class LaanaFileUtils { } } - toLocalPath(cacheId: string) { + async toLocalPath(cacheId: string, forceRevalidate = false) { + const cacheFilePath = path.join(this.cacheDir, cacheId); + if (!fs.existsSync(cacheFilePath) || forceRevalidate) { + if (cacheId.startsWith('@QQFileElement')) { + const { msgId, chatType, peerUid, fileElementId } = this.decodeFileElementCacheId(cacheId); + const downloadPath = await this.core.apis.FileApi.downloadMedia( + msgId, + chatType, + peerUid, + fileElementId, + '', + '', + ); + await fsPromises.symlink(downloadPath, cacheFilePath); + } else { + throw Error(`请求的缓存不存在: ${cacheId}`); + } + } return path.join(this.cacheDir, cacheId); } @@ -48,4 +61,26 @@ export class LaanaFileUtils { async createCacheFromUrl(url: string) { return this.createCacheFromBytes(await httpDownload({ url })); } + + encodeFileElementToCacheId( + msgId: string, + chatType: ChatType, + peerUid: string, + fileElementId: string + ) { + return `QQFileElement@${msgId}@${chatType}@${peerUid}@${fileElementId}`; + } + + decodeFileElementCacheId(cacheId: string) { + if (!cacheId.startsWith('QQFileElement')) { + throw Error('不支持的缓存 ID'); + } + const [, msgId, chatType, peerUid, fileElementId] = cacheId.split('@'); + return { + msgId, + chatType: parseInt(chatType), + peerUid, + fileElementId + }; + } } diff --git a/src/laana-v0.2.0/utils/message.ts b/src/laana-v0.2.0/utils/message.ts index 01f68c4d..36232b57 100644 --- a/src/laana-v0.2.0/utils/message.ts +++ b/src/laana-v0.2.0/utils/message.ts @@ -1,7 +1,7 @@ import { AtType, ChatType, ElementType, NapCatCore, Peer, SendMessageElement, SendTextElement } from '@/core'; import { NapCatLaanaAdapter } from '..'; import { OutgoingMessage, SendMessagePing } from '../types/action/message'; -import { Peer as LaanaPeer, Peer_Type } from '../types/entity/message'; +import { Bubble, Message as LaanaMessage, Peer as LaanaPeer, Peer_Type } from '../types/entity/message'; import faceConfig from '@/core/external/face_config.json'; type Laana2RawConverters = { @@ -143,7 +143,7 @@ export class LaanaMessageUtils { } else if (content.oneofKind === 'image') { const cacheId = await this.laana.utils.file.resolveCacheIdFromLaanaFile(content.image); elements.push(await this.core.apis.FileApi.createValidSendPicElement( - this.laana.utils.file.toLocalPath(cacheId) + await this.laana.utils.file.toLocalPath(cacheId) )); fileCacheIds.push(cacheId); } else { @@ -159,7 +159,7 @@ export class LaanaMessageUtils { return { elements: [ await this.core.apis.FileApi.createValidSendFileElement( - this.laana.utils.file.toLocalPath(cacheId), + await this.laana.utils.file.toLocalPath(cacheId), msgContent.name, ), ], @@ -172,7 +172,7 @@ export class LaanaMessageUtils { return { elements: [ await this.core.apis.FileApi.createValidSendPicElement( - this.laana.utils.file.toLocalPath(cacheId), + await this.laana.utils.file.toLocalPath(cacheId), msgContent.displayText, // TODO: make display text optional // TODO: add 'sub type' field ) @@ -199,7 +199,7 @@ export class LaanaMessageUtils { return { elements: [ await this.core.apis.FileApi.createValidSendVideoElement( - this.laana.utils.file.toLocalPath(cacheId), + await this.laana.utils.file.toLocalPath(cacheId), // TODO: add file name and thumb path ), ], @@ -212,7 +212,7 @@ export class LaanaMessageUtils { return { elements: [ await this.core.apis.FileApi.createValidSendPttElement( - this.laana.utils.file.toLocalPath(cacheId), + await this.laana.utils.file.toLocalPath(cacheId), ) ], fileCacheIds: [cacheId],