diff --git a/.gitignore b/.gitignore index 0546396..376458b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ build/ out/ local.properties +config.json secret.gradle diff --git a/bot/build.gradle b/bot/build.gradle new file mode 100644 index 0000000..2549ab4 --- /dev/null +++ b/bot/build.gradle @@ -0,0 +1,37 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id "org.jetbrains.kotlin.plugin.serialization" + id "org.jetbrains.kotlin.kapt" + id 'application' +} + +project.group="$group" +project.version="$version" + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version" + implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" + implementation "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version" + + implementation "dev.inmo:tgbotapi:$tgbotapi_version" + implementation "dev.inmo:micro_utils.repos.exposed:$microutils_version" + + implementation "com.github.matfax.klassindex:library:$klassindex_version" + kapt "com.github.matfax.klassindex:processor:$klassindex_version" + implementation "org.xerial:sqlite-jdbc:$sqlite_version" + + implementation project(":plugin") +} + +application { + mainClassName = 'dev.inmo.plagubot.AppKt' +} + +kapt { + arguments { + arg("com.github.matfax.klassindex.IndexSubclasses", "dev.inmo.plagubot.Plugin") + } +} + diff --git a/src/main/kotlin/dev/inmo/plagubot/App.kt b/bot/src/main/kotlin/dev/inmo/plagubot/App.kt similarity index 89% rename from src/main/kotlin/dev/inmo/plagubot/App.kt rename to bot/src/main/kotlin/dev/inmo/plagubot/App.kt index b9cfc6a..c945643 100644 --- a/src/main/kotlin/dev/inmo/plagubot/App.kt +++ b/bot/src/main/kotlin/dev/inmo/plagubot/App.kt @@ -1,16 +1,20 @@ package dev.inmo.plagubot import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions +import dev.inmo.plagubot.config.Config +import dev.inmo.plagubot.config.configSerialFormat import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands import dev.inmo.tgbotapi.extensions.api.telegramBot import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling import dev.inmo.tgbotapi.types.botCommandsLimit import kotlinx.coroutines.* +import kotlinx.serialization.InternalSerializationApi import java.io.File /** * This method by default expects one argument in [args] field: path to config */ +@InternalSerializationApi suspend fun main(args: Array) { val (configPath) = args val file = File(configPath) @@ -37,5 +41,4 @@ suspend fun main(args: Array) { } } } - } diff --git a/bot/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt b/bot/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt new file mode 100644 index 0000000..19ef11e --- /dev/null +++ b/bot/src/main/kotlin/dev/inmo/plagubot/HelloPlugin.kt @@ -0,0 +1,23 @@ +package dev.inmo.plagubot + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter +import kotlinx.coroutines.CoroutineScope +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import org.jetbrains.exposed.sql.Database + +@Serializable +@SerialName("Hello") +data class HelloPlugin( + val parameter: String +) : Plugin { + override suspend fun invoke( + bot: TelegramBot, + database: Database, + updatesFilter: FlowsUpdatesFilter, + scope: CoroutineScope + ) { + println(parameter) + } +} diff --git a/bot/src/main/kotlin/dev/inmo/plagubot/config/Config.kt b/bot/src/main/kotlin/dev/inmo/plagubot/config/Config.kt new file mode 100644 index 0000000..5fea6be --- /dev/null +++ b/bot/src/main/kotlin/dev/inmo/plagubot/config/Config.kt @@ -0,0 +1,42 @@ +package dev.inmo.plagubot.config + +import com.github.matfax.klassindex.KlassIndex +import dev.inmo.plagubot.Plugin +import kotlinx.serialization.* +import kotlinx.serialization.json.Json +import kotlinx.serialization.modules.* +import kotlin.reflect.KClass + +@InternalSerializationApi +internal inline fun KClass.includeIn(builder: PolymorphicModuleBuilder) = builder.subclass(this, serializer()) + +@InternalSerializationApi +internal val configSerialFormat: StringFormat + get() = Json { + ignoreUnknownKeys = true + serializersModule = SerializersModule { + polymorphic(Plugin::class) { + KlassIndex.getSubclasses(Plugin::class).flatMap { kclass -> + kclass.includeIn(this) + kclass.annotations.mapNotNull { it as? SerialName }.map { + it.value to kclass.serializer() + } + listOfNotNull( + kclass.simpleName ?.let { + it to kclass.serializer() + } + ) + }.toMap().let { + default { requiredType -> + it[requiredType] + } + } + } + } + } + +@Serializable +data class Config( + val plugins: List<@Contextual Plugin>, + val database: DatabaseConfig, + val botToken: String +) diff --git a/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt b/bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt similarity index 82% rename from src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt rename to bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt index cee3daa..1d1b4e0 100644 --- a/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt +++ b/bot/src/main/kotlin/dev/inmo/plagubot/config/DatabaseConfig.kt @@ -9,7 +9,7 @@ import java.sql.Connection @Serializable data class DatabaseConfig( - val url: String, + val url: String = "jdbc:sqlite:file:test?mode=memory&cache=shared", val driver: String = JDBC::class.qualifiedName!!, val username: String = "", val password: String = "", @@ -37,12 +37,4 @@ data class DatabaseConfig( database // init database } } - - @Deprecated( - "Deprecated due to the replacement by lateinit database field with the same functionality", - ReplaceWith("database") - ) - fun connect(): Database { - return database - } } diff --git a/build.gradle b/build.gradle index 716147d..26dd3c8 100644 --- a/build.gradle +++ b/build.gradle @@ -9,30 +9,11 @@ buildscript { } } -plugins { - id 'org.jetbrains.kotlin.jvm' version "$kotlin_version" - id "org.jetbrains.kotlin.plugin.serialization" version "$kotlin_version" - id 'application' -} - -project.group="dev.inmo" -project.version="$version" - -repositories { - jcenter() - mavenCentral() -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version" - - implementation "dev.inmo:tgbotapi:$tgbotapi_version" - implementation "dev.inmo:micro_utils.repos.exposed:$microutils_version" - api "org.xerial:sqlite-jdbc:$sqlite_version" -} - -application { - mainClassName = 'dev.inmo.plagubot.AppKt' +allprojects { + repositories { + jcenter() + mavenCentral() + mavenLocal() + maven { url 'https://jitpack.io' } + } } diff --git a/gradle.properties b/gradle.properties index 9e50bb8..7a03964 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,8 +7,11 @@ kotlin.incremental=true kotlin_version=1.4.10 kotlin_coroutines_version=1.4.1 kotlin_serialisation_runtime_version=1.0.1 +kotlin_exposed_version=0.28.1 tgbotapi_version=0.30.3 microutils_version=0.3.2 +klassindex_version=4.1.0-rc.1 sqlite_version=3.30.1 +group=dev.inmo version=0.0.1 diff --git a/plugin/build.gradle b/plugin/build.gradle new file mode 100644 index 0000000..ea3d933 --- /dev/null +++ b/plugin/build.gradle @@ -0,0 +1,15 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' + id "org.jetbrains.kotlin.plugin.serialization" +} + +project.group="$group" +project.version="$version" + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version" + + implementation "dev.inmo:tgbotapi:$tgbotapi_version" + implementation "dev.inmo:micro_utils.repos.exposed:$microutils_version" +} diff --git a/src/main/kotlin/dev/inmo/plagubot/Plugin.kt b/plugin/src/main/kotlin/dev/inmo/plagubot/Plugin.kt similarity index 100% rename from src/main/kotlin/dev/inmo/plagubot/Plugin.kt rename to plugin/src/main/kotlin/dev/inmo/plagubot/Plugin.kt diff --git a/settings.gradle b/settings.gradle index 6ad5a36..69cf6d4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,3 @@ +include ":bot", ":plugin" + rootProject.name = 'plagubot' diff --git a/src/main/kotlin/dev/inmo/plagubot/Config.kt b/src/main/kotlin/dev/inmo/plagubot/Config.kt deleted file mode 100644 index a0e1a0e..0000000 --- a/src/main/kotlin/dev/inmo/plagubot/Config.kt +++ /dev/null @@ -1,19 +0,0 @@ -package dev.inmo.plagubot - -import dev.inmo.plagubot.config.DatabaseConfig -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.serialization.* -import kotlinx.serialization.json.Json - -val configSerialFormat: StringFormat - get() = Json { - ignoreUnknownKeys = true - } - -@Serializable -data class Config( - val plugins: List<@Contextual Plugin>, - val database: DatabaseConfig, - val botToken: String -) diff --git a/template.config.json b/template.config.json new file mode 100644 index 0000000..d360991 --- /dev/null +++ b/template.config.json @@ -0,0 +1,16 @@ +{ + "database": { + "url": "jdbc:sqlite:file:test?mode=memory&cache=shared IT IS JUST EXAMPLE", + "driver": "org.sqlite.JDBC", + "username": "OPTIONAL username", + "password": "OPTIONAL password", + "initAutomatically": false + }, + "botToken": "1234567890:ABCDEFGHIJKLMNOP_qrstuvwxyz12345678", + "plugins": [ + { + "type": "Hello", + "parameter": "Example" + } + ] +} \ No newline at end of file