first version

This commit is contained in:
InsanusMokrassar 2020-11-11 23:05:21 +06:00
parent 3f46ed032c
commit 9b46894d99
6 changed files with 113 additions and 9 deletions

View File

@ -29,6 +29,8 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version"
implementation "dev.inmo:tgbotapi:$tgbotapi_version" implementation "dev.inmo:tgbotapi:$tgbotapi_version"
implementation "dev.inmo:micro_utils.repos.exposed:$microutils_version"
api "org.xerial:sqlite-jdbc:$sqlite_version"
} }
application { application {

View File

@ -7,6 +7,8 @@ kotlin.incremental=true
kotlin_version=1.4.10 kotlin_version=1.4.10
kotlin_coroutines_version=1.4.1 kotlin_coroutines_version=1.4.1
kotlin_serialisation_runtime_version=1.0.1 kotlin_serialisation_runtime_version=1.0.1
tgbotapi_version=0.30.0 tgbotapi_version=0.30.3
microutils_version=0.3.2
sqlite_version=3.30.1
version=0.0.1 version=0.0.1

View File

@ -1,13 +1,41 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import dev.inmo.tgbotapi.extensions.api.bot.getMe import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.telegramBot 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 java.io.File
/** /**
* This method by default expects one argument in [args] field: telegram bot token * This method by default expects one argument in [args] field: path to config
*/ */
suspend fun main(args: Array<String>) { suspend fun main(args: Array<String>) {
val bot = telegramBot(args.first()) val (configPath) = args
val file = File(configPath)
val config = configSerialFormat.decodeFromString(Config.serializer(), file.readText())
val scope = CoroutineScope(Dispatchers.Default)
val bot = telegramBot(config.botToken)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
val commands = config.plugins.flatMap {
it.invoke(bot, config.database.database, this, scope)
it.getCommands()
}.let {
val futureUnavailable = it.drop(botCommandsLimit.last)
if (futureUnavailable.isNotEmpty()) {
println("Next commands are out of range in setting command request and will be unavailable from autocompleting: ${futureUnavailable}")
}
it.take(botCommandsLimit.last)
}
scope.launch {
safelyWithoutExceptions {
bot.setMyCommands(commands)
}
}
}
println(bot.getMe())
} }

View File

@ -1,9 +1,19 @@
package dev.inmo.plagubot package dev.inmo.plagubot
import kotlinx.serialization.Contextual import dev.inmo.plagubot.config.DatabaseConfig
import kotlinx.serialization.Serializable import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.*
import kotlinx.serialization.json.Json
val configSerialFormat: StringFormat
get() = Json {
ignoreUnknownKeys = true
}
@Serializable @Serializable
data class Config( data class Config(
val plugins: List<@Contextual Plugin> val plugins: List<@Contextual Plugin>,
val database: DatabaseConfig,
val botToken: String
) )

View File

@ -1,3 +1,17 @@
package dev.inmo.plagubot package dev.inmo.plagubot
interface Plugin import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import kotlinx.coroutines.CoroutineScope
import org.jetbrains.exposed.sql.Database
interface Plugin {
suspend fun getCommands(): List<BotCommand> = emptyList()
suspend operator fun invoke(
bot: TelegramBot,
database: Database,
updatesFilter: FlowsUpdatesFilter,
scope: CoroutineScope
)
}

View File

@ -0,0 +1,48 @@
package dev.inmo.plagubot.config
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.transactions.transactionManager
import org.sqlite.JDBC
import java.sql.Connection
@Serializable
data class DatabaseConfig(
val url: String,
val driver: String = JDBC::class.qualifiedName!!,
val username: String = "",
val password: String = "",
val initAutomatically: Boolean = true
) {
@Transient
private lateinit var _database: Database
val database: Database
get() = try {
_database
} catch (e: UninitializedPropertyAccessException) {
Database.connect(
url,
driver,
username,
password
).also {
_database = it
it.transactionManager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE // Or Connection.TRANSACTION_READ_UNCOMMITTED
}
}
init {
if (initAutomatically) {
database // init database
}
}
@Deprecated(
"Deprecated due to the replacement by lateinit database field with the same functionality",
ReplaceWith("database")
)
fun connect(): Database {
return database
}
}