add actuality checker

This commit is contained in:
InsanusMokrassar 2022-04-20 00:11:03 +06:00
parent 6327366720
commit 570568cd26
2 changed files with 101 additions and 48 deletions

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.libraries.cache.media.common package dev.inmo.tgbotapi.libraries.cache.media.common
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.DeleteMessage
import dev.inmo.tgbotapi.requests.DownloadFileStream import dev.inmo.tgbotapi.requests.DownloadFileStream
import dev.inmo.tgbotapi.requests.abstracts.MultipartFile import dev.inmo.tgbotapi.requests.abstracts.MultipartFile
import dev.inmo.tgbotapi.requests.get.GetFile import dev.inmo.tgbotapi.requests.get.GetFile
@ -16,6 +17,9 @@ class DefaultMessageContentCache<K>(
private val bot: TelegramBot, private val bot: TelegramBot,
private val filesRefreshingChatId: ChatId, private val filesRefreshingChatId: ChatId,
private val simpleMessageContentCache: MessagesSimpleCache<K>, private val simpleMessageContentCache: MessagesSimpleCache<K>,
private val mediaFileActualityChecker: MediaFileActualityChecker = MediaFileActualityChecker.WithDelay(
MediaFileActualityChecker.Default(filesRefreshingChatId)
),
private val messagesFilesCache: MessagesFilesCache<K> = InMemoryMessagesFilesCache() private val messagesFilesCache: MessagesFilesCache<K> = InMemoryMessagesFilesCache()
) : MessageContentCache<K> { ) : MessageContentCache<K> {
override suspend fun save(content: MessageContent): K { override suspend fun save(content: MessageContent): K {
@ -56,54 +60,50 @@ class DefaultMessageContentCache<K>(
override suspend fun get(k: K): MessageContent? { override suspend fun get(k: K): MessageContent? {
val savedSimpleContent = simpleMessageContentCache.get(k) ?: return null val savedSimpleContent = simpleMessageContentCache.get(k) ?: return null
if (savedSimpleContent is MediaContent) { if (savedSimpleContent is MediaContent && !with(mediaFileActualityChecker) { bot.isActual(savedSimpleContent) }) {
runCatching { val savedFileContentAllocator = messagesFilesCache.get(k) ?: error("Unexpected absence of $k file for content ($simpleMessageContentCache)")
bot.execute(GetFile(savedSimpleContent.media.fileId)) val newContent = bot.execute(
}.onFailure { when (savedSimpleContent.asInputMedia()) {
val savedFileContentAllocator = messagesFilesCache.get(k) ?: error("Unexpected absence of $k file for content ($simpleMessageContentCache)") is InputMediaAnimation -> SendAnimation(
val newContent = bot.execute( filesRefreshingChatId,
when (savedSimpleContent.asInputMedia()) { MultipartFile(
is InputMediaAnimation -> SendAnimation( savedFileContentAllocator
filesRefreshingChatId, ),
MultipartFile( disableNotification = true
savedFileContentAllocator )
), is InputMediaAudio -> SendAudio(
disableNotification = true filesRefreshingChatId,
) MultipartFile(
is InputMediaAudio -> SendAudio( savedFileContentAllocator
filesRefreshingChatId, ),
MultipartFile( disableNotification = true
savedFileContentAllocator )
), is InputMediaVideo -> SendVideo(
disableNotification = true filesRefreshingChatId,
) MultipartFile(
is InputMediaVideo -> SendVideo( savedFileContentAllocator
filesRefreshingChatId, ),
MultipartFile( disableNotification = true
savedFileContentAllocator )
), is InputMediaDocument -> SendDocument(
disableNotification = true filesRefreshingChatId,
) MultipartFile(
is InputMediaDocument -> SendDocument( savedFileContentAllocator
filesRefreshingChatId, ),
MultipartFile( disableNotification = true
savedFileContentAllocator )
), is InputMediaPhoto -> SendPhoto(
disableNotification = true filesRefreshingChatId,
) MultipartFile(
is InputMediaPhoto -> SendPhoto( savedFileContentAllocator
filesRefreshingChatId, ),
MultipartFile( disableNotification = true
savedFileContentAllocator )
), }
disableNotification = true )
)
}
)
simpleMessageContentCache.update(k, newContent.content) simpleMessageContentCache.update(k, newContent.content)
return newContent.content return newContent.content
}
} }
return savedSimpleContent return savedSimpleContent
} }
@ -122,7 +122,10 @@ class DefaultMessageContentCache<K>(
bot: TelegramBot, bot: TelegramBot,
filesRefreshingChatId: ChatId, filesRefreshingChatId: ChatId,
simpleMessageContentCache: MessagesSimpleCache<String> = InMemoryMessagesSimpleCache(), simpleMessageContentCache: MessagesSimpleCache<String> = InMemoryMessagesSimpleCache(),
mediaFileActualityChecker: MediaFileActualityChecker = MediaFileActualityChecker.WithDelay(
MediaFileActualityChecker.Default(filesRefreshingChatId)
),
messagesFilesCache: MessagesFilesCache<String> = InMemoryMessagesFilesCache() messagesFilesCache: MessagesFilesCache<String> = InMemoryMessagesFilesCache()
) = DefaultMessageContentCache(bot, filesRefreshingChatId, simpleMessageContentCache, messagesFilesCache) ) = DefaultMessageContentCache(bot, filesRefreshingChatId, simpleMessageContentCache, mediaFileActualityChecker, messagesFilesCache)
} }
} }

View File

@ -0,0 +1,50 @@
package dev.inmo.tgbotapi.libraries.cache.media.common
import com.soywiz.klock.DateTime
import com.soywiz.klock.milliseconds
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.DeleteMessage
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.MilliSeconds
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
fun interface MediaFileActualityChecker {
suspend fun TelegramBot.isActual(mediaContent: MediaContent): Boolean
class Default(
private val checkingChatId: ChatId
) : MediaFileActualityChecker {
override suspend fun TelegramBot.isActual(mediaContent: MediaContent): Boolean {
return runCatching {
execute(mediaContent.createResend(checkingChatId)).also { sentMessage ->
execute(DeleteMessage(sentMessage.chat.id, sentMessage.messageId))
}
}.isSuccess
}
}
class WithDelay(
private val underhoodChecker: MediaFileActualityChecker,
private val checkingDelay: MilliSeconds = 24 * 60 * 60 * 1000L // one day
) : MediaFileActualityChecker {
private val fileIdChecksMap = mutableMapOf<FileId, DateTime>()
private val checkingDelayTimeSpan = checkingDelay.milliseconds
override suspend fun TelegramBot.isActual(mediaContent: MediaContent): Boolean {
val now = DateTime.now()
val lastCheck = fileIdChecksMap[mediaContent.media.fileId]
return if (lastCheck == null || now - lastCheck > checkingDelayTimeSpan) {
with(underhoodChecker) {
isActual(mediaContent)
}.also {
if (it) {
fileIdChecksMap[mediaContent.media.fileId] = now
}
}
} else {
true
}
}
}
}