complete 1.0.0

This commit is contained in:
InsanusMokrassar 2022-05-16 13:58:16 -04:00
parent dec27b1c34
commit 77ba1d686c
6 changed files with 64 additions and 56 deletions

View File

@ -1,6 +1,9 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
@ -9,6 +12,7 @@ import org.koin.core.Koin
import org.koin.core.KoinApplication import org.koin.core.KoinApplication
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.get import org.koin.core.component.get
import org.koin.core.module.Module
import org.koin.dsl.module import org.koin.dsl.module
@Serializable @Serializable
@ -18,16 +22,18 @@ class HelloPlugin : Plugin {
data class HelloPluginConfig( data class HelloPluginConfig(
val print: String val print: String
) )
override suspend fun BehaviourContext.invoke(
database: Database,
params: JsonObject
) {
loadModule {
single {
get<Json>().decodeFromJsonElement(HelloPluginConfig.serializer(), params["helloPlugin"] ?: return@single null)
}
}
println(get<HelloPluginConfig>().print) override fun Module.setupDI(database: Database, params: JsonObject) {
single {
get<Json>().decodeFromJsonElement(HelloPluginConfig.serializer(), params["helloPlugin"] ?: return@single null)
}
}
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
println(koin.get<HelloPluginConfig>().print)
println(getMe())
onCommand("hello_world") {
reply(it, "Hello :)")
}
} }
} }

View File

@ -2,6 +2,7 @@ package dev.inmo.plagubot
import dev.inmo.plagubot.config.* import dev.inmo.plagubot.config.*
import dev.inmo.tgbotapi.bot.ktor.telegramBot import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.webhook.deleteWebhook
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -9,14 +10,14 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.KoinApplication import org.koin.core.KoinApplication
import org.koin.core.component.get
import org.koin.core.context.GlobalContext import org.koin.core.context.GlobalContext
import org.koin.core.qualifier.named import org.koin.core.module.Module
import org.koin.core.scope.Scope
import org.koin.dsl.module import org.koin.dsl.module
const val DefaultPlaguBotParamsKey = "plagubot" val Scope.plagubot: PlaguBot
val Plugin.plagubot: PlaguBot
get() = get() get() = get()
@Serializable @Serializable
@ -27,12 +28,30 @@ data class PlaguBot(
@Transient @Transient
private val bot = telegramBot(config.botToken) private val bot = telegramBot(config.botToken)
override suspend fun BehaviourContext.invoke( override fun Module.setupDI(database: Database, params: JsonObject) {
database: Database, single { config }
params: JsonObject single { config.plugins }
) { single { config.databaseConfig }
single { config.databaseConfig.database }
single { defaultJsonFormat }
single { this@PlaguBot }
includes(
config.plugins.map {
module {
with(it) {
setupDI(database, params)
}
}
}
)
}
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
config.plugins.forEach { config.plugins.forEach {
it.apply { invoke(database, params) } with(it) {
setupBotPlugin(koin)
}
} }
} }
@ -40,25 +59,21 @@ data class PlaguBot(
* This method will create an [Job] which will be the main [Job] of ran instance * This method will create an [Job] which will be the main [Job] of ran instance
*/ */
suspend fun start( suspend fun start(
scope: CoroutineScope = CoroutineScope(Dispatchers.Default) scope: CoroutineScope = CoroutineScope(Dispatchers.IO)
): Job { ): Job {
val koinApp = KoinApplication.init() val koinApp = KoinApplication.init()
koinApp.modules( koinApp.modules(
module { module {
single { config } setupDI(config.databaseConfig.database, json)
single { config.plugins }
single { config.database }
single(named(defaultDatabaseParamsName)) { config.database.database }
single { defaultJsonFormat }
single(named(DefaultPlaguBotParamsKey)) { this@PlaguBot }
} }
) )
GlobalContext.startKoin(koinApp)
lateinit var behaviourContext: BehaviourContext lateinit var behaviourContext: BehaviourContext
bot.buildBehaviour(scope = scope) { bot.buildBehaviour(scope = scope) {
invoke(config.database.database, json)
behaviourContext = this behaviourContext = this
setupBotPlugin(koinApp.koin)
deleteWebhook()
} }
GlobalContext.startKoin(koinApp)
return bot.startGettingOfUpdatesByLongPolling(scope = behaviourContext, updatesFilter = behaviourContext) return bot.startGettingOfUpdatesByLongPolling(scope = behaviourContext, updatesFilter = behaviourContext)
} }
} }

