diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 44b7760..d6cccba 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,11 +1,12 @@ [versions] kotlin = "1.7.10" -kotlin-serialization = "1.4.0-RC" +kotlin-serialization = "1.4.0" plagubot = "2.1.0" tgbotapi = "3.1.1" -microutils = "0.12.1" +microutils = "0.12.2" +kslog = "0.5.1" dexcount = "3.1.0" junit_version = "4.12" @@ -32,6 +33,7 @@ tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" } plagubot-plugin = { module = "dev.inmo:plagubot.plugin", version.ref = "plagubot" } microutils-repos-common = { module = "dev.inmo:micro_utils.repos.common", version.ref = "microutils" } microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" } +kslog = { module = "dev.inmo:kslog", version.ref = "kslog" } # buildscript classpaths diff --git a/posts/build.gradle b/posts/build.gradle index 1b0a1a6..a210d1d 100644 --- a/posts/build.gradle +++ b/posts/build.gradle @@ -12,6 +12,7 @@ kotlin { dependencies { api libs.tgbotapi api libs.microutils.repos.common + api libs.kslog } } jvmMain { diff --git a/posts/src/commonMain/kotlin/sending/PostPublisher.kt b/posts/src/commonMain/kotlin/sending/PostPublisher.kt new file mode 100644 index 0000000..3419807 --- /dev/null +++ b/posts/src/commonMain/kotlin/sending/PostPublisher.kt @@ -0,0 +1,60 @@ +package dev.inmo.plaguposter.posts.sending + +import dev.inmo.kslog.common.logger +import dev.inmo.kslog.common.w +import dev.inmo.plaguposter.posts.models.PostId +import dev.inmo.plaguposter.posts.repo.PostsRepo +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.api.forwardMessage +import dev.inmo.tgbotapi.extensions.api.send.copyMessage +import dev.inmo.tgbotapi.extensions.api.send.send +import dev.inmo.tgbotapi.extensions.utils.* +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.message.content.MediaGroupContent + +class PostPublisher( + private val bot: TelegramBot, + private val repo: PostsRepo, + private val cachingChatId: ChatId, + private val targetChatId: ChatId +) { + suspend fun publish(postId: PostId) { + val messagesInfo = repo.getById(postId) ?: let { + logger.w { "Unable to get post with id $postId for publishing" } + return + } + val sortedMessagesContents = messagesInfo.content.groupBy { it.group }.flatMap { (group, list) -> + if (group == null) { + list.map { + it.order to listOf(it) + } + } else { + listOf(list.first().order to list) + } + }.sortedBy { it.first } + + sortedMessagesContents.forEach { (_, contents) -> + contents.singleOrNull() ?.also { + bot.copyMessage(targetChatId, it.chatId, it.messageId) + return@forEach + } + val resultContents = contents.mapNotNull { + it.order to (bot.forwardMessage(cachingChatId, it.chatId, it.messageId).contentMessageOrNull() ?: return@mapNotNull null) + }.sortedBy { it.first }.mapNotNull { (_, it) -> + it.withContentOrNull() ?: null.also { _ -> + bot.copyMessage(targetChatId, it) + } + } + resultContents.singleOrNull() ?.also { + bot.copyMessage(targetChatId, it) + return@forEach + } ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach { + bot.send( + targetChatId, + it.map { it.content.toMediaGroupMemberTelegramMedia() } + ) + } + } + + } +} diff --git a/posts/src/jvmMain/kotlin/Plugin.kt b/posts/src/jvmMain/kotlin/Plugin.kt index f420db5..2b860a2 100644 --- a/posts/src/jvmMain/kotlin/Plugin.kt +++ b/posts/src/jvmMain/kotlin/Plugin.kt @@ -1,12 +1,39 @@ package dev.inmo.plaguposter.posts +import dev.inmo.kslog.common.logger +import dev.inmo.kslog.common.w import dev.inmo.plagubot.Plugin -import kotlinx.serialization.json.JsonObject +import dev.inmo.plaguposter.posts.exposed.ExposedPostsRepo +import dev.inmo.plaguposter.posts.repo.PostsRepo +import dev.inmo.plaguposter.posts.sending.PostPublisher +import dev.inmo.tgbotapi.types.ChatId +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.* import org.jetbrains.exposed.sql.Database import org.koin.core.module.Module object Plugin : Plugin { + @Serializable + data class Config( + @SerialName("targetChat") + val targetChatId: ChatId, + @SerialName("cacheChat") + val cacheChatId: ChatId + ) + override fun Module.setupDI(database: Database, params: JsonObject) { - TODO("Not yet implemented") + val configJson = params["posts"] ?: this@Plugin.let { + it.logger.w { + "Unable to load posts plugin due to absence of `posts` key in config" + } + return + } + single { get().decodeFromJsonElement(Config.serializer(), configJson) } + single { ExposedPostsRepo(database, get()) } + single { + val config = get() + PostPublisher(get(), get(), config.cacheChatId, config.targetChatId) + } } } diff --git a/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt b/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt index 7eaeed2..b31f6a6 100644 --- a/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt +++ b/posts/src/jvmMain/kotlin/exposed/ExposedContentInfoRepo.kt @@ -4,12 +4,8 @@ import com.benasher44.uuid.uuid4 import dev.inmo.micro_utils.repos.KeyValuesRepo import dev.inmo.micro_utils.repos.exposed.* import dev.inmo.plaguposter.posts.models.* -import dev.inmo.plaguposter.posts.repo.PostsRepo import dev.inmo.tgbotapi.types.ChatId import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.statements.InsertStatement -import org.jetbrains.exposed.sql.statements.UpdateStatement -import sun.security.pkcs.ContentInfo internal class ExposedContentInfoRepo( override val database: Database,