Merge pull request #69 from InsanusMokrassar/0.18.0

0.18.0
This commit is contained in:
InsanusMokrassar 2024-01-13 15:40:35 +06:00 committed by GitHub
commit ccf60c95ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 127 deletions

View File

@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.libraries.cache.admins
import korlibs.time.minutes
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.Seconds
import korlibs.time.seconds
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.serialization.Serializable

View File

@ -8,6 +8,7 @@ import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.chat.ExtendedBot
import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember
import dev.inmo.tgbotapi.types.message.abstracts.*
import korlibs.time.seconds
import kotlinx.serialization.Serializable
interface DefaultAdminsCacheAPIRepo {

View File

@ -11,10 +11,10 @@ kotlin_serialisation_core_version=1.6.2
github_release_plugin_version=2.4.1
tgbotapi_version=9.4.3
micro_utils_version=0.20.23
exposed_version=0.45.0
plagubot_version=7.4.2
tgbotapi_version=10.0.0
micro_utils_version=0.20.26
exposed_version=0.46.0
plagubot_version=8.0.0
# Dokka
@ -23,4 +23,4 @@ dokka_version=1.9.10
# Project data
group=dev.inmo
version=0.17.2
version=0.18.0

View File

@ -3,8 +3,10 @@ package dev.inmo.tgbotapi.libraries.resender
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageId
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.abstracts.Message
import dev.inmo.tgbotapi.types.message.abstracts.PossiblyMediaGroupMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import kotlinx.serialization.Serializable
@Serializable
@ -13,7 +15,20 @@ data class MessageMetaInfo(
val chatId: IdChatIdentifier,
val messageId: MessageId,
val group: String? = null
)
) {
val metaInfo: Message.MetaInfo
get() = Message.MetaInfo(chatId, messageId)
}
fun Message.asMessageMetaInfos(): List<MessageMetaInfo> {
return if (this is ContentMessage<*>) {
(content as? MediaGroupContent<*>) ?.group ?.map {
MessageMetaInfo(it.sourceMessage.chat.id, it.sourceMessage.messageId, it.sourceMessage.mediaGroupId)
}
} else {
null
} ?: listOf(MessageMetaInfo(chat.id, messageId, (this as? PossiblyMediaGroupMessage<*>) ?.mediaGroupId))
}
operator fun MessageMetaInfo.Companion.invoke(
message: Message

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.libraries.resender
import dev.inmo.micro_utils.common.applyDiff
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.ForwardMessage
import dev.inmo.tgbotapi.requests.send.CopyMessage
import dev.inmo.tgbotapi.requests.send.CopyMessages
import dev.inmo.tgbotapi.requests.send.media.SendMediaGroup
import dev.inmo.tgbotapi.types.ChatIdentifier
import dev.inmo.tgbotapi.types.IdChatIdentifier
@ -19,135 +21,58 @@ class MessagesResender(
messagesInfo: List<MessageMetaInfo>,
onBetweenMessages: suspend (sent: List<MessageMetaInfo>, toBeSent: List<MessageMetaInfo>) -> Unit
): List<Pair<MessageMetaInfo, MessageMetaInfo>> {
val messagesWithOrders = messagesInfo.mapIndexed { i, messageInfo -> messageInfo to i }.toMap()
val ordersWithMessagesGroups = messagesInfo.groupBy { it.group }.flatMap { (group, list) ->
if (group == null) {
list.map {
messagesWithOrders.getValue(it) to listOf(it)
}
} else {
listOf(messagesWithOrders.getValue(list.first()) to list)
}
}.sortedBy { it.first }
val sent = mutableListOf<MessageMetaInfo>()
val leftToSend = ordersWithMessagesGroups.map { it.second }.toMutableList()
return ordersWithMessagesGroups.flatMap { (_, contents) ->
val sourceMessagesToSentMessages = mutableListOf<Pair<MessageMetaInfo, MessageMetaInfo>>()
onBetweenMessages(sent.toList(), leftToSend.flatten())
when {
contents.size == 1 -> {
val messageInfo = contents.first()
runCatching {
MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
fromChatId = messageInfo.chatId,
messageId = messageInfo.messageId
)
)
val currentGroup = mutableListOf<MessageMetaInfo>()
suspend fun makeCopy(): List<Pair<MessageMetaInfo, MessageMetaInfo>> {
currentGroup.sortBy { it.messageId }
while (currentGroup.isNotEmpty()) {
return runCatching {
bot.execute(
CopyMessages(
toChatId = targetChatId,
fromChatId = currentGroup.firstOrNull() ?.chatId ?: return emptyList(),
messageIds = currentGroup.map { it.messageId }
)
}.onFailure { _ ->
runCatching {
bot.execute(
ForwardMessage(
toChatId = targetChatId,
fromChatId = messageInfo.chatId,
messageId = messageInfo.messageId
)
)
}.onSuccess {
MessageMetaInfo(
targetChatId,
).mapIndexed { i, newMessageId ->
currentGroup[i] to MessageMetaInfo(targetChatId, newMessageId)
}.also {
currentGroup.clear()
}
}.getOrElse {
currentGroup.applyDiff(
currentGroup.filter {
runCatching {
bot.execute(
CopyMessage(
targetChatId,
fromChatId = it.chat.id,
ForwardMessage(
toChatId = cacheChatId,
fromChatId = it.chatId,
messageId = it.messageId
)
)
)
}.isSuccess
}
}.getOrNull() ?.let {
sourceMessagesToSentMessages.add(messageInfo to it)
}
}
else -> {
val resultContents = contents.mapNotNull {
it to (
bot.execute(
ForwardMessage(
toChatId = cacheChatId,
fromChatId = it.chatId,
messageId = it.messageId
)
) as? ContentMessage<*> ?: return@mapNotNull null)
}.mapNotNull { (src, forwardedMessage) ->
val forwardedMessageAsMediaPartMessage = forwardedMessage.takeIf {
it.content is MediaGroupPartContent
} ?.let {
it as ContentMessage<MediaGroupPartContent>
}
src to (forwardedMessageAsMediaPartMessage ?: null.also { _ ->
sourceMessagesToSentMessages.add(
src to MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
fromChatId = forwardedMessage.chat.id,
messageId = forwardedMessage.messageId
)
)
)
)
} ?: return@mapNotNull null)
}
resultContents.singleOrNull() ?.also { (src, it) ->
sourceMessagesToSentMessages.add(
src to MessageMetaInfo(
targetChatId,
bot.execute(
CopyMessage(
targetChatId,
it.chat.id,
it.messageId
)
)
)
)
} ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach {
bot.execute(
SendMediaGroup<MediaGroupPartContent>(
targetChatId,
it.map { it.second.content.toMediaGroupMemberTelegramMedia() }
)
).content.group.mapIndexed { i, partWrapper ->
it.getOrNull(i) ?.let {
sourceMessagesToSentMessages.add(
it.first to MessageMetaInfo(
partWrapper.sourceMessage.chat.id,
partWrapper.sourceMessage.messageId,
partWrapper.sourceMessage.mediaGroupId
)
)
}
}
}
}
)
null
} ?: continue
}
leftToSend.takeIf { it.isNotEmpty() } ?.removeAt(0) ?.also {
sent.addAll(it)
}
sourceMessagesToSentMessages.toList()
return emptyList()
}
val copied = mutableListOf<Pair<MessageMetaInfo, MessageMetaInfo>>()
for (content in messagesInfo) {
when {
currentGroup.isEmpty() ||
currentGroup.first().chatId == content.chatId -> currentGroup.add(content)
else -> {
onBetweenMessages(copied.map { it.first }, currentGroup.toList())
copied.addAll(makeCopy())
}
}
}
if (currentGroup.isNotEmpty()) {
onBetweenMessages(copied.map { it.first }, currentGroup.toList())
copied.addAll(makeCopy())
}
return copied.toList()
}
suspend fun resend(