Merge pull request #16 from InsanusMokrassar/0.2.3

0.2.3
This commit is contained in:
InsanusMokrassar 2023-08-13 00:04:27 +06:00 committed by GitHub
commit feef8efee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 90 additions and 69 deletions

View File

@ -1,5 +1,10 @@
# PlaguPoster # PlaguPoster
## 0.2.3
* Add opportunity to use several target chat ids
* Update dependencies
## 0.2.2 ## 0.2.2
* `GarbageCollector`: * `GarbageCollector`:

View File

@ -1,6 +1,5 @@
package dev.inmo.plaguposter.common package dev.inmo.plaguposter.common
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier import dev.inmo.tgbotapi.types.IdChatIdentifier
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
@ -10,14 +9,26 @@ import kotlinx.serialization.Serializable
data class ChatConfig( data class ChatConfig(
@SerialName("targetChat") @SerialName("targetChat")
@Serializable(FullChatIdentifierSerializer::class) @Serializable(FullChatIdentifierSerializer::class)
val targetChatId: IdChatIdentifier, val targetChatId: IdChatIdentifier? = null,
@SerialName("sourceChat") @SerialName("sourceChat")
@Serializable(FullChatIdentifierSerializer::class) @Serializable(FullChatIdentifierSerializer::class)
val sourceChatId: IdChatIdentifier, val sourceChatId: IdChatIdentifier,
@SerialName("cacheChat") @SerialName("cacheChat")
@Serializable(FullChatIdentifierSerializer::class) @Serializable(FullChatIdentifierSerializer::class)
val cacheChatId: IdChatIdentifier val cacheChatId: IdChatIdentifier,
@SerialName("targetChats")
val targetChatIds: List<@Serializable(FullChatIdentifierSerializer::class) IdChatIdentifier> = emptyList(),
) { ) {
val allTargetChatIds by lazy {
listOfNotNull(targetChatId) + targetChatIds
}
init {
require(targetChatId != null || targetChatIds.isNotEmpty()) {
"One of fields, 'targetChat' or 'targetChats' should be presented"
}
}
fun check(chatId: IdChatIdentifier) = when (chatId) { fun check(chatId: IdChatIdentifier) = when (chatId) {
targetChatId, targetChatId,
sourceChatId, sourceChatId,

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.common package dev.inmo.plaguposter.common
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer

View File

@ -1,6 +1,5 @@
package dev.inmo.plaguposter.common package dev.inmo.plaguposter.common
import dev.inmo.kslog.common.i
import dev.inmo.kslog.common.iS import dev.inmo.kslog.common.iS
import dev.inmo.kslog.common.logger import dev.inmo.kslog.common.logger
import dev.inmo.plagubot.Plugin import dev.inmo.plagubot.Plugin
@ -27,7 +26,7 @@ object CommonPlugin : Plugin {
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
val config = koin.get<ChatConfig>() val config = koin.get<ChatConfig>()
Log.iS { "Target chat info: ${getChat(config.targetChatId)}" } Log.iS { "Target chats info: ${config.allTargetChatIds.map { getChat(it) }.joinToString()}" }
Log.iS { "Source chat info: ${getChat(config.sourceChatId)}" } Log.iS { "Source chat info: ${getChat(config.sourceChatId)}" }
Log.iS { "Cache chat info: ${getChat(config.cacheChatId)}" } Log.iS { "Cache chat info: ${getChat(config.cacheChatId)}" }
} }

View File

@ -10,4 +10,4 @@ android.enableJetifier=true
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.2.2 version=0.2.3

View File

@ -1,16 +1,16 @@
[versions] [versions]
kotlin = "1.8.21" kotlin = "1.8.22"
kotlin-serialization = "1.5.0" kotlin-serialization = "1.5.1"
plagubot = "5.1.2" plagubot = "7.0.0"
tgbotapi = "7.1.2" tgbotapi = "9.0.0"
microutils = "0.18.1" microutils = "0.19.9"
kslog = "1.1.1" kslog = "1.1.2"
krontab = "1.0.0" krontab = "2.1.2"
plagubot-plugins = "0.11.2" plagubot-plugins = "0.13.0"
dokka = "1.8.10" dokka = "1.8.20"
psql = "42.6.0" psql = "42.6.0"

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.posts.models package dev.inmo.plaguposter.posts.models
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.plaguposter.common.DateTimeSerializer import dev.inmo.plaguposter.common.DateTimeSerializer
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.posts.repo package dev.inmo.plaguposter.posts.repo
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.repos.ReadCRUDRepo import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.plaguposter.posts.models.* import dev.inmo.plaguposter.posts.models.*
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId

View File

@ -18,7 +18,7 @@ class PostPublisher(
private val bot: TelegramBot, private val bot: TelegramBot,
private val postsRepo: PostsRepo, private val postsRepo: PostsRepo,
private val cachingChatId: IdChatIdentifier, private val cachingChatId: IdChatIdentifier,
private val targetChatId: IdChatIdentifier, private val targetChatIds: List<IdChatIdentifier>,
private val deleteAfterPosting: Boolean = true private val deleteAfterPosting: Boolean = true
) { ) {
suspend fun publish(postId: PostId) { suspend fun publish(postId: PostId) {
@ -38,6 +38,7 @@ class PostPublisher(
sortedMessagesContents.forEach { (_, contents) -> sortedMessagesContents.forEach { (_, contents) ->
contents.singleOrNull() ?.also { contents.singleOrNull() ?.also {
targetChatIds.forEach { targetChatId ->
runCatching { runCatching {
bot.copyMessage(targetChatId, it.chatId, it.messageId) bot.copyMessage(targetChatId, it.chatId, it.messageId)
}.onFailure { _ -> }.onFailure { _ ->
@ -51,25 +52,32 @@ class PostPublisher(
bot.copyMessage(targetChatId, it) bot.copyMessage(targetChatId, it)
} }
} }
}
return@forEach return@forEach
} }
val resultContents = contents.mapNotNull { val resultContents = contents.mapNotNull {
it.order to (bot.forwardMessage(toChatId = cachingChatId, fromChatId = it.chatId, messageId = it.messageId).contentMessageOrNull() ?: return@mapNotNull null) it.order to (bot.forwardMessage(toChatId = cachingChatId, fromChatId = it.chatId, messageId = it.messageId).contentMessageOrNull() ?: return@mapNotNull null)
}.sortedBy { it.first }.mapNotNull { (_, forwardedMessage) -> }.sortedBy { it.first }.mapNotNull { (_, forwardedMessage) ->
forwardedMessage.withContentOrNull<MediaGroupPartContent>() ?: null.also { _ -> forwardedMessage.withContentOrNull<MediaGroupPartContent>() ?: null.also { _ ->
targetChatIds.forEach { targetChatId ->
bot.copyMessage(targetChatId, forwardedMessage) bot.copyMessage(targetChatId, forwardedMessage)
} }
} }
}
resultContents.singleOrNull() ?.also { resultContents.singleOrNull() ?.also {
targetChatIds.forEach { targetChatId ->
bot.copyMessage(targetChatId, it) bot.copyMessage(targetChatId, it)
}
return@forEach return@forEach
} ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach { } ?: resultContents.chunked(mediaCountInMediaGroup.last).forEach {
targetChatIds.forEach { targetChatId ->
bot.send( bot.send(
targetChatId, targetChatId,
it.map { it.content.toMediaGroupMemberTelegramMedia() } it.map { it.content.toMediaGroupMemberTelegramMedia() }
) )
} }
} }
}
if (deleteAfterPosting) { if (deleteAfterPosting) {
postsRepo.deleteById(postId) postsRepo.deleteById(postId)

View File

@ -29,7 +29,6 @@ import kotlinx.serialization.json.*
import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin import org.koin.core.Koin
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.dsl.binds
object Plugin : Plugin { object Plugin : Plugin {
@Serializable @Serializable
@ -59,7 +58,7 @@ object Plugin : Plugin {
} }
single { single {
val config = get<Config>() val config = get<Config>()
PostPublisher(get(), get(), config.chats.cacheChatId, config.chats.targetChatId, config.deleteAfterPublishing) PostPublisher(get(), get(), config.chats.cacheChatId, config.chats.allTargetChatIds, config.deleteAfterPublishing)
} }
} }

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.posts.cached package dev.inmo.plaguposter.posts.cached
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.pagination.FirstPagePagination import dev.inmo.micro_utils.pagination.FirstPagePagination
import dev.inmo.micro_utils.pagination.firstPageWithOneElementPagination import dev.inmo.micro_utils.pagination.firstPageWithOneElementPagination
import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging import dev.inmo.micro_utils.pagination.utils.doForAllWithNextPaging
@ -25,6 +25,7 @@ class CachedPostsRepo(
parentRepo, parentRepo,
kvCache, kvCache,
scope, scope,
skipStartInvalidate = false,
{ it.id } { it.id }
) { ) {
override val removedPostsFlow: Flow<RegisteredPost> by parentRepo::removedPostsFlow override val removedPostsFlow: Flow<RegisteredPost> by parentRepo::removedPostsFlow

View File

@ -1,7 +1,7 @@
package dev.inmo.plaguposter.posts.exposed package dev.inmo.plaguposter.posts.exposed
import com.benasher44.uuid.uuid4 import com.benasher44.uuid.uuid4
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.repos.KeyValuesRepo import dev.inmo.micro_utils.repos.KeyValuesRepo
import dev.inmo.micro_utils.repos.UpdatedValuePair import dev.inmo.micro_utils.repos.UpdatedValuePair
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo

View File

@ -1,7 +1,7 @@
package dev.inmo.plaguposter.ratings.gc package dev.inmo.plaguposter.ratings.gc
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.seconds import korlibs.time.seconds
import dev.inmo.krontab.KrontabTemplate import dev.inmo.krontab.KrontabTemplate
import dev.inmo.krontab.toSchedule import dev.inmo.krontab.toSchedule
import dev.inmo.krontab.utils.asFlowWithDelays import dev.inmo.krontab.utils.asFlowWithDelays

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.ratings.selector package dev.inmo.plaguposter.ratings.selector
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
import dev.inmo.plaguposter.posts.repo.PostsRepo import dev.inmo.plaguposter.posts.repo.PostsRepo
import dev.inmo.plaguposter.ratings.repo.RatingsRepo import dev.inmo.plaguposter.ratings.repo.RatingsRepo

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.ratings.selector package dev.inmo.plaguposter.ratings.selector
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
interface Selector { interface Selector {

View File

@ -1,7 +1,7 @@
package dev.inmo.plaguposter.ratings.selector.models package dev.inmo.plaguposter.ratings.selector.models
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.seconds import korlibs.time.seconds
import dev.inmo.micro_utils.pagination.FirstPagePagination import dev.inmo.micro_utils.pagination.FirstPagePagination
import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.Pagination
import dev.inmo.micro_utils.pagination.utils.getAllByWithNextPaging import dev.inmo.micro_utils.pagination.utils.getAllByWithNextPaging

View File

@ -1,7 +1,7 @@
package dev.inmo.plaguposter.ratings.selector.models package dev.inmo.plaguposter.ratings.selector.models
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.Time import korlibs.time.Time
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.ratings.selector.models package dev.inmo.plaguposter.ratings.selector.models
import com.soywiz.klock.* import korlibs.time.*
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.ratings.source.buttons package dev.inmo.plaguposter.ratings.source.buttons
import com.soywiz.klock.DateFormat import korlibs.time.DateFormat
import dev.inmo.kslog.common.TagLogger import dev.inmo.kslog.common.TagLogger
import dev.inmo.kslog.common.d import dev.inmo.kslog.common.d
import dev.inmo.kslog.common.i import dev.inmo.kslog.common.i

View File

@ -1,9 +1,8 @@
package dev.inmo.plaguposter.ratings.source.repos package dev.inmo.plaguposter.ratings.source.repos
import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.KeyValueRepo
import dev.inmo.micro_utils.repos.cache.KeyValueCacheRepo
import dev.inmo.micro_utils.repos.cache.cache.FullKVCache import dev.inmo.micro_utils.repos.cache.cache.FullKVCache
import dev.inmo.micro_utils.repos.cache.full.cached import dev.inmo.micro_utils.repos.cache.full.fullyCached
import dev.inmo.plaguposter.common.ShortMessageInfo import dev.inmo.plaguposter.common.ShortMessageInfo
import dev.inmo.tgbotapi.types.PollIdentifier import dev.inmo.tgbotapi.types.PollIdentifier
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -12,4 +11,4 @@ class CachedPollsToMessagesInfoRepo(
private val repo: PollsToMessagesInfoRepo, private val repo: PollsToMessagesInfoRepo,
private val scope: CoroutineScope, private val scope: CoroutineScope,
private val kvCache: FullKVCache<PollIdentifier, ShortMessageInfo> = FullKVCache() private val kvCache: FullKVCache<PollIdentifier, ShortMessageInfo> = FullKVCache()
) : PollsToMessagesInfoRepo, KeyValueRepo<PollIdentifier, ShortMessageInfo> by repo.cached(kvCache, scope) ) : PollsToMessagesInfoRepo, KeyValueRepo<PollIdentifier, ShortMessageInfo> by repo.fullyCached(kvCache, scope)

View File

@ -2,8 +2,7 @@ package dev.inmo.plaguposter.ratings.source.repos
import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.KeyValueRepo
import dev.inmo.micro_utils.repos.cache.cache.FullKVCache import dev.inmo.micro_utils.repos.cache.cache.FullKVCache
import dev.inmo.micro_utils.repos.cache.full.cached import dev.inmo.micro_utils.repos.cache.full.fullyCached
import dev.inmo.plaguposter.common.ShortMessageInfo
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
import dev.inmo.tgbotapi.types.PollIdentifier import dev.inmo.tgbotapi.types.PollIdentifier
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -12,4 +11,4 @@ class CachedPollsToPostsIdsRepo(
private val repo: PollsToPostsIdsRepo, private val repo: PollsToPostsIdsRepo,
private val scope: CoroutineScope, private val scope: CoroutineScope,
private val kvCache: FullKVCache<PollIdentifier, PostId> = FullKVCache() private val kvCache: FullKVCache<PollIdentifier, PostId> = FullKVCache()
) : PollsToPostsIdsRepo, KeyValueRepo<PollIdentifier, PostId> by repo.cached(kvCache, scope) ) : PollsToPostsIdsRepo, KeyValueRepo<PollIdentifier, PostId> by repo.fullyCached(kvCache, scope)

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.triggers.selector_with_timer package dev.inmo.plaguposter.triggers.selector_with_timer
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
fun interface AutopostFilter { fun interface AutopostFilter {

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.triggers.selector_with_timer package dev.inmo.plaguposter.triggers.selector_with_timer
import com.soywiz.klock.DateFormat import korlibs.time.DateFormat
import dev.inmo.krontab.KrontabTemplate import dev.inmo.krontab.KrontabTemplate
import dev.inmo.krontab.toSchedule import dev.inmo.krontab.toSchedule
import dev.inmo.krontab.utils.asFlowWithDelays import dev.inmo.krontab.utils.asFlowWithDelays

View File

@ -1,10 +1,10 @@
package dev.inmo.plaguposter.triggers.timer package dev.inmo.plaguposter.triggers.timer
import com.soywiz.klock.DateFormat import korlibs.time.DateFormat
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.DateTimeTz import korlibs.time.DateTimeTz
import com.soywiz.klock.Month import korlibs.time.Month
import com.soywiz.klock.Year import korlibs.time.Year
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.repos.unset import dev.inmo.micro_utils.repos.unset
import dev.inmo.plaguposter.common.SuccessfulSymbol import dev.inmo.plaguposter.common.SuccessfulSymbol

View File

@ -1,7 +1,7 @@
package dev.inmo.plaguposter.triggers.timer package dev.inmo.plaguposter.triggers.timer
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import com.soywiz.klock.minutes import korlibs.time.minutes
fun nearestAvailableTimerTime() = (DateTime.now() + 1.minutes).copyDayOfMonth( fun nearestAvailableTimerTime() = (DateTime.now() + 1.minutes).copyDayOfMonth(
milliseconds = 0, milliseconds = 0,

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.triggers.timer package dev.inmo.plaguposter.triggers.timer
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.micro_utils.coroutines.plus import dev.inmo.micro_utils.coroutines.plus
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.triggers.timer package dev.inmo.plaguposter.triggers.timer
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.repos.KeyValueRepo import dev.inmo.micro_utils.repos.KeyValueRepo
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.triggers.timer package dev.inmo.plaguposter.triggers.timer
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.koin.singleWithRandomQualifierAndBinds import dev.inmo.micro_utils.koin.singleWithRandomQualifierAndBinds

View File

@ -1,6 +1,6 @@
package dev.inmo.plaguposter.triggers.timer.repo package dev.inmo.plaguposter.triggers.timer.repo
import com.soywiz.klock.DateTime import korlibs.time.DateTime
import dev.inmo.micro_utils.common.firstNotNull import dev.inmo.micro_utils.common.firstNotNull
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.pagination.paginate import dev.inmo.micro_utils.pagination.paginate