View File

@ -1,11 +1,13 @@
package dev.inmo.plagubot.config package dev.inmo.plagubot.config
import dev.inmo.plagubot.Plugin import dev.inmo.plagubot.Plugin
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
data class Config( data class Config(
val botToken: String, val botToken: String,
val plugins: List<Plugin>, val plugins: List<Plugin>,
val database: DatabaseConfig = DatabaseConfig(), @SerialName("database")
val databaseConfig: DatabaseConfig = DatabaseConfig(),
) )

View File

@ -1,21 +1,15 @@
package dev.inmo.plagubot.config package dev.inmo.plagubot.config
import dev.inmo.plagubot.Plugin
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.transactions.transactionManager import org.jetbrains.exposed.sql.transactions.transactionManager
import org.koin.core.KoinApplication
import org.koin.core.context.loadKoinModules
import org.koin.core.qualifier.StringQualifier
import org.koin.core.qualifier.named
import org.koin.core.scope.Scope import org.koin.core.scope.Scope
import org.sqlite.JDBC import org.sqlite.JDBC
import java.sql.Connection import java.sql.Connection
const val defaultDatabaseParamsName = "defaultDatabase" inline val Scope.database: Database?
inline val Plugin.database: Database? get() = getOrNull<Database>()
get() = getKoin().getOrNull<Database>(named(defaultDatabaseParamsName))
@Serializable @Serializable
data class DatabaseConfig( data class DatabaseConfig(

View File

@ -32,7 +32,7 @@ class ConfigTest {
PluginsConfigurationSerializer, PluginsConfigurationSerializer,
configAndPluginsConfigJsonFormat.encodeToString(PluginsConfigurationSerializer, config) configAndPluginsConfigJsonFormat.encodeToString(PluginsConfigurationSerializer, config)
) as Config ) as Config
assertEquals(config.database, redecoded.database) assertEquals(config.databaseConfig, redecoded.databaseConfig)
assertEquals(config.plugins, redecoded.plugins) assertEquals(config.plugins, redecoded.plugins)
assertEquals(config.botToken, redecoded.botToken) assertEquals(config.botToken, redecoded.botToken)
assertEquals(config.params ?.toMap(), redecoded.params ?.toMap()) assertEquals(config.params ?.toMap(), redecoded.params ?.toMap())

View File

@ -1,18 +1,11 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import kotlinx.coroutines.CoroutineScope
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
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.KoinApplication import org.koin.core.module.Module
import org.koin.core.component.KoinComponent
import org.koin.dsl.ModuleDeclaration
import org.koin.dsl.module
/** /**
* **ANY REALIZATION OF [Plugin] MUST HAVE CONSTRUCTOR WITH ABSENCE OF INCOMING PARAMETERS** * **ANY REALIZATION OF [Plugin] MUST HAVE CONSTRUCTOR WITH ABSENCE OF INCOMING PARAMETERS**
@ -22,17 +15,15 @@ import org.koin.dsl.module
* too. * too.
*/ */
@Serializable(PluginSerializer::class) @Serializable(PluginSerializer::class)
interface Plugin : KoinComponent { interface Plugin {
fun loadModule(createdAtStart: Boolean = false, moduleDeclaration: ModuleDeclaration) = getKoin().loadModules(
listOf(
module(createdAtStart, moduleDeclaration)
)
)
/** /**
* This method (usually) will be invoked just one time in the whole application. * This method will be called when this plugin should configure di module based on the incoming params
*/ */
suspend operator fun BehaviourContext.invoke( fun Module.setupDI(
database: Database, database: Database,
params: JsonObject params: JsonObject
) {} )
suspend fun BehaviourContext.setupBotPlugin(
koin: Koin
)
} }