add inlines plugin

This commit is contained in:
2022-09-09 19:40:46 +06:00
parent 4c9b6e485f
commit bf68fc58f4
16 changed files with 193 additions and 21 deletions

22
inlines/build.gradle Normal file
View File

@@ -0,0 +1,22 @@
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
id "com.android.library"
}
apply from: "$mppProjectWithSerializationPresetPath"
kotlin {
sourceSets {
commonMain {
dependencies {
api project(":plaguposter.common")
api libs.tgbotapi.admins
}
}
jvmMain {
dependencies {
}
}
}
}

View File

@@ -0,0 +1 @@
package dev.inmo.plaguposter.inlines

View File

@@ -0,0 +1,67 @@
package dev.inmo.plaguposter.inlines
import dev.inmo.micro_utils.pagination.Pagination
import dev.inmo.micro_utils.pagination.utils.paginate
import dev.inmo.plagubot.Plugin
import dev.inmo.plaguposter.common.ChatConfig
import dev.inmo.plaguposter.inlines.models.OfferTemplate
import dev.inmo.plaguposter.inlines.repos.InlineTemplatesRepo
import dev.inmo.tgbotapi.bot.exceptions.RequestException
import dev.inmo.tgbotapi.extensions.api.answers.answerInlineQuery
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onBaseInlineQuery
import dev.inmo.tgbotapi.libraries.cache.admins.AdminsCacheAPI
import dev.inmo.tgbotapi.libraries.cache.admins.adminsPlugin
import dev.inmo.tgbotapi.types.inlineQueryAnswerResultsLimit
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.*
import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.module.Module
object Plugin : Plugin {
@Serializable
internal data class Config(
val preset: List<OfferTemplate>
)
override fun Module.setupDI(database: Database, params: JsonObject) {
single { get<Json>().decodeFromJsonElement(Config.serializer(), params["inlines"] ?: return@single Config(emptyList())) }
single { InlineTemplatesRepo(getOrNull<Config>() ?.preset ?.toMutableSet() ?: mutableSetOf()) }
}
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
val adminsApi = koin.get<AdminsCacheAPI>()
val chatConfig = koin.get<ChatConfig>()
val templatesRepo = koin.get<InlineTemplatesRepo>()
onBaseInlineQuery { query ->
if (!adminsApi.isAdmin(chatConfig.sourceChatId, query.from.id)) {
answerInlineQuery(query, cachedTime = 0)
return@onBaseInlineQuery
}
val page = query.offset.toIntOrNull() ?: 0
try {
answerInlineQuery(
query,
templatesRepo.templates.paginate(
Pagination(
page,
inlineQueryAnswerResultsLimit.last + 1
)
).results.mapIndexedNotNull { index, offerTemplate ->
offerTemplate.createArticleResult(
index.toString(),
query.query
)
},
nextOffset = (page + 1).toString(),
cachedTime = 0
)
} catch (e: RequestException) {
bot.answerInlineQuery(
query,
cachedTime = 0
)
}
}
}
}

View File

@@ -0,0 +1,40 @@
package dev.inmo.plaguposter.inlines.models
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
import dev.inmo.tgbotapi.types.message.MarkdownV2
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
@Serializable
data class Format(
val template: String,
val regexTemplate: String = "^$",
val splitBy: String? = null,
val enableMarkdownSupport: Boolean = false
) {
@Transient
val queryRegex = Regex(regexTemplate, RegexOption.DOT_MATCHES_ALL)
init {
println(queryRegex)
}
fun formatByRegex(with: String): String? {
return if (queryRegex.matches(with)) {
template.format(*(splitBy ?.let { with.split(it).toTypedArray() } ?: arrayOf(with)))
} else {
null
}
}
fun createContent(with: String): InputTextMessageContent? {
return if (queryRegex.matches(with)) {
InputTextMessageContent(
template.format(*(splitBy ?.let { with.split(it).toTypedArray() } ?: arrayOf(with))),
if (enableMarkdownSupport) MarkdownV2 else null
)
} else {
null
}
}
}

View File

@@ -0,0 +1,22 @@
package dev.inmo.plaguposter.inlines.models
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
import kotlinx.serialization.Serializable
@Serializable
data class OfferTemplate(
val title: String,
val formats: List<Format> = emptyList(),
val description: String? = null
) {
fun createArticleResult(id: String, query: String): InlineQueryResultArticle? = formats.firstOrNull {
it.queryRegex.matches(query)
} ?.createContent(query) ?.let { content ->
InlineQueryResultArticle(
id,
title,
content,
description = description
)
}
}

View File

@@ -0,0 +1,16 @@
package dev.inmo.plaguposter.inlines.repos
import dev.inmo.plaguposter.inlines.models.OfferTemplate
class InlineTemplatesRepo(
private val _templates: MutableSet<OfferTemplate>
) {
internal val templates
get() = _templates.toList()
suspend fun addTemplate(offerTemplate: OfferTemplate): Boolean {
return _templates.add(offerTemplate)
}
suspend fun dropTemplate(offerTemplate: OfferTemplate): Boolean {
return _templates.remove(offerTemplate)
}
}

View File

@@ -0,0 +1 @@
<manifest package="dev.inmo.plaguposter.inlines"/>