Compare commits

...

14 Commits

15 changed files with 128 additions and 56 deletions

View File

@@ -1,5 +1,35 @@
# Changelog # Changelog
## 8.1.0
* Integrate `dev.inmo:micro_utils.startup` into project
## 8.0.0
* `Versions`:
* `tgbotapi`: `1.0.0`
* `MicroUtils`: `0.20.26`
* `Exposed`: `0.46.0`
## 7.4.2
* `Versions`:
* `Kotlin`: `1.9.22`
* `tgbotapi`: `9.4.3`
* `MicroUtils`: `0.20.23`
* `Koin`: `3.5.7`
## 7.4.1
* `Versions`:
* `Serialization`: `1.6.2`
* `tgbotapi`: `9.4.2`
* `Exposed`: `0.45.0`
* `SQLite`: `3.44.1.0`
* `MicroUtils`: `0.20.19`
* `uuid`: `0.8.2`
* `ktor`: `2.3.7`
## 7.3.0 ## 7.3.0
* `Versions`: * `Versions`:

View File

@@ -20,6 +20,7 @@ dependencies {
api libs.tgbotapi.behaviourBuilder.fsm api libs.tgbotapi.behaviourBuilder.fsm
api libs.microutils.repos.exposed api libs.microutils.repos.exposed
api libs.microutils.koin api libs.microutils.koin
api libs.microutils.startup.launcher
api libs.sqlite api libs.sqlite

View File

@@ -49,18 +49,14 @@ publishing {
} }
} }
repositories { repositories {
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) { if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
maven { maven {
name = "Gitea" name = "InmoNexus"
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven") url = uri("https://nexus.inmo.dev/repository/maven-releases/")
credentials(HttpHeaderCredentials) { credentials {
name = "Authorization" username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN') password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
}
authentication {
header(HttpHeaderAuthentication)
} }
} }

View File

@@ -1 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Bot","description":"Base PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"} {"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Bot","description":"Base PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}

View File

@@ -32,8 +32,6 @@ object HelloPlugin : Plugin {
override fun Module.setupDI(database: Database, params: JsonObject) { override fun Module.setupDI(database: Database, params: JsonObject) {
single { single {
get<Json>().decodeFromJsonElement(HelloPluginConfig.serializer(), params["helloPlugin"] ?: return@single null) get<Json>().decodeFromJsonElement(HelloPluginConfig.serializer(), params["helloPlugin"] ?: return@single null)
} }
} }
@@ -43,6 +41,11 @@ object HelloPlugin : Plugin {
data class SaidHelloOnce(override val context: IdChatIdentifier) : InternalFSMState data class SaidHelloOnce(override val context: IdChatIdentifier) : InternalFSMState
} }
override suspend fun startPlugin(koin: Koin) {
super.startPlugin(koin)
logger.i { "This logic called BEFORE the bot will be started and setup" }
}
override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) { override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) {
val toPrint = koin.getOrNull<HelloPluginConfig>() ?.print ?: "Hello :)" val toPrint = koin.getOrNull<HelloPluginConfig>() ?.print ?: "Hello :)"
logger.d { toPrint } logger.d { toPrint }

View File

@@ -8,6 +8,7 @@ import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.* import dev.inmo.micro_utils.fsm.common.managers.*
import dev.inmo.micro_utils.koin.getAllDistinct import dev.inmo.micro_utils.koin.getAllDistinct
import dev.inmo.plagubot.config.* import dev.inmo.plagubot.config.*
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
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.api.webhook.deleteWebhook
import dev.inmo.tgbotapi.extensions.behaviour_builder.* import dev.inmo.tgbotapi.extensions.behaviour_builder.*
@@ -37,19 +38,36 @@ data class PlaguBot(
private val config: Config private val config: Config
) : Plugin { ) : Plugin {
@Transient @Transient
private val bot = telegramBot(config.botToken) private val bot = telegramBot(
token = config.botToken,
apiUrl = config.botApiServer
) {
setupBotClient()
}
override fun Module.setupDI(database: Database, params: JsonObject) { override fun KtorRequestsExecutorBuilder.setupBotClient() {
single { config } config.botPlugins.forEach {
single { config.plugins } with(it) {
single { config.databaseConfig } setupBotClient()
single { config.databaseConfig.database } }
}
}
override fun Module.setupDI(config: JsonObject) {
single { this@PlaguBot.config }
single { this@PlaguBot.config.plugins }
single { this@PlaguBot.config.databaseConfig }
single { this@PlaguBot.config.databaseConfig.database }
single { defaultJsonFormat } single { defaultJsonFormat }
single { this@PlaguBot } single { this@PlaguBot }
single { bot } single { bot }
}
override fun Module.setupDI(database: Database, params: JsonObject) {
setupDI(params)
includes( includes(
config.plugins.mapNotNull { config.botPlugins.mapNotNull {
runCatching { runCatching {
module { module {
with(it) { with(it) {
@@ -57,14 +75,31 @@ data class PlaguBot(
} }
} }
}.onFailure { e -> }.onFailure { e ->
logger.w("Unable to load DI part of $it", e) logger.w(e) { "Unable to load DI part of $it" }
}.getOrNull() }.getOrNull()
} }
) )
} }
override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) { override suspend fun startPlugin(koin: Koin) {
super.startPlugin(koin)
config.plugins.forEach { plugin -> config.plugins.forEach { plugin ->
runCatchingSafely {
logger.i { "Starting of $plugin common logic" }
with(plugin) {
startPlugin(koin)
}
}.onFailure { e ->
logger.w(e) { "Unable to load common logic of $plugin" }
}.onSuccess {
logger.i { "Complete loading of $plugin common logic" }
}
}
}
override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) {
config.botPlugins.forEach { plugin ->
runCatchingSafely { runCatchingSafely {
logger.i("Start loading of $plugin") logger.i("Start loading of $plugin")
with(plugin) { with(plugin) {
@@ -91,9 +126,11 @@ data class PlaguBot(
setupDI(config.databaseConfig.database, json) setupDI(config.databaseConfig.database, json)
} }
) )
logger.i("Modules loaded") logger.i("Modules loaded. Starting koin")
GlobalContext.startKoin(koinApp) GlobalContext.startKoin(koinApp)
logger.i("Koin started") logger.i("Koin started. Starting plugins common logic")
startPlugin(koinApp.koin)
logger.i("Plugins common logic started. Starting setup of bot logic part")
lateinit var behaviourContext: BehaviourContext lateinit var behaviourContext: BehaviourContext
val onStartContextsConflictResolver by lazy { koinApp.koin.getAllDistinct<OnStartContextsConflictResolver>() } val onStartContextsConflictResolver by lazy { koinApp.koin.getAllDistinct<OnStartContextsConflictResolver>() }
val onUpdateContextsConflictResolver by lazy { koinApp.koin.getAllDistinct<OnUpdateContextsConflictResolver>() } val onUpdateContextsConflictResolver by lazy { koinApp.koin.getAllDistinct<OnUpdateContextsConflictResolver>() }

View File

@@ -1,15 +1,20 @@
package dev.inmo.plagubot.config package dev.inmo.plagubot.config
import dev.inmo.micro_utils.common.Warning import dev.inmo.micro_utils.common.Warning
import dev.inmo.micro_utils.startup.plugin.StartPlugin
import dev.inmo.plagubot.Plugin import dev.inmo.plagubot.Plugin
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Warning("This API is internal and can be changed without notifications of mentions of changes") @Warning("This API is internal and can be changed without notifications or mentions of changes")
@Serializable @Serializable
data class Config( data class Config(
val botToken: String, val botToken: String,
val plugins: List<Plugin>, val plugins: List<StartPlugin>,
@SerialName("database") @SerialName("database")
val databaseConfig: DatabaseConfig = DatabaseConfig(), val databaseConfig: DatabaseConfig = DatabaseConfig(),
) val botApiServer: String = telegramBotAPIDefaultUrl
) {
val botPlugins = plugins.filterIsInstance<Plugin>()
}

View File

@@ -17,7 +17,7 @@ allprojects {
mavenCentral() mavenCentral()
mavenLocal() mavenLocal()
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
maven { url "https://git.inmo.dev/api/packages/InsanusMokrassar/maven" } maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
} }
} }

View File

@@ -5,4 +5,4 @@ kotlin.js.generate.externals=true
kotlin.incremental=true kotlin.incremental=true
group=dev.inmo group=dev.inmo
version=7.4.0 version=8.1.0

View File

@@ -1,27 +1,22 @@
[versions] [versions]
kt = "1.9.21" kt = "1.9.22"
kt-serialization = "1.6.1" kt-serialization = "1.6.2"
kt-coroutines = "1.7.3" kt-coroutines = "1.7.3"
microutils = "0.20.15" microutils = "0.20.26"
tgbotapi = "9.4.1" tgbotapi = "10.0.0"
ksp = "1.9.20-1.0.14" ksp = "1.9.22-1.0.16"
jb-exposed = "0.44.1" jb-exposed = "0.46.0"
jb-dokka = "1.9.10" jb-dokka = "1.9.10"
sqlite = "3.43.0.0" sqlite = "3.44.1.0"
klock = "4.0.10"
uuid = "0.8.1"
ktor = "2.3.6"
gh-release = "2.4.1" gh-release = "2.4.1"
koin = "3.5.0" koin = "3.5.3"
[libraries] [libraries]
@@ -35,6 +30,8 @@ tgbotapi-behaviourBuilder-fsm = { module = "dev.inmo:tgbotapi.behaviour_builder.
microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" } microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" }
microutils-koin = { module = "dev.inmo:micro_utils.koin", version.ref = "microutils" } microutils-koin = { module = "dev.inmo:micro_utils.koin", version.ref = "microutils" }
microutils-koin-generator = { module = "dev.inmo:micro_utils.koin.generator", version.ref = "microutils" } microutils-koin-generator = { module = "dev.inmo:micro_utils.koin.generator", version.ref = "microutils" }
microutils-startup-launcher = { module = "dev.inmo:micro_utils.startup.launcher", version.ref = "microutils" }
microutils-startup-plugin = { module = "dev.inmo:micro_utils.startup.plugin", version.ref = "microutils" }
koin = { module = "io.insert-koin:koin-core", version.ref = "koin" } koin = { module = "io.insert-koin:koin-core", version.ref = "koin" }

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-8.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -14,6 +14,7 @@ dependencies {
api libs.tgbotapi api libs.tgbotapi
api libs.microutils.repos.exposed api libs.microutils.repos.exposed
api libs.microutils.startup.plugin
api libs.koin api libs.koin
} }

View File

@@ -49,18 +49,14 @@ publishing {
} }
} }
repositories { repositories {
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) { if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
maven { maven {
name = "Gitea" name = "InmoNexus"
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven") url = uri("https://nexus.inmo.dev/repository/maven-releases/")
credentials(HttpHeaderCredentials) { credentials {
name = "Authorization" username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN') password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
}
authentication {
header(HttpHeaderAuthentication)
} }
} }

View File

@@ -1 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Plugin","description":"Base dependency for whole PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"} {"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Plugin","description":"Base dependency for whole PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}

View File

@@ -1,6 +1,8 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.micro_utils.fsm.common.State import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.startup.plugin.StartPlugin
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -17,14 +19,18 @@ import org.koin.core.module.Module
* too. * too.
*/ */
@Serializable(PluginSerializer::class) @Serializable(PluginSerializer::class)
interface Plugin { interface Plugin : StartPlugin {
fun KtorRequestsExecutorBuilder.setupBotClient() {}
/** /**
* This method will be called when this plugin should configure di module based on the incoming params * This method will be called when this plugin should configure di module based on the incoming params
*/ */
fun Module.setupDI( fun Module.setupDI(
database: Database, database: Database,
params: JsonObject params: JsonObject
) {} ) {
setupDI(params)
}
/** /**
* Override this method in cases when you want to declare common bot behaviour. In case you wish to use FSM, you * Override this method in cases when you want to declare common bot behaviour. In case you wish to use FSM, you