mirror of
https://github.com/InsanusMokrassar/PlaguPoster.git
synced 2024-12-22 14:07:14 +00:00
improvements
This commit is contained in:
parent
b1eed5ca1c
commit
36bedff5f3
@ -1,7 +1,10 @@
|
|||||||
package dev.inmo.plaguposter.posts.models
|
package dev.inmo.plaguposter.posts.models
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.mediaGroupMessageOrNull
|
||||||
import dev.inmo.tgbotapi.types.ChatId
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
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.content.MessageContent
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@ -10,4 +13,13 @@ data class PostContentInfo(
|
|||||||
val messageId: MessageIdentifier,
|
val messageId: MessageIdentifier,
|
||||||
val group: String?,
|
val group: String?,
|
||||||
val order: Int
|
val order: Int
|
||||||
)
|
) {
|
||||||
|
companion object {
|
||||||
|
fun fromMessage(message: ContentMessage<*>, order: Int) = PostContentInfo(
|
||||||
|
message.chat.id,
|
||||||
|
message.messageId,
|
||||||
|
message.mediaGroupMessageOrNull() ?.mediaGroupId,
|
||||||
|
order
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ import org.koin.core.module.Module
|
|||||||
|
|
||||||
object Plugin : Plugin {
|
object Plugin : Plugin {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Config(
|
private data class Config(
|
||||||
@SerialName("targetChat")
|
@SerialName("targetChat")
|
||||||
val targetChatId: ChatId,
|
val targetChatId: ChatId,
|
||||||
@SerialName("cacheChat")
|
@SerialName("cacheChat")
|
||||||
|
21
posts_registrar/build.gradle
Normal file
21
posts_registrar/build.gradle
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
id "com.android.library"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppProjectWithSerializationPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api project(":plaguposter.posts")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jvmMain {
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
posts_registrar/src/commonMain/kotlin/PackageInfo.kt
Normal file
1
posts_registrar/src/commonMain/kotlin/PackageInfo.kt
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dev.inmo.plaguposter.posts.registrar
|
@ -0,0 +1,22 @@
|
|||||||
|
package dev.inmo.plaguposter.posts.registrar.state
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.fsm.common.State
|
||||||
|
import dev.inmo.plaguposter.posts.models.PostContentInfo
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
interface RegistrationState : State {
|
||||||
|
override val context: ChatId
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class InProcess(
|
||||||
|
override val context: ChatId,
|
||||||
|
val messages: List<PostContentInfo>
|
||||||
|
) : RegistrationState
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Finish(
|
||||||
|
override val context: ChatId,
|
||||||
|
val messages: List<PostContentInfo>
|
||||||
|
) : RegistrationState
|
||||||
|
}
|
166
posts_registrar/src/jvmMain/kotlin/Plugin.kt
Normal file
166
posts_registrar/src/jvmMain/kotlin/Plugin.kt
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
package dev.inmo.plaguposter.posts.registrar
|
||||||
|
|
||||||
|
import com.benasher44.uuid.uuid4
|
||||||
|
import dev.inmo.kslog.common.logger
|
||||||
|
import dev.inmo.kslog.common.w
|
||||||
|
import dev.inmo.micro_utils.coroutines.firstOf
|
||||||
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
|
import dev.inmo.micro_utils.fsm.common.State
|
||||||
|
import dev.inmo.micro_utils.repos.create
|
||||||
|
import dev.inmo.plagubot.Plugin
|
||||||
|
import dev.inmo.plaguposter.posts.models.NewPost
|
||||||
|
import dev.inmo.plaguposter.posts.models.PostContentInfo
|
||||||
|
import dev.inmo.plaguposter.posts.registrar.state.RegistrationState
|
||||||
|
import dev.inmo.plaguposter.posts.repo.PostsRepo
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.delete
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.edit.edit
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.send.send
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.*
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.strictlyOn
|
||||||
|
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.extensions.sameMessage
|
||||||
|
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.types.buttons.*
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
|
||||||
|
import dev.inmo.tgbotapi.requests.send.SendTextMessage
|
||||||
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.MessageContent
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.TextContent
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
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
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object Plugin : Plugin {
|
||||||
|
@Serializable
|
||||||
|
private data class Config(
|
||||||
|
@SerialName("sourceChat")
|
||||||
|
val sourceChatId: ChatId
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun Module.setupDI(database: Database, params: JsonObject) {
|
||||||
|
val configJson = params["registrar"] ?: this@Plugin.let {
|
||||||
|
it.logger.w {
|
||||||
|
"Unable to load posts plugin due to absence of `registrar` key in config"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
single { get<Json>().decodeFromJsonElement(Config.serializer(), configJson) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) {
|
||||||
|
val config = koin.get<Config>()
|
||||||
|
val postsRepo = koin.get<PostsRepo>()
|
||||||
|
|
||||||
|
strictlyOn {state: RegistrationState.InProcess ->
|
||||||
|
val buttonUuid = "finish"
|
||||||
|
|
||||||
|
val messageToDelete = send(
|
||||||
|
state.context,
|
||||||
|
buildEntities {
|
||||||
|
if (state.messages.isNotEmpty()) {
|
||||||
|
regular("Your message(s) has been registered. You may send new ones or push \"Finish\" to finalize your post")
|
||||||
|
} else {
|
||||||
|
regular("Ok, send me your messages for new post")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
replyMarkup = if (state.messages.isNotEmpty()) {
|
||||||
|
flatInlineKeyboard {
|
||||||
|
dataButton(
|
||||||
|
"Finish",
|
||||||
|
buttonUuid
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
val newMessagesInfo = firstOf {
|
||||||
|
add {
|
||||||
|
listOf(
|
||||||
|
waitContentMessage(
|
||||||
|
includeMediaGroups = false
|
||||||
|
).filter {
|
||||||
|
it.chat.id == state.context
|
||||||
|
}.take(1).first()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add {
|
||||||
|
waitMediaGroupMessages().filter {
|
||||||
|
it.first().chat.id == state.context
|
||||||
|
}.take(1).first()
|
||||||
|
}
|
||||||
|
add {
|
||||||
|
val finishPressed = waitMessageDataCallbackQuery().filter {
|
||||||
|
it.message.sameMessage(messageToDelete) && it.data == buttonUuid
|
||||||
|
}.first()
|
||||||
|
emptyList<ContentMessage<MessageContent>>()
|
||||||
|
}
|
||||||
|
}.ifEmpty {
|
||||||
|
edit(messageToDelete, "Ok, finishing your request")
|
||||||
|
return@strictlyOn RegistrationState.Finish(
|
||||||
|
state.context,
|
||||||
|
state.messages
|
||||||
|
)
|
||||||
|
}.map {
|
||||||
|
PostContentInfo.fromMessage(it, state.messages.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
RegistrationState.InProcess(
|
||||||
|
state.context,
|
||||||
|
state.messages + newMessagesInfo
|
||||||
|
).also {
|
||||||
|
delete(messageToDelete)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
strictlyOn { state: RegistrationState.Finish ->
|
||||||
|
postsRepo.create(
|
||||||
|
NewPost(
|
||||||
|
state.messages
|
||||||
|
)
|
||||||
|
).firstOrNull() ?.let {
|
||||||
|
send(state.context, "Ok, you have registered ${it.content.size} messages as new post")
|
||||||
|
} ?: send(
|
||||||
|
state.context,
|
||||||
|
"Sorry, for some reason I was unable to register your post"
|
||||||
|
)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
onCommand("start_post", initialFilter = { it.chat.id == config.sourceChatId }) {
|
||||||
|
startChain(RegistrationState.InProcess(it.chat.id, emptyList()))
|
||||||
|
}
|
||||||
|
|
||||||
|
onContentMessage(
|
||||||
|
initialFilter = { it.chat.id == config.sourceChatId && it.mediaGroupMessageOrNull() ?.mediaGroupId == null }
|
||||||
|
) {
|
||||||
|
startChain(RegistrationState.Finish(it.chat.id, listOf(PostContentInfo.fromMessage(it, 0))))
|
||||||
|
}
|
||||||
|
|
||||||
|
onMediaGroup(
|
||||||
|
initialFilter = { it.first().chat.id == config.sourceChatId }
|
||||||
|
) {
|
||||||
|
startChain(
|
||||||
|
RegistrationState.Finish(
|
||||||
|
it.first().chat.id,
|
||||||
|
it.map {
|
||||||
|
PostContentInfo.fromMessage(
|
||||||
|
it,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
posts_registrar/src/main/AndroidManifest.xml
Normal file
1
posts_registrar/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="dev.inmo.plaguposter.posts.registrar"/>
|
@ -1,7 +1,8 @@
|
|||||||
rootProject.name = 'plaguposter'
|
rootProject.name = 'plaguposter'
|
||||||
|
|
||||||
String[] includes = [
|
String[] includes = [
|
||||||
":posts"
|
":posts",
|
||||||
|
":posts_registrar"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
23
template/build.gradle
Normal file
23
template/build.gradle
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
plugins {
|
||||||
|
id "org.jetbrains.kotlin.multiplatform"
|
||||||
|
id "org.jetbrains.kotlin.plugin.serialization"
|
||||||
|
id "com.android.library"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply from: "$mppProjectWithSerializationPresetPath"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api libs.tgbotapi
|
||||||
|
api libs.microutils.repos.common
|
||||||
|
api libs.kslog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jvmMain {
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
template/src/commonMain/kotlin/PackageInfo.kt
Normal file
1
template/src/commonMain/kotlin/PackageInfo.kt
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dev.inmo.plaguposter.template
|
11
template/src/jvmMain/kotlin/Plugin.kt
Normal file
11
template/src/jvmMain/kotlin/Plugin.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package dev.inmo.plaguposter.template
|
||||||
|
|
||||||
|
import dev.inmo.plagubot.Plugin
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
import org.koin.core.module.Module
|
||||||
|
|
||||||
|
object Plugin : Plugin {
|
||||||
|
override fun Module.setupDI(database: Database, params: JsonObject) {
|
||||||
|
}
|
||||||
|
}
|
1
template/src/main/AndroidManifest.xml
Normal file
1
template/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="dev.inmo.plaguposter.template"/>
|
Loading…
Reference in New Issue
Block a user