updates and fixes

This commit is contained in:
InsanusMokrassar 2022-11-17 15:09:10 +06:00
parent 18ed638bcc
commit 5366dcdba1
16 changed files with 121 additions and 74 deletions

View File

@ -18,6 +18,7 @@ allprojects {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
google() google()
maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" }
} }
} }

View File

@ -1,13 +1,16 @@
package dev.inmo.plaguposter.common package dev.inmo.plaguposter.common
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.Message import dev.inmo.tgbotapi.types.message.abstracts.Message
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class ShortMessageInfo( data class ShortMessageInfo(
val chatId: ChatId, @Serializable(FullChatIdentifierSerializer::class)
val chatId: IdChatIdentifier,
val messageId: MessageIdentifier val messageId: MessageIdentifier
) )

View File

@ -0,0 +1,20 @@
package dev.inmo.plaguposter.common
import dev.inmo.kslog.common.i
import dev.inmo.kslog.common.iS
import dev.inmo.kslog.common.logger
import dev.inmo.plagubot.Plugin
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import org.koin.core.Koin
object CommonPlugin : Plugin {
private val Log = logger
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
val config = koin.get<ChatConfig>()
Log.iS { "Target chat info: ${getChat(config.targetChatId)}" }
Log.iS { "Source chat info: ${getChat(config.sourceChatId)}" }
Log.iS { "Cache chat info: ${getChat(config.cacheChatId)}" }
}
}

View File

@ -1,15 +1,17 @@
[versions] [versions]
kotlin = "1.7.20" kotlin = "1.7.21"
kotlin-serialization = "1.4.1" kotlin-serialization = "1.4.1"
plagubot = "2.4.0" plagubot = "3.1.3"
tgbotapi = "3.3.0" tgbotapi = "4.1.2"
microutils = "0.13.1" microutils = "0.14.2"
kslog = "0.5.2" kslog = "0.5.3"
krontab = "0.8.1" krontab = "0.8.3"
tgbotapi-libraries = "0.5.6" tgbotapi-libraries = "0.6.3"
plagubot-plugins = "0.5.0" plagubot-plugins = "0.6.1"
dokka = "1.7.20"
psql = "42.5.0" psql = "42.5.0"
@ -39,7 +41,7 @@ psql = { module = "org.postgresql:postgresql", version.ref = "psql" }
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
kotlin-serialization-plugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" } kotlin-serialization-plugin = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
kotlin-dokka-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "kotlin" } kotlin-dokka-plugin = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" }
[plugins] [plugins]

View File

