Compare commits

...

17 Commits

Author SHA1 Message Date
7ffd5a1433 update dependencies 2022-07-09 00:12:24 +06:00
05e2ec1c0d start 1.2.2 2022-07-09 00:07:07 +06:00
819ed7720a Merge pull request #32 from InsanusMokrassar/1.2.1
1.2.1
2022-06-26 15:15:38 +06:00
c99e4ee188 Update CHANGELOG.md 2022-06-26 14:46:09 +06:00
a408cc5099 Update CHANGELOG.md 2022-06-26 14:45:55 +06:00
f1d3f48a6b Update libs.versions.toml 2022-06-26 14:44:13 +06:00
2777a260ae Update gradle.properties 2022-06-26 14:42:44 +06:00
155b9865a8 Merge pull request #31 from InsanusMokrassar/1.2.0
1.2.0
2022-06-22 09:05:33 +06:00
ecc17e50b9 update dependencies 2022-06-21 23:54:25 +06:00
ffafee3f43 start 1.2.0 2022-06-21 23:53:38 +06:00
b99bb9ee64 Merge pull request #30 from InsanusMokrassar/1.1.2
1.1.2
2022-06-20 20:59:53 +06:00
0dff596926 update dependencies and optimize imports 2022-06-20 20:58:38 +06:00
e0a19bb5e5 start 1.1.2 + add opportunity to load object plugins 2022-06-20 20:52:42 +06:00
5ec1c8c55f Merge pull request #29 from InsanusMokrassar/1.1.1
1.1.1
2022-06-11 19:20:33 +06:00
37fd9f39d3 fixes in logging 2022-06-11 19:19:19 +06:00
f9f56f6afb update dependencies and add logging 2022-06-11 19:15:09 +06:00
343c26a7f1 start 1.1.1 2022-06-08 17:14:50 +06:00
10 changed files with 89 additions and 36 deletions

2
.gitignore vendored
View File

@@ -10,5 +10,7 @@ build/
out/ out/
local.properties local.properties
local.*
local.*/
config.json config.json
secret.gradle secret.gradle

View File

@@ -1,5 +1,43 @@
# Changelog # Changelog
## 1.2.2
* `Versions`
* `tgbotapi`: `2.1.2`
* `microutils`: `0.11.12`
* `coroutines`: `1.6.3`
* `ktor`: `2.0.3`
## 1.2.1
* `Versions`
* `tgbotapi`: `2.1.1`
* `microutils`: `0.11.6`
* `kslog`: `0.3.2`
## 1.2.0
* `Versions`
* `tgbotapi`: `2.1.0`
## 1.1.2
* `Versions`
* `tgbotapi`: `2.0.3`
* `microutils`: `0.11.3`
* `kslog`: `0.3.1`
* `Plugin`:
* Now it is possible to use `object`s of plugins instead of classes
## 1.1.1
* `Versions`
* `coroutines`: `1.6.2`
* `tgbotapi`: `2.0.2`
* `microutils`: `0.11.0`
* `ktor`: `2.0.2`
* `uuid`: `0.4.1`
## 1.1.0 ## 1.1.0
* `Versions` * `Versions`

View File

