2022-03-22 12:52:23 +00:00
package dev.inmo.tgbotapi.libraries.cache.media.common
import dev.inmo.tgbotapi.bot.TelegramBot
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.MessageIdentifier
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
2022-03-22 12:52:23 +00:00
import io.ktor.utils.io.cancel
2022-04-11 15:28:53 +00:00
import io.ktor.utils.io.core.Input
2022-03-22 12:52:23 +00:00
2022-04-11 15:28:53 +00:00
class DefaultMessageContentCache (
2022-03-22 12:52:23 +00:00
private val bot : TelegramBot ,
2022-04-11 15:28:53 +00:00
private val filesRefreshingChatId : ChatId ,
private val simpleMessageContentCache : MessagesSimpleCache = InMemoryMessagesSimpleCache ( ) ,
private val messagesFilesCache : MessagesFilesCache = InMemoryMessagesFilesCache ( )
2022-03-22 12:52:23 +00:00
) : MessageContentCache {
override suspend fun save ( chatId : ChatId , messageId : MessageIdentifier , content : MessageContent ) : Boolean {
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
save ( chatId , messageId , content , extendedInfo . fileName ) {
allocator . invoke ( ) . asInput ( )
}
2022-03-22 12:52:23 +00:00
}
2022-04-11 15:28:53 +00:00
else -> simpleMessageContentCache . runCatching {
set ( chatId , messageId , content )
} . isSuccess
}
}
override suspend fun save (
chatId : ChatId ,
messageId : MessageIdentifier ,
content : MediaContent ,
filename : String ,
inputAllocator : suspend ( ) -> Input
) : Boolean {
runCatching {
messagesFilesCache . set ( chatId , messageId , filename , inputAllocator )
2022-03-22 12:52:23 +00:00
} . onFailure {
return false
}
2022-04-11 15:28:53 +00:00
return simpleMessageContentCache . runCatching {
set ( chatId , messageId , content )
} . isSuccess
2022-03-22 12:52:23 +00:00
}
override suspend fun get ( chatId : ChatId , messageId : MessageIdentifier ) : MessageContent ? {
val savedSimpleContent = simpleMessageContentCache . get ( chatId , messageId ) ?: return null
if ( savedSimpleContent is MediaContent ) {
runCatching {
2022-04-11 15:42:12 +00:00
bot . execute ( GetFile ( savedSimpleContent . media . fileId ) )
2022-03-22 12:52:23 +00:00
} . onFailure {
val savedFileContentAllocator = messagesFilesCache . get ( chatId , messageId ) ?: error ( " Unexpected absence of $chatId : $messageId 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-04-11 15:28:53 +00:00
simpleMessageContentCache . set ( chatId , messageId , newContent . content )
2022-03-22 12:52:23 +00:00
return newContent . content
}
}
return savedSimpleContent
}
override suspend fun contains ( chatId : ChatId , messageId : MessageIdentifier ) : Boolean {
return simpleMessageContentCache . contains ( chatId , messageId )
}
override suspend fun remove ( chatId : ChatId , messageId : MessageIdentifier ) {
simpleMessageContentCache . remove ( chatId , messageId )
messagesFilesCache . remove ( chatId , messageId )
}
}