TelegramBotApiLibraries/cache/content/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/media/common/DefaultMessageContentCache.kt

136 lines
5.2 KiB
Kotlin
Raw Normal View History

2022-03-22 12:52:23 +00:00
package dev.inmo.tgbotapi.libraries.cache.media.common
import dev.inmo.tgbotapi.bot.TelegramBot
2022-04-19 18:11:03 +00:00
import dev.inmo.tgbotapi.requests.DeleteMessage
2022-03-22 12:52:23 +00:00
import dev.inmo.tgbotapi.requests.DownloadFileStream
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.get.GetFile
import dev.inmo.tgbotapi.requests.send.media.*
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.InputMedia.*
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
2022-04-11 15:28:53 +00:00
import dev.inmo.tgbotapi.utils.asInput
import io.ktor.utils.io.core.Input
2022-03-22 12:52:23 +00:00
2022-04-11 17:32:06 +00:00
class DefaultMessageContentCache<K>(
2022-03-22 12:52:23 +00:00
private val bot: TelegramBot,
2022-04-11 15:28:53 +00:00
private val filesRefreshingChatId: ChatId,
2022-04-11 17:32:06 +00:00
private val simpleMessageContentCache: MessagesSimpleCache<K>,
2022-04-19 18:11:03 +00:00
private val mediaFileActualityChecker: MediaFileActualityChecker = MediaFileActualityChecker.WithDelay(
MediaFileActualityChecker.Default(filesRefreshingChatId)
),
2022-04-11 17:32:06 +00:00
private val messagesFilesCache: MessagesFilesCache<K> = InMemoryMessagesFilesCache()
) : MessageContentCache<K> {
override suspend fun save(content: MessageContent): K {
2022-04-11 15:28:53 +00:00
return when (content) {
is MediaContent -> {
2022-03-22 12:52:23 +00:00
val extendedInfo = bot.execute(
GetFile(content.media.fileId)
)
val allocator = bot.execute(
DownloadFileStream(
extendedInfo.filePath
)
)
2022-04-11 15:28:53 +00:00
2022-04-11 17:32:06 +00:00
save(content, extendedInfo.fileName) {
2022-04-11 15:28:53 +00:00
allocator.invoke().asInput()
}
2022-03-22 12:52:23 +00:00
}
2022-04-11 17:32:06 +00:00
else -> simpleMessageContentCache.add(content)
2022-04-11 15:28:53 +00:00
}
}
override suspend fun save(
content: MediaContent,
filename: String,
inputAllocator: suspend () -> Input
2022-04-11 17:32:06 +00:00
): K {
val key = simpleMessageContentCache.add(content)
2022-04-11 15:28:53 +00:00
runCatching {
2022-04-11 17:32:06 +00:00
messagesFilesCache.set(key, filename, inputAllocator)
2022-03-22 12:52:23 +00:00
}.onFailure {
2022-04-11 17:32:06 +00:00
simpleMessageContentCache.remove(key)
2022-04-19 18:19:25 +00:00
}.onSuccess {
with(mediaFileActualityChecker) {
bot.saved(content)
}
2022-03-22 12:52:23 +00:00
}
2022-04-11 17:32:06 +00:00
return key
2022-03-22 12:52:23 +00:00
}
2022-04-11 17:32:06 +00:00
override suspend fun get(k: K): MessageContent? {
val savedSimpleContent = simpleMessageContentCache.get(k) ?: return null
2022-03-22 12:52:23 +00:00
2022-04-19 18:11:03 +00:00
if (savedSimpleContent is MediaContent && !with(mediaFileActualityChecker) { bot.isActual(savedSimpleContent) }) {
val savedFileContentAllocator = messagesFilesCache.get(k) ?: error("Unexpected absence of $k file for content ($simpleMessageContentCache)")
val newContent = bot.execute(
when (savedSimpleContent.asInputMedia()) {
is InputMediaAnimation -> SendAnimation(
filesRefreshingChatId,
MultipartFile(
savedFileContentAllocator
),
disableNotification = true
)
is InputMediaAudio -> SendAudio(
filesRefreshingChatId,
MultipartFile(
savedFileContentAllocator
),
disableNotification = true
)
is InputMediaVideo -> SendVideo(
filesRefreshingChatId,
MultipartFile(
savedFileContentAllocator
),
disableNotification = true
)
is InputMediaDocument -> SendDocument(
filesRefreshingChatId,
MultipartFile(
savedFileContentAllocator
),
disableNotification = true
)
is InputMediaPhoto -> SendPhoto(
filesRefreshingChatId,
MultipartFile(
savedFileContentAllocator
),
disableNotification = true
)
}
)
2022-03-22 12:52:23 +00:00
2022-04-19 18:11:03 +00:00
simpleMessageContentCache.update(k, newContent.content)
return newContent.content
2022-03-22 12:52:23 +00:00
}
return savedSimpleContent
}
2022-04-11 17:32:06 +00:00
override suspend fun contains(k: K): Boolean {
return simpleMessageContentCache.contains(k)
2022-03-22 12:52:23 +00:00
}
2022-04-11 17:32:06 +00:00
override suspend fun remove(k: K) {
simpleMessageContentCache.remove(k)
messagesFilesCache.remove(k)
}
companion object {
operator fun invoke(
bot: TelegramBot,
filesRefreshingChatId: ChatId,
simpleMessageContentCache: MessagesSimpleCache<String> = InMemoryMessagesSimpleCache(),
2022-04-19 18:11:03 +00:00
mediaFileActualityChecker: MediaFileActualityChecker = MediaFileActualityChecker.WithDelay(
MediaFileActualityChecker.Default(filesRefreshingChatId)
),
2022-04-11 17:32:06 +00:00
messagesFilesCache: MessagesFilesCache<String> = InMemoryMessagesFilesCache()
2022-04-19 18:11:03 +00:00
) = DefaultMessageContentCache(bot, filesRefreshingChatId, simpleMessageContentCache, mediaFileActualityChecker, messagesFilesCache)
2022-03-22 12:52:23 +00:00
}
}