@@ -17,6 +17,7 @@ dependencies {
api libs.tgbotapi api libs.tgbotapi
api libs.microutils.repos.exposed api libs.microutils.repos.exposed
api libs.kslog
api libs.sqlite api libs.sqlite

View File

@@ -1,7 +1,9 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.plagubot.config.* import dev.inmo.kslog.common.KSLog
import kotlinx.coroutines.* import dev.inmo.kslog.common.i
import dev.inmo.plagubot.config.Config
import dev.inmo.plagubot.config.defaultJsonFormat
import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import java.io.File import java.io.File
@@ -11,10 +13,13 @@ import java.io.File
*/ */
@InternalSerializationApi @InternalSerializationApi
suspend fun main(args: Array<String>) { suspend fun main(args: Array<String>) {
KSLog.default = KSLog("PlaguBot")
val (configPath) = args val (configPath) = args
val file = File(configPath) val file = File(configPath)
KSLog.i("Start read config from ${file.absolutePath}")
val json = defaultJsonFormat.parseToJsonElement(file.readText()).jsonObject val json = defaultJsonFormat.parseToJsonElement(file.readText()).jsonObject
val config = defaultJsonFormat.decodeFromJsonElement(Config.serializer(), json) val config = defaultJsonFormat.decodeFromJsonElement(Config.serializer(), json)
KSLog.i("Config has been read")
PlaguBot(json, config).start().join() PlaguBot(json, config).start().join()
} }

View File

@@ -1,23 +1,21 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.kslog.common.*
import dev.inmo.tgbotapi.extensions.api.bot.getMe import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.send.reply 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 dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import kotlinx.serialization.* import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
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.component.KoinComponent
import org.koin.core.component.get
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.dsl.module
@Serializable @Serializable
@SerialName("Hello") @SerialName("Hello")
class HelloPlugin : Plugin { object HelloPlugin : Plugin {
@Serializable @Serializable
data class HelloPluginConfig( data class HelloPluginConfig(
val print: String val print: String
@@ -30,8 +28,8 @@ class HelloPlugin : Plugin {
} }
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
println(koin.get<HelloPluginConfig>().print) logger.d { koin.get<HelloPluginConfig>().print }
println(getMe()) logger.dS { getMe().toString() }
onCommand("hello_world") { onCommand("hello_world") {
reply(it, "Hello :)") reply(it, "Hello :)")
} }

View File

@@ -1,10 +1,14 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.kslog.common.*
import dev.inmo.micro_utils.common.Warning
import dev.inmo.micro_utils.coroutines.runCatchingSafely import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.plagubot.config.* import dev.inmo.plagubot.config.Config
import dev.inmo.plagubot.config.defaultJsonFormat
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.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -17,19 +21,19 @@ import org.koin.core.context.GlobalContext
import org.koin.core.module.Module import org.koin.core.module.Module
import org.koin.core.scope.Scope import org.koin.core.scope.Scope
import org.koin.dsl.module import org.koin.dsl.module
import java.util.logging.Level
import java.util.logging.Logger
val Scope.plagubot: PlaguBot val Scope.plagubot: PlaguBot
get() = get() get() = get()
val Koin.plagubot: PlaguBot
get() = get()
@OptIn(Warning::class)
@Serializable @Serializable
data class PlaguBot( data class PlaguBot(
private val json: JsonObject, private val json: JsonObject,
private val config: Config private val config: Config
) : Plugin { ) : Plugin {
@Transient
private val logger = Logger.getLogger("PlaguBot")
@Transient @Transient
private val bot = telegramBot(config.botToken) private val bot = telegramBot(config.botToken)
@@ -50,24 +54,24 @@ data class PlaguBot(
} }
} }
}.onFailure { e -> }.onFailure { e ->
logger.log(Level.WARNING, "Unable to load DI part of $it", e) logger.w("Unable to load DI part of $it", e)
}.getOrNull() }.getOrNull()
} }
) )
} }
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
config.plugins.map { config.plugins.map { plugin ->
launch { launch {
runCatchingSafely { runCatchingSafely {
logger.info("Start loading of $it") logger.i("Start loading of $plugin")
with(it) { with(plugin) {
setupBotPlugin(koin) setupBotPlugin(koin)
} }
}.onFailure { e -> }.onFailure { e ->
logger.log(Level.WARNING, "Unable to load bot part of $it", e) logger.w("Unable to load bot part of $plugin", e)
}.onSuccess { }.onSuccess {
logger.info("Complete loading of $it") logger.i("Complete loading of $plugin")
} }
} }
}.joinAll() }.joinAll()
@@ -79,26 +83,26 @@ data class PlaguBot(
suspend fun start( suspend fun start(
scope: CoroutineScope = CoroutineScope(Dispatchers.IO) scope: CoroutineScope = CoroutineScope(Dispatchers.IO)
): Job { ): Job {
logger.info("Start initialization") logger.i("Start initialization")
val koinApp = KoinApplication.init() val koinApp = KoinApplication.init()
koinApp.modules( koinApp.modules(
module { module {
setupDI(config.databaseConfig.database, json) setupDI(config.databaseConfig.database, json)
} }
) )
logger.info("Modules loaded") logger.i("Modules loaded")
GlobalContext.startKoin(koinApp) GlobalContext.startKoin(koinApp)
logger.info("Koin started") logger.i("Koin started")
lateinit var behaviourContext: BehaviourContext lateinit var behaviourContext: BehaviourContext
bot.buildBehaviour(scope = scope) { bot.buildBehaviour(scope = scope) {
logger.info("Start setup of bot part") logger.i("Start setup of bot part")
behaviourContext = this behaviourContext = this
setupBotPlugin(koinApp.koin) setupBotPlugin(koinApp.koin)
deleteWebhook() deleteWebhook()
} }
logger.info("Behaviour builder has been setup") logger.i("Behaviour builder has been setup")
return bot.startGettingOfUpdatesByLongPolling(scope = behaviourContext, updatesFilter = behaviourContext).also { return bot.startGettingOfUpdatesByLongPolling(scope = behaviourContext, updatesFilter = behaviourContext).also {
logger.info("Long polling has been started") logger.i("Long polling has been started")
} }
} }
} }

