start of implementation

This commit is contained in:
2022-09-07 00:52:45 +06:00
parent 8fe93e20bc
commit 4a6e7e472b
7 changed files with 106 additions and 4 deletions

View File

@@ -1,13 +1,18 @@
package telegram_bot
import dev.inmo.micro_utils.repos.cache.cache.FullKVCache
import dev.inmo.micro_utils.repos.cache.cached
import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo
import dev.inmo.micro_utils.repos.mappers.withMapper
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.types.ChatId
import java.io.File
import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex
import kotlinx.serialization.json.Json
import models.Config
/**
* This method by default expects one argument in [args] field: telegram bot configuration
@@ -23,6 +28,22 @@ suspend fun main(args: Array<String>) {
// that is kotlin coroutine scope which will be used in requests and parallel works under the hood
val scope = CoroutineScope(Dispatchers.Default)
val repo = ExposedKeyValueRepo(
config.database.database,
{ long("chat_id") },
{ text("config") },
"configs"
).withMapper(
{ chatId },
{ json.encodeToString(ChatConfig.serializer(), this) },
{ ChatId(this) },
{ json.decodeFromString(ChatConfig.serializer(), this) },
).cached(FullKVCache(), scope = scope)
val chatsChangingMutex = Mutex()
val chatsSendingJobs = mutableMapOf<ChatId, Job>()
// here should be main logic of your bot
bot.buildBehaviourWithLongPolling(scope) {
// in this lambda you will be able to call methods without "bot." prefix

View File

@@ -0,0 +1,11 @@
import dev.inmo.krontab.*
import kotlinx.serialization.Serializable
@Serializable
data class ChatConfig(
val krontab: KrontabTemplate
) {
val scheduler by lazy {
krontab.toSchedule()
}
}

View File

@@ -1,8 +1,9 @@
package telegram_bot
package models
import kotlinx.serialization.Serializable
@Serializable
data class Config(
val token: String
val token: String,
val database: DatabaseConfig
)

View File

@@ -0,0 +1,9 @@
package models
import kotlinx.serialization.Serializable
@Serializable
data class DBConnectOptions(
val attempts: Int = 3,
val delay: Long = 1000L
)

View File

@@ -0,0 +1,37 @@
package models
import dev.inmo.kslog.common.e
import dev.inmo.kslog.common.logger
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.transactions.transactionManager
import org.postgresql.Driver
import java.sql.Connection
@Serializable
data class DatabaseConfig(
val url: String = "jdbc:pgsql://localhost:12346/test",
val driver: String = Driver::class.qualifiedName!!,
val username: String = "",
val password: String = "",
val reconnectOptions: DBConnectOptions? = DBConnectOptions()
) {
@Transient
val database: Database = (0 until (reconnectOptions ?.attempts ?: 1)).firstNotNullOfOrNull {
runCatching {
Database.connect(
url,
driver,
username,
password
).also {
it.transactionManager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE // Or Connection.TRANSACTION_READ_UNCOMMITTED
it.connector().close()
}
}.onFailure {
logger.e(it)
Thread.sleep(reconnectOptions ?.delay ?: return@onFailure)
}.getOrNull()
} ?: error("Unable to create database")
}