production ready?

This commit is contained in:
2022-09-04 15:46:45 +06:00
parent 1e393103c8
commit e8637a2de6
12 changed files with 130 additions and 19 deletions

View File

@@ -3,5 +3,8 @@ package dev.inmo.plaguposter.posts.repo
import dev.inmo.micro_utils.repos.ReadCRUDRepo
import dev.inmo.micro_utils.repos.WriteCRUDRepo
import dev.inmo.plaguposter.posts.models.*
import kotlinx.coroutines.flow.Flow
interface WritePostsRepo : WriteCRUDRepo<RegisteredPost, PostId, NewPost>
interface WritePostsRepo : WriteCRUDRepo<RegisteredPost, PostId, NewPost> {
val removedPostsFlow: Flow<RegisteredPost>
}

View File

@@ -2,20 +2,37 @@ package dev.inmo.plaguposter.posts
import dev.inmo.kslog.common.logger
import dev.inmo.kslog.common.w
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.repos.deleteById
import dev.inmo.plagubot.Plugin
import dev.inmo.plaguposter.common.SuccessfulSymbol
import dev.inmo.plaguposter.common.UnsuccessfulSymbol
import dev.inmo.plaguposter.posts.exposed.ExposedPostsRepo
import dev.inmo.plaguposter.posts.models.ChatConfig
import dev.inmo.plaguposter.posts.repo.*
import dev.inmo.plaguposter.posts.sending.PostPublisher
import dev.inmo.tgbotapi.extensions.api.delete
import dev.inmo.tgbotapi.extensions.api.edit.edit
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.message.textsources.regular
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.*
import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.module.Module
import org.koin.dsl.binds
object Plugin : Plugin {
@Serializable
data class Config(
val chats: ChatConfig,
val autoRemoveMessages: Boolean = true
)
override fun Module.setupDI(database: Database, params: JsonObject) {
val configJson = params["posts"] ?: this@Plugin.let {
it.logger.w {
@@ -23,7 +40,8 @@ object Plugin : Plugin {
}
return
}
single { get<Json>().decodeFromJsonElement(ChatConfig.serializer(), configJson) }
single { get<Json>().decodeFromJsonElement(Config.serializer(), configJson) }
single { get<Config>().chats }
single { ExposedPostsRepo(database) } binds arrayOf(
PostsRepo::class,
ReadPostsRepo::class,
@@ -34,4 +52,39 @@ object Plugin : Plugin {
PostPublisher(get(), get(), config.cacheChatId, config.targetChatId)
}
}
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
val postsRepo = koin.get<PostsRepo>()
val config = koin.get<Config>()
if (config.autoRemoveMessages) {
postsRepo.removedPostsFlow.subscribeSafelyWithoutExceptions(this) {
it.content.forEach {
runCatchingSafely {
delete(it.chatId, it.messageId)
}
}
}
}
onCommand("delete_post", requireOnlyCommandInMessage = true) {
val messageInReply = it.replyTo ?: run {
reply(it, "Reply some message of post to delete it")
return@onCommand
}
val postId = postsRepo.getIdByChatAndMessage(messageInReply.chat.id, messageInReply.messageId) ?: run {
reply(it, "Unable to find post id by message")
return@onCommand
}
postsRepo.deleteById(postId)
if (postsRepo.contains(postId)) {
edit(it, it.content.textSources + regular(UnsuccessfulSymbol))
} else {
edit(it, it.content.textSources + regular(SuccessfulSymbol))
}
}
}
}

View File

@@ -8,6 +8,7 @@ import dev.inmo.plaguposter.posts.models.*
import dev.inmo.plaguposter.posts.repo.PostsRepo
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.MessageIdentifier
import kotlinx.coroutines.flow.*
import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.InsertStatement
@@ -45,6 +46,9 @@ class ExposedPostsRepo(
)
}
private val _removedPostsFlow = MutableSharedFlow<RegisteredPost>()
override val removedPostsFlow: Flow<RegisteredPost> = _removedPostsFlow.asSharedFlow()
init {
initTable()
}
@@ -93,24 +97,29 @@ class ExposedPostsRepo(
override suspend fun deleteById(ids: List<PostId>) {
onBeforeDelete(ids)
val posts = ids.mapNotNull {
getById(it)
}.associateBy { it.id }
val existsIds = posts.keys.toList()
transaction(db = database) {
val deleted = deleteWhere(null, null) {
selectByIds(ids)
selectByIds(existsIds)
}
with(contentRepo) {
deleteWhere {
postIdColumn.inList(ids.map { it.string })
postIdColumn.inList(existsIds.map { it.string })
}
}
if (deleted == ids.size) {
ids
if (deleted == existsIds.size) {
existsIds
} else {
ids.filter {
existsIds.filter {
select { selectById(it) }.limit(1).none()
}
}
}.forEach {
_deletedObjectsIdsFlow.emit(it)
_removedPostsFlow.emit(posts[it] ?: return@forEach)
}
}