View File

@@ -1,9 +1,11 @@
package dev.inmo.plagubot.config package dev.inmo.plagubot.config
import dev.inmo.micro_utils.common.Warning
import dev.inmo.plagubot.Plugin import dev.inmo.plagubot.Plugin
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")
@Serializable @Serializable
data class Config( data class Config(
val botToken: String, val botToken: String,

View File

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

View File

@@ -2,10 +2,11 @@
kt = "1.6.21" kt = "1.6.21"
kt-serialization = "1.3.3" kt-serialization = "1.3.3"
kt-coroutines = "1.6.1" kt-coroutines = "1.6.3"
microutils = "0.10.5" microutils = "0.11.12"
tgbotapi = "2.0.0" tgbotapi = "2.1.2"
kslog = "0.3.2"
jb-exposed = "0.38.2" jb-exposed = "0.38.2"
jb-dokka = "1.6.21" jb-dokka = "1.6.21"
@@ -13,11 +14,11 @@ jb-dokka = "1.6.21"
sqlite = "3.36.0.3" sqlite = "3.36.0.3"
klock = "2.7.0" klock = "2.7.0"
uuid = "0.4.0" uuid = "0.4.1"
ktor = "2.0.1" ktor = "2.0.3"
gh-release = "2.3.7" gh-release = "2.4.1"
android-gradle = "7.0.4" android-gradle = "7.0.4"
dexcount = "3.1.0" dexcount = "3.1.0"
@@ -32,6 +33,7 @@ kt-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json"
tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" } tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" }
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" }
kslog = { module = "dev.inmo:kslog", version.ref = "kslog" }
koin = { module = "io.insert-koin:koin-core", version.ref = "koin" } koin = { module = "io.insert-koin:koin-core", version.ref = "koin" }

View File

@@ -13,7 +13,8 @@ class PluginSerializer : KSerializer<Plugin> {
get() = String.serializer().descriptor get() = String.serializer().descriptor
override fun deserialize(decoder: Decoder): Plugin { override fun deserialize(decoder: Decoder): Plugin {
return Class.forName(decoder.decodeString()).getDeclaredConstructor().newInstance() as Plugin val kclass = Class.forName(decoder.decodeString()).kotlin
return (kclass.objectInstance ?: kclass.constructors.first { it.parameters.isEmpty() }.call()) as Plugin
} }
override fun serialize(encoder: Encoder, value: Plugin) { override fun serialize(encoder: Encoder, value: Plugin) {