@ -23,6 +23,7 @@ import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage
import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton
import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackDataInlineKeyboardButton import dev.inmo.tgbotapi.types.buttons.InlineKeyboardButtons.CallbackDataInlineKeyboardButton
import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
@ -108,7 +109,7 @@ object Plugin : Plugin {
suspend fun refreshPostMessage( suspend fun refreshPostMessage(
postId: PostId, postId: PostId,
chatId: ChatId, chatId: IdChatIdentifier,
messageId: MessageIdentifier messageId: MessageIdentifier
) { ) {
val post = postsRepo.getById(postId) ?: return val post = postsRepo.getById(postId) ?: return

View File

@ -5,18 +5,20 @@ import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
import dev.inmo.micro_utils.repos.mappers.withMapper import dev.inmo.micro_utils.repos.mappers.withMapper
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import kotlinx.serialization.builtins.PairSerializer import kotlinx.serialization.builtins.PairSerializer
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.Database
private val ChatIdToMessageSerializer = PairSerializer(ChatId.serializer(), MessageIdentifier.serializer()) private val ChatIdToMessageSerializer = PairSerializer(FullChatIdentifierSerializer, MessageIdentifier.serializer())
fun PostsMessages( fun PostsMessages(
database: Database, database: Database,
json: Json json: Json
): KeyValueRepo<PostId, Pair<ChatId, MessageIdentifier>> = ExposedKeyValueRepo<String, String>( ): KeyValueRepo<PostId, Pair<IdChatIdentifier, MessageIdentifier>> = ExposedKeyValueRepo<String, String>(
database, database,
{ text("postId") }, { text("postId") },
{ text("chatToMessage") }, { text("chatToMessage") },
@ -25,5 +27,5 @@ fun PostsMessages(
{ string }, { string },
{ json.encodeToString(ChatIdToMessageSerializer, this) }, { json.encodeToString(ChatIdToMessageSerializer, this) },
{ PostId(this) }, { PostId(this) },
{ json.decodeFromString(ChatIdToMessageSerializer, this) } { json.decodeFromString(ChatIdToMessageSerializer, this) as Pair<IdChatIdentifier, MessageIdentifier> }
) )

View File

@ -1,25 +1,39 @@
package dev.inmo.plaguposter.posts.models package dev.inmo.plaguposter.posts.models
import dev.inmo.tgbotapi.extensions.utils.mediaGroupMessageOrNull import dev.inmo.tgbotapi.extensions.utils.possiblyMediaGroupMessageOrNull
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class PostContentInfo( data class PostContentInfo(
val chatId: ChatId, @Serializable(FullChatIdentifierSerializer::class)
val chatId: IdChatIdentifier,
val messageId: MessageIdentifier, val messageId: MessageIdentifier,
val group: String?, val group: String?,
val order: Int val order: Int
) { ) {
companion object { companion object {
fun fromMessage(message: ContentMessage<*>, order: Int) = PostContentInfo( private fun fromMessage(message: ContentMessage<*>, order: Int) = PostContentInfo(
message.chat.id, message.chat.id,
message.messageId, message.messageId,
message.mediaGroupMessageOrNull() ?.mediaGroupId, message.possiblyMediaGroupMessageOrNull() ?.mediaGroupId,
order order
) )
fun fromMessage(message: ContentMessage<*>): List<PostContentInfo> {
val content = message.content
return if (content is MediaGroupContent<*>) {
content.group.mapIndexed { i, it ->
fromMessage(it.sourceMessage, i)
}
} else {
listOf(fromMessage(message, 0))
}
}
} }
} }

View File

@ -4,9 +4,10 @@ import com.soywiz.klock.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
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
interface ReadPostsRepo : ReadCRUDRepo<RegisteredPost, PostId> { interface ReadPostsRepo : ReadCRUDRepo<RegisteredPost, PostId> {
suspend fun getIdByChatAndMessage(chatId: ChatId, messageId: MessageIdentifier): PostId? suspend fun getIdByChatAndMessage(chatId: IdChatIdentifier, messageId: MessageIdentifier): PostId?
suspend fun getPostCreationTime(postId: PostId): DateTime? suspend fun getPostCreationTime(postId: PostId): DateTime?
} }

View File

@ -12,6 +12,7 @@ import dev.inmo.tgbotapi.extensions.api.send.send
import dev.inmo.tgbotapi.extensions.utils.* import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.MediaGroupPartContent
class PostPublisher( class PostPublisher(
private val bot: TelegramBot, private val bot: TelegramBot,
@ -37,14 +38,26 @@ class PostPublisher(
sortedMessagesContents.forEach { (_, contents) -> sortedMessagesContents.forEach { (_, contents) ->
contents.singleOrNull() ?.also { contents.singleOrNull() ?.also {
runCatching {
bot.copyMessage(targetChatId, it.chatId, it.messageId) bot.copyMessage(targetChatId, it.chatId, it.messageId)
}.onFailure { _ ->
runCatching {
bot.forwardMessage(
it.chatId,
targetChatId,
it.messageId
)
}.onSuccess {
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 { (_, it) -> }.sortedBy { it.first }.mapNotNull { (_, forwardedMessage) ->
it.withContentOrNull<MediaGroupContent>() ?: null.also { _ -> forwardedMessage.withContentOrNull<MediaGroupPartContent>() ?: null.also { _ ->
bot.copyMessage(targetChatId, it) bot.copyMessage(targetChatId, forwardedMessage)
} }
} }
resultContents.singleOrNull() ?.also { resultContents.singleOrNull() ?.also {

View File

@ -5,6 +5,7 @@ import dev.inmo.micro_utils.repos.KeyValuesRepo
import dev.inmo.micro_utils.repos.exposed.* import dev.inmo.micro_utils.repos.exposed.*
import dev.inmo.plaguposter.posts.models.* import dev.inmo.plaguposter.posts.models.*
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.IdChatIdentifier
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
internal class ExposedContentInfoRepo( internal class ExposedContentInfoRepo(
@ -13,13 +14,14 @@ internal class ExposedContentInfoRepo(
) : ExposedRepo, Table(name = "posts_content") { ) : ExposedRepo, Table(name = "posts_content") {
val postIdColumn = text("post_id").references(postIdColumnReference, ReferenceOption.CASCADE, ReferenceOption.CASCADE) val postIdColumn = text("post_id").references(postIdColumnReference, ReferenceOption.CASCADE, ReferenceOption.CASCADE)
val chatIdColumn = long("chat_id") val chatIdColumn = long("chat_id")
val threadIdColumn = long("thread_id").nullable().default(null)
val messageIdColumn = long("message_id") val messageIdColumn = long("message_id")
val groupColumn = text("group").nullable() val groupColumn = text("group").nullable()
val orderColumn = integer("order") val orderColumn = integer("order")
val ResultRow.asObject val ResultRow.asObject
get() = PostContentInfo( get() = PostContentInfo(
ChatId(get(chatIdColumn)), IdChatIdentifier(get(chatIdColumn), get(threadIdColumn)),
get(messageIdColumn), get(messageIdColumn),
get(groupColumn), get(groupColumn),
get(orderColumn) get(orderColumn)

View File

@ -9,10 +9,13 @@ import dev.inmo.micro_utils.repos.exposed.initTable
import dev.inmo.plaguposter.posts.models.* import dev.inmo.plaguposter.posts.models.*
import dev.inmo.plaguposter.posts.repo.PostsRepo import dev.inmo.plaguposter.posts.repo.PostsRepo
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.MessageIdentifier import dev.inmo.tgbotapi.types.MessageIdentifier
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList
import org.jetbrains.exposed.sql.statements.* import org.jetbrains.exposed.sql.statements.*
import org.jetbrains.exposed.sql.transactions.transaction import org.jetbrains.exposed.sql.transactions.transaction
@ -33,8 +36,8 @@ class ExposedPostsRepo(
override val primaryKey: PrimaryKey = PrimaryKey(idColumn) override val primaryKey: PrimaryKey = PrimaryKey(idColumn)
override val selectById: SqlExpressionBuilder.(PostId) -> Op<Boolean> = { idColumn.eq(it.string) } override val selectById: ISqlExpressionBuilder.(PostId) -> Op<Boolean> = { idColumn.eq(it.string) }
override val selectByIds: SqlExpressionBuilder.(List<PostId>) -> Op<Boolean> = { idColumn.inList(it.map { it.string }) } override val selectByIds: ISqlExpressionBuilder.(List<PostId>) -> Op<Boolean> = { idColumn.inList(it.map { it.string }) }
override val ResultRow.asObject: RegisteredPost override val ResultRow.asObject: RegisteredPost
get() { get() {
val id = PostId(get(idColumn)) val id = PostId(get(idColumn))
@ -86,6 +89,7 @@ class ExposedPostsRepo(
insert { insert {
it[postIdColumn] = post.id.string it[postIdColumn] = post.id.string
it[chatIdColumn] = contentInfo.chatId.chatId it[chatIdColumn] = contentInfo.chatId.chatId
it[threadIdColumn] = contentInfo.chatId.threadId
it[messageIdColumn] = contentInfo.messageId it[messageIdColumn] = contentInfo.messageId
it[groupColumn] = contentInfo.group it[groupColumn] = contentInfo.group
it[orderColumn] = contentInfo.order it[orderColumn] = contentInfo.order
@ -102,14 +106,14 @@ class ExposedPostsRepo(
override suspend fun onAfterCreate(values: List<Pair<NewPost, RegisteredPost>>): List<RegisteredPost> { override suspend fun onAfterCreate(values: List<Pair<NewPost, RegisteredPost>>): List<RegisteredPost> {
values.forEach { values.forEach {
updateContent(it.second) updateContent(it.second.copy(content = it.first.content))
} }
return super.onAfterCreate(values) return super.onAfterCreate(values)
} }
override suspend fun onAfterUpdate(value: List<UpdatedValuePair<NewPost, RegisteredPost>>): List<RegisteredPost> { override suspend fun onAfterUpdate(value: List<UpdatedValuePair<NewPost, RegisteredPost>>): List<RegisteredPost> {
value.forEach { value.forEach {
updateContent(it.second) updateContent(it.second.copy(content = it.first.content))
} }
return super.onAfterUpdate(value) return super.onAfterUpdate(value)
} }
@ -122,7 +126,7 @@ class ExposedPostsRepo(
val existsIds = posts.keys.toList() val existsIds = posts.keys.toList()
transaction(db = database) { transaction(db = database) {
val deleted = deleteWhere(null, null) { val deleted = deleteWhere(null, null) {
selectByIds(existsIds) selectByIds(it, existsIds)
} }
with(contentRepo) { with(contentRepo) {
deleteWhere { deleteWhere {
@ -142,10 +146,10 @@ class ExposedPostsRepo(
} }
} }
override suspend fun getIdByChatAndMessage(chatId: ChatId, messageId: MessageIdentifier): PostId? { override suspend fun getIdByChatAndMessage(chatId: IdChatIdentifier, messageId: MessageIdentifier): PostId? {
return transaction(database) { return transaction(database) {
with(contentRepo) { with(contentRepo) {
select { chatIdColumn.eq(chatId.chatId).and(messageIdColumn.eq(messageId)) }.limit(1).firstOrNull() ?.get(postIdColumn) select { chatIdColumn.eq(chatId.chatId).and(threadIdColumn.eq(chatId.threadId)).and(messageIdColumn.eq(messageId)) }.limit(1).firstOrNull() ?.get(postIdColumn)
} ?.let(::PostId) } ?.let(::PostId)
} }
} }

View File

@ -3,20 +3,24 @@ package dev.inmo.plaguposter.posts.registrar.state
import dev.inmo.micro_utils.fsm.common.State import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.plaguposter.posts.models.PostContentInfo import dev.inmo.plaguposter.posts.models.PostContentInfo
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.FullChatIdentifierSerializer
import dev.inmo.tgbotapi.types.IdChatIdentifier
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
interface RegistrationState : State { interface RegistrationState : State {
override val context: ChatId override val context: IdChatIdentifier
@Serializable @Serializable
data class InProcess( data class InProcess(
override val context: ChatId, @Serializable(FullChatIdentifierSerializer::class)
override val context: IdChatIdentifier,
val messages: List<PostContentInfo> val messages: List<PostContentInfo>
) : RegistrationState ) : RegistrationState
@Serializable @Serializable
data class Finish( data class Finish(
override val context: ChatId, @Serializable(FullChatIdentifierSerializer::class)
override val context: IdChatIdentifier,
val messages: List<PostContentInfo> val messages: List<PostContentInfo>
) : RegistrationState ) : RegistrationState
} }

View File

@ -22,12 +22,12 @@ import dev.inmo.tgbotapi.extensions.utils.extensions.raw.text
import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat
import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage
import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities
import dev.inmo.tgbotapi.extensions.utils.formatting.regular
import dev.inmo.tgbotapi.extensions.utils.mediaGroupMessageOrNull
import dev.inmo.tgbotapi.extensions.utils.textContentOrNull import dev.inmo.tgbotapi.extensions.utils.textContentOrNull
import dev.inmo.tgbotapi.extensions.utils.types.buttons.* import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.MediaGroupContent
import dev.inmo.tgbotapi.types.message.content.MessageContent import dev.inmo.tgbotapi.types.message.content.MessageContent
import dev.inmo.tgbotapi.utils.regular
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import org.koin.core.Koin import org.koin.core.Koin
@ -43,7 +43,7 @@ object Plugin : Plugin {
val messageToDelete = send( val messageToDelete = send(
state.context, state.context,
buildEntities { dev.inmo.tgbotapi.utils.buildEntities {
if (state.messages.isNotEmpty()) { if (state.messages.isNotEmpty()) {
regular("Your message(s) has been registered. You may send new ones or push \"Finish\" to finalize your post") regular("Your message(s) has been registered. You may send new ones or push \"Finish\" to finalize your post")
} else { } else {
@ -65,18 +65,11 @@ object Plugin : Plugin {
val newMessagesInfo = firstOf { val newMessagesInfo = firstOf {
add { add {
listOf( listOf(
waitContentMessage( waitContentMessage().filter {
includeMediaGroups = false
).filter {
it.chat.id == state.context && it.content.textContentOrNull() ?.text != "/finish_post" it.chat.id == state.context && it.content.textContentOrNull() ?.text != "/finish_post"
}.take(1).first() }.take(1).first()
) )
} }
add {
waitMediaGroupMessages().filter {
it.first().chat.id == state.context
}.take(1).first()
}
add { add {
val finishPressed = waitMessageDataCallbackQuery().filter { val finishPressed = waitMessageDataCallbackQuery().filter {
it.message.sameMessage(messageToDelete) && it.data == buttonUuid it.message.sameMessage(messageToDelete) && it.data == buttonUuid
@ -95,8 +88,8 @@ object Plugin : Plugin {
state.context, state.context,
state.messages state.messages
) )
}.map { }.flatMap {
PostContentInfo.fromMessage(it, state.messages.size) PostContentInfo.fromMessage(it)
} }
RegistrationState.InProcess( RegistrationState.InProcess(
@ -121,25 +114,9 @@ object Plugin : Plugin {
} }
onContentMessage( onContentMessage(
initialFilter = { it.chat.id == config.sourceChatId && it.mediaGroupMessageOrNull() ?.mediaGroupId == null && !FirstSourceIsCommandsFilter(it) } initialFilter = { it.chat.id == config.sourceChatId && !FirstSourceIsCommandsFilter(it) }
) { ) {
startChain(RegistrationState.Finish(it.chat.id, listOf(PostContentInfo.fromMessage(it, 0)))) startChain(RegistrationState.Finish(it.chat.id, PostContentInfo.fromMessage(it)))
}
onMediaGroup(
initialFilter = { it.first().chat.id == config.sourceChatId }
) {
startChain(
RegistrationState.Finish(
it.first().chat.id,
it.map {
PostContentInfo.fromMessage(
it,
0
)
}
)
)
} }
koin.getOrNull<InlineTemplatesRepo>() ?.apply { koin.getOrNull<InlineTemplatesRepo>() ?.apply {
addTemplate( addTemplate(

View File

@ -4,6 +4,7 @@ import dev.inmo.micro_utils.repos.exposed.initTable
import dev.inmo.micro_utils.repos.exposed.keyvalue.AbstractExposedKeyValueRepo import dev.inmo.micro_utils.repos.exposed.keyvalue.AbstractExposedKeyValueRepo
import dev.inmo.plaguposter.common.ShortMessageInfo import dev.inmo.plaguposter.common.ShortMessageInfo
import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.IdChatIdentifier
import dev.inmo.tgbotapi.types.PollIdentifier import dev.inmo.tgbotapi.types.PollIdentifier
import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.* import org.jetbrains.exposed.sql.statements.*
@ -16,10 +17,11 @@ class ExposedPollsToMessagesInfoRepo(
) { ) {
override val keyColumn = text("poll_id") override val keyColumn = text("poll_id")
private val chatIdColumn = long("chat_id") private val chatIdColumn = long("chat_id")
private val threadIdColumn = long("thread_id").nullable().default(null)
private val messageIdColumn = long("message_id") private val messageIdColumn = long("message_id")
override val selectById: SqlExpressionBuilder.(PollIdentifier) -> Op<Boolean> = { keyColumn.eq(it) } override val selectById: ISqlExpressionBuilder.(PollIdentifier) -> Op<Boolean> = { keyColumn.eq(it) }
override val selectByValue: SqlExpressionBuilder.(ShortMessageInfo) -> Op<Boolean> = { override val selectByValue: ISqlExpressionBuilder.(ShortMessageInfo) -> Op<Boolean> = {
chatIdColumn.eq(it.chatId.chatId).and( chatIdColumn.eq(it.chatId.chatId).and(threadIdColumn.eq(it.chatId.threadId)).and(
messageIdColumn.eq(it.messageId) messageIdColumn.eq(it.messageId)
) )
} }
@ -27,7 +29,7 @@ class ExposedPollsToMessagesInfoRepo(
get() = get(keyColumn) get() = get(keyColumn)
override val ResultRow.asObject: ShortMessageInfo override val ResultRow.asObject: ShortMessageInfo
get() = ShortMessageInfo( get() = ShortMessageInfo(
get(chatIdColumn).let(::ChatId), IdChatIdentifier(get(chatIdColumn), get(threadIdColumn)),
get(messageIdColumn) get(messageIdColumn)
) )
@ -37,6 +39,7 @@ class ExposedPollsToMessagesInfoRepo(
override fun update(k: PollIdentifier, v: ShortMessageInfo, it: UpdateBuilder<Int>) { override fun update(k: PollIdentifier, v: ShortMessageInfo, it: UpdateBuilder<Int>) {
it[chatIdColumn] = v.chatId.chatId it[chatIdColumn] = v.chatId.chatId
it[threadIdColumn] = v.chatId.threadId
it[messageIdColumn] = v.messageId it[messageIdColumn] = v.messageId
} }

View File

@ -12,8 +12,8 @@ class ExposedPollsToPostsIdsRepo(
) : PollsToPostsIdsRepo, AbstractExposedKeyValueRepo<PollIdentifier, PostId>(database, "polls_to_posts") { ) : PollsToPostsIdsRepo, AbstractExposedKeyValueRepo<PollIdentifier, PostId>(database, "polls_to_posts") {
override val keyColumn = text("poll_id") override val keyColumn = text("poll_id")
val postIdColumn = text("postId") val postIdColumn = text("postId")
override val selectById: SqlExpressionBuilder.(PollIdentifier) -> Op<Boolean> = { keyColumn.eq(it) } override val selectById: ISqlExpressionBuilder.(PollIdentifier) -> Op<Boolean> = { keyColumn.eq(it) }
override val selectByValue: SqlExpressionBuilder.(PostId) -> Op<Boolean> = { postIdColumn.eq(it.string) } override val selectByValue: ISqlExpressionBuilder.(PostId) -> Op<Boolean> = { postIdColumn.eq(it.string) }
override val ResultRow.asKey: PollIdentifier override val ResultRow.asKey: PollIdentifier
get() = get(keyColumn) get() = get(keyColumn)
override val ResultRow.asObject: PostId override val ResultRow.asObject: PostId

View File

@ -17,8 +17,8 @@ class ExposedRatingsRepo (
) { ) {
override val keyColumn = text("post_id") override val keyColumn = text("post_id")
val ratingsColumn = double("rating") val ratingsColumn = double("rating")
override val selectById: SqlExpressionBuilder.(PostId) -> Op<Boolean> = { keyColumn.eq(it.string) } override val selectById: ISqlExpressionBuilder.(PostId) -> Op<Boolean> = { keyColumn.eq(it.string) }
override val selectByValue: SqlExpressionBuilder.(Rating) -> Op<Boolean> = { ratingsColumn.eq(it.double) } override val selectByValue: ISqlExpressionBuilder.(Rating) -> Op<Boolean> = { ratingsColumn.eq(it.double) }
override val ResultRow.asKey: PostId override val ResultRow.asKey: PostId
get() = get(keyColumn).let(::PostId) get() = get(keyColumn).let(::PostId)
override val ResultRow.asObject: Rating override val ResultRow.asObject: Rating