From 18fc3fd1dd4afd3627a5512a00472f6d276db234 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 9 Sep 2022 18:55:26 +0600 Subject: [PATCH 1/7] update dependencies and add opportunity to listen for admins in chats --- .../cache/admins/AdminsChangesListener.kt | 24 +++++++++++++++++++ .../cache/admins/DefaultAdminsCacheAPI.kt | 10 -------- .../cache/admins/TriggerAdminsUpdate.kt | 21 ++++++++++++++++ gradle.properties | 10 ++++---- 4 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt create mode 100644 cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/TriggerAdminsUpdate.kt diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt new file mode 100644 index 0000000..036a757 --- /dev/null +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt @@ -0,0 +1,24 @@ +package dev.inmo.tgbotapi.libraries.cache.admins + +import dev.inmo.tgbotapi.extensions.api.bot.getMe +import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMemberUpdated +import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember + +suspend fun BehaviourContext.activateAdminsChangesListening( + repo: DefaultAdminsCacheAPIRepo +) { + val me = getMe() + onChatMemberUpdated { + when { + it.oldChatMemberState is AdministratorChatMember && it.newChatMemberState !is AdministratorChatMember || + it.newChatMemberState is AdministratorChatMember && it.oldChatMemberState !is AdministratorChatMember -> { + updateAdmins( + it.chat.id, + repo, + me + ) + } + } + } +} diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt index 75c6ae0..89dd586 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt @@ -29,15 +29,6 @@ class DefaultAdminsCacheAPI( bot.getMe().also { botInfo = it } } - private suspend fun triggerUpdate(chatId: ChatId): List { - val botInfo = getBotInfo() - val admins = bot.getChatAdministrators(chatId).filter { - botInfo.id != it.user.id - } - repo.setChatAdmins(chatId, admins) - return admins - } - override suspend fun getChatAdmins(chatId: ChatId): List? { val settings = settingsAPI.getChatSettings(chatId) val lastUpdate = repo.lastUpdate(chatId) @@ -63,5 +54,4 @@ class DefaultAdminsCacheAPI( } override suspend fun settings(): AdminsCacheSettingsAPI = settingsAPI - } diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/TriggerAdminsUpdate.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/TriggerAdminsUpdate.kt new file mode 100644 index 0000000..c241bab --- /dev/null +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/TriggerAdminsUpdate.kt @@ -0,0 +1,21 @@ +package dev.inmo.tgbotapi.libraries.cache.admins + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.api.bot.getMe +import dev.inmo.tgbotapi.extensions.api.chat.get.getChatAdministrators +import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.types.chat.ExtendedBot +import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember + +internal suspend fun TelegramBot.updateAdmins( + chatId: ChatId, + repo: DefaultAdminsCacheAPIRepo, + botInfo: ExtendedBot? = null +): List { + val botInfo = botInfo ?: getMe() + val admins = getChatAdministrators(chatId).filter { + botInfo.id != it.user.id + } + repo.setChatAdmins(chatId, admins) + return admins +} diff --git a/gradle.properties b/gradle.properties index 330ac00..be1ce12 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,10 +11,10 @@ kotlin_serialisation_core_version=1.4.0 github_release_plugin_version=2.4.1 -tgbotapi_version=3.2.0 -micro_utils_version=0.12.5 +tgbotapi_version=3.2.1 +micro_utils_version=0.12.11 exposed_version=0.39.2 -plagubot_version=2.2.0 +plagubot_version=2.3.1 # ANDROID @@ -33,5 +33,5 @@ dokka_version=1.7.10 # Project data group=dev.inmo -version=0.5.2 -android_code_version=29 +version=0.5.3 +android_code_version=30 From bb7fb985e31c965b7d8b1e9c82af4f58d168cec7 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 9 Sep 2022 18:57:19 +0600 Subject: [PATCH 2/7] update arguments in activateAdminsChangesListening --- .../cache/admins/AdminsChangesListener.kt | 14 +++++++++++--- .../cache/admins/DefaultAdminsCacheAPI.kt | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt index 036a757..36fb9d4 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt @@ -1,15 +1,23 @@ package dev.inmo.tgbotapi.libraries.cache.admins import dev.inmo.tgbotapi.extensions.api.bot.getMe -import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext +import dev.inmo.tgbotapi.extensions.behaviour_builder.* +import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.ChatMemberUpdatedFilterByChat import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMemberUpdated +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatChatMemberUpdatedMarkerFactory +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember +import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated +import dev.inmo.tgbotapi.types.update.abstracts.Update suspend fun BehaviourContext.activateAdminsChangesListening( - repo: DefaultAdminsCacheAPIRepo + repo: DefaultAdminsCacheAPIRepo, + initialFilter: SimpleFilter? = null, + markerFactory: MarkerFactory = ByChatChatMemberUpdatedMarkerFactory ) { val me = getMe() - onChatMemberUpdated { + onChatMemberUpdated(initialFilter, markerFactory = markerFactory) { when { it.oldChatMemberState is AdministratorChatMember && it.newChatMemberState !is AdministratorChatMember || it.newChatMemberState is AdministratorChatMember && it.oldChatMemberState !is AdministratorChatMember -> { diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt index 89dd586..7374290 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt @@ -36,9 +36,9 @@ class DefaultAdminsCacheAPI( settings == null -> null settings.refreshOnRequests && (lastUpdate == null || (DateTime.now() - lastUpdate).seconds > settings.refreshSeconds) -> { - triggerUpdate(chatId) + bot.updateAdmins(chatId, repo, getBotInfo()) } - else -> repo.getChatAdmins(chatId) ?: triggerUpdate(chatId) + else -> repo.getChatAdmins(chatId) ?: bot.updateAdmins(chatId, repo, getBotInfo()) } } From 53630d4864aa29bd30da08183ccf099e5527a47e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 9 Sep 2022 19:16:19 +0600 Subject: [PATCH 3/7] rework of plagubot part of admins plugin --- .../micro_utils/DefaultAdminsCacheAPI.kt | 8 ++- .../libraries/cache/admins/AdminsCacheAPI.kt | 16 ++--- .../libraries/cache/admins/AdminsPlugin.kt | 69 ++++++++++++++++--- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt b/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt index 0027b85..bfb6249 100644 --- a/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt +++ b/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt @@ -28,7 +28,7 @@ private class SetChatAdminsRepoAction( override val toReturn: Continuation ) : RepoActions() -class DefaultAdminsCacheAPIRepo( +class DefaultAdminsCacheAPIRepoImpl( private val adminsRepo: KeyValuesRepo, private val updatesRepo: KeyValueRepo, private val scope: CoroutineScope @@ -60,3 +60,9 @@ class DefaultAdminsCacheAPIRepo( actor.trySend(GetUpdateDateTimeRepoAction(chatId, it)) } } + +fun DefaultAdminsCacheAPIRepo( + adminsRepo: KeyValuesRepo, + updatesRepo: KeyValueRepo, + scope: CoroutineScope +) = DefaultAdminsCacheAPIRepoImpl(adminsRepo, updatesRepo, scope) diff --git a/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt b/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt index 5a57304..c7609a2 100644 --- a/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt +++ b/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt @@ -5,20 +5,18 @@ import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo import dev.inmo.micro_utils.repos.mappers.withMapper import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext -import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DefaultAdminsCacheAPIRepo +import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DefaultAdminsCacheAPIRepoImpl import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DynamicAdminsCacheSettingsAPI import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.chat.member.* import kotlinx.coroutines.CoroutineScope import kotlinx.serialization.* -import kotlinx.serialization.cbor.Cbor import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.statements.api.ExposedBlob -private val serializationFormat = Json { +val telegramAdminsSerializationFormat = Json { ignoreUnknownKeys = true serializersModule = SerializersModule { polymorphic(AdministratorChatMember::class) { @@ -35,7 +33,7 @@ fun AdminsCacheAPI( scope: CoroutineScope ) : AdminsCacheAPI = DefaultAdminsCacheAPI( bot, - DefaultAdminsCacheAPIRepo( + DefaultAdminsCacheAPIRepoImpl( ExposedKeyValuesRepo( database, { long("chatId") }, @@ -43,9 +41,9 @@ fun AdminsCacheAPI( "AdminsTable" ).withMapper( keyFromToTo = { chatId }, - valueFromToTo = { serializationFormat.encodeToString(this) }, + valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, keyToToFrom = { toChatId() }, - valueToToFrom = { serializationFormat.decodeFromString(this) } + valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } ), ExposedKeyValueRepo( database, @@ -68,9 +66,9 @@ fun AdminsCacheAPI( "DynamicAdminsCacheSettingsAPI" ).withMapper( keyFromToTo = { chatId }, - valueFromToTo = { serializationFormat.encodeToString(this) }, + valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, keyToToFrom = { toChatId() }, - valueToToFrom = { serializationFormat.decodeFromString(this) } + valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } ), scope ) diff --git a/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt b/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt index a53a14a..1527c76 100644 --- a/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt +++ b/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt @@ -1,17 +1,24 @@ package dev.inmo.tgbotapi.libraries.cache.admins +import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo +import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo +import dev.inmo.micro_utils.repos.mappers.withMapper import dev.inmo.plagubot.Plugin import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext -import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DefaultAdminsCacheAPIRepoImpl +import dev.inmo.tgbotapi.libraries.cache.admins.micro_utils.DynamicAdminsCacheSettingsAPI +import dev.inmo.tgbotapi.types.* +import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember +import kotlinx.coroutines.* import kotlinx.coroutines.flow.* import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient +import kotlinx.serialization.* import kotlinx.serialization.json.JsonObject import org.jetbrains.exposed.sql.Database import org.koin.core.Koin import org.koin.core.module.Module +import org.koin.core.qualifier.named import org.koin.core.scope.Scope val Scope.adminsPlugin: AdminsPlugin? @@ -28,6 +35,7 @@ class AdminsPlugin : Plugin { private val databaseToAdminsCacheAPI = mutableMapOf>() private val mutex = Mutex() + @Deprecated("Will be removed soon due to its redundancy") suspend fun adminsAPI(database: Database): AdminsCacheAPI { val flow = mutex.withLock { databaseToAdminsCacheAPI.getOrPut(database){ MutableStateFlow(null) } @@ -37,16 +45,59 @@ class AdminsPlugin : Plugin { override fun Module.setupDI(database: Database, params: JsonObject) { single { this@AdminsPlugin } + val scopeQualifier = named("admins plugin scope") + single(scopeQualifier) { CoroutineScope(Dispatchers.IO + SupervisorJob()) } + single { + DefaultAdminsCacheAPIRepoImpl( + ExposedKeyValuesRepo( + database, + { long("chatId") }, + { text("member") }, + "AdminsTable" + ).withMapper( + keyFromToTo = { chatId }, + valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, + keyToToFrom = { toChatId() }, + valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } + ), + ExposedKeyValueRepo( + database, + { long("chatId") }, + { long("datetime") }, + "AdminsUpdatesTimesTable" + ).withMapper( + keyFromToTo = { chatId }, + valueFromToTo = { this }, + keyToToFrom = { toChatId() }, + valueToToFrom = { this } + ), + get(scopeQualifier) + ) + } + single { + DynamicAdminsCacheSettingsAPI( + ExposedKeyValueRepo( + database, + { long("chatId") }, + { text("settings") }, + "DynamicAdminsCacheSettingsAPI" + ).withMapper( + keyFromToTo = { chatId }, + valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, + keyToToFrom = { toChatId() }, + valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } + ), + get(scopeQualifier) + ) + } + single { DefaultAdminsCacheAPI(get(), get(), get()) } } override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { with(koin) { - mutex.withLock { - val flow = databaseToAdminsCacheAPI.getOrPut(koin.get()){ MutableStateFlow(null) } - if (flow.value == null) { - flow.value = AdminsCacheAPI(koin.get()) - } - } + activateAdminsChangesListening( + get() + ) } } } From 1c87f64a6df40a38f892e29388f927b77cfa911e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 9 Sep 2022 19:32:21 +0600 Subject: [PATCH 4/7] fix --- .../dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt b/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt index 1527c76..c9d5aed 100644 --- a/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt +++ b/cache/admins/plagubot/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsPlugin.kt @@ -20,6 +20,7 @@ import org.koin.core.Koin import org.koin.core.module.Module import org.koin.core.qualifier.named import org.koin.core.scope.Scope +import org.koin.dsl.binds val Scope.adminsPlugin: AdminsPlugin? get() = getOrNull() @@ -90,7 +91,9 @@ class AdminsPlugin : Plugin { get(scopeQualifier) ) } - single { DefaultAdminsCacheAPI(get(), get(), get()) } + single { DefaultAdminsCacheAPI(get(), get(), get()) } binds arrayOf( + AdminsCacheAPI::class + ) } override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) { From b2719c076017c9914d73ca849147c958eec3a9a0 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 9 Sep 2022 20:20:39 +0600 Subject: [PATCH 5/7] AdminsCacheAPI with defaults and customizing opportunity --- .../libraries/cache/admins/AdminsCacheAPI.kt | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt b/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt index c7609a2..9803ada 100644 --- a/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt +++ b/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt @@ -1,5 +1,7 @@ package dev.inmo.tgbotapi.libraries.cache.admins +import dev.inmo.micro_utils.repos.KeyValueRepo +import dev.inmo.micro_utils.repos.KeyValuesRepo import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo import dev.inmo.micro_utils.repos.mappers.withMapper @@ -75,3 +77,47 @@ fun AdminsCacheAPI( ) fun BehaviourContext.AdminsCacheAPI(database: Database) = AdminsCacheAPI(this, database, this) + +fun BehaviourContext.AdminsCacheAPI( + database: Database, + scope: CoroutineScope, + defaultAdminsCacheAPIRepo: DefaultAdminsCacheAPIRepo = DefaultAdminsCacheAPIRepoImpl( + ExposedKeyValuesRepo( + database, + { long("chatId") }, + { text("member") }, + "AdminsTable" + ).withMapper( + keyFromToTo = { chatId }, + valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, + keyToToFrom = { toChatId() }, + valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } + ), + ExposedKeyValueRepo( + database, + { long("chatId") }, + { long("datetime") }, + "AdminsUpdatesTimesTable" + ).withMapper( + keyFromToTo = { chatId }, + valueFromToTo = { this }, + keyToToFrom = { toChatId() }, + valueToToFrom = { this } + ), + scope + ), + adminsCacheSettingsAPI: AdminsCacheSettingsAPI = DynamicAdminsCacheSettingsAPI( + ExposedKeyValueRepo( + database, + { long("chatId") }, + { text("settings") }, + "DynamicAdminsCacheSettingsAPI" + ).withMapper( + keyFromToTo = { chatId }, + valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, + keyToToFrom = { toChatId() }, + valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } + ), + scope + ) +) = DefaultAdminsCacheAPI(this, defaultAdminsCacheAPIRepo, adminsCacheSettingsAPI) From cea8ba47db6f047d2a6e4a8c69898e0d49179ff8 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 10 Sep 2022 18:54:25 +0600 Subject: [PATCH 6/7] fixes and improvements --- .../cache/admins/AdminsCacheSettingsAPI.kt | 5 +- .../cache/admins/AdminsChangesListener.kt | 16 ++++- .../cache/admins/AdminsSimpleFilter.kt | 37 +++++++++++ .../cache/admins/DefaultAdminsCacheAPI.kt | 22 ++++++- .../cache/admins/MessageSenderVerification.kt | 29 ++++++++- .../micro_utils/DefaultAdminsCacheAPI.kt | 4 ++ .../libraries/cache/admins/AdminsCacheAPI.kt | 62 ++++--------------- 7 files changed, 116 insertions(+), 59 deletions(-) create mode 100644 cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsSimpleFilter.kt diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheSettingsAPI.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheSettingsAPI.kt index e960565..5bd1cad 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheSettingsAPI.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheSettingsAPI.kt @@ -15,8 +15,11 @@ data class AdminsCacheSettings( */ val disableRequestsRefreshMode: Boolean = false ) { - val refreshOnRequests: Boolean + val refreshOnCacheCalls: Boolean get() = !disableRequestsRefreshMode + @Deprecated("Renamed", ReplaceWith("refreshOnCacheCalls")) + val refreshOnRequests: Boolean + get() = refreshOnCacheCalls } interface AdminsCacheSettingsAPI { diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt index 36fb9d4..1688df0 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsChangesListener.kt @@ -7,17 +7,19 @@ import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onChatMe import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.ByChatChatMemberUpdatedMarkerFactory import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.marker_factories.MarkerFactory +import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember import dev.inmo.tgbotapi.types.chat.member.ChatMemberUpdated import dev.inmo.tgbotapi.types.update.abstracts.Update +import kotlinx.coroutines.Job suspend fun BehaviourContext.activateAdminsChangesListening( repo: DefaultAdminsCacheAPIRepo, initialFilter: SimpleFilter? = null, markerFactory: MarkerFactory = ByChatChatMemberUpdatedMarkerFactory -) { +): Job { val me = getMe() - onChatMemberUpdated(initialFilter, markerFactory = markerFactory) { + return onChatMemberUpdated(initialFilter, markerFactory = markerFactory) { when { it.oldChatMemberState is AdministratorChatMember && it.newChatMemberState !is AdministratorChatMember || it.newChatMemberState is AdministratorChatMember && it.oldChatMemberState !is AdministratorChatMember -> { @@ -30,3 +32,13 @@ suspend fun BehaviourContext.activateAdminsChangesListening( } } } + +suspend fun BehaviourContext.activateAdminsChangesListening( + repo: DefaultAdminsCacheAPIRepo, + allowedChats: List +) = activateAdminsChangesListening( + repo, + { + it.chat.id in allowedChats + } +) diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsSimpleFilter.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsSimpleFilter.kt new file mode 100644 index 0000000..6fd5fe9 --- /dev/null +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsSimpleFilter.kt @@ -0,0 +1,37 @@ +package dev.inmo.tgbotapi.libraries.cache.admins + +import dev.inmo.tgbotapi.abstracts.FromUser +import dev.inmo.tgbotapi.extensions.behaviour_builder.utils.SimpleFilter +import dev.inmo.tgbotapi.types.ChatId +import dev.inmo.tgbotapi.types.UserId +import dev.inmo.tgbotapi.types.message.abstracts.Message + +fun AdminsChecker( + adminsCacheAPI: AdminsCacheAPI +): SimpleFilter> = SimpleFilter { + adminsCacheAPI.isAdmin(it.first, it.second) +} + +fun AdminsChecker( + adminsCacheAPI: AdminsCacheAPI, + mapper: (T) -> Pair +): SimpleFilter { + val baseChecker = AdminsChecker(adminsCacheAPI) + + return SimpleFilter { + baseChecker(mapper(it)) + } +} + +fun MessageAdminsChecker( + adminsCacheAPI: AdminsCacheAPI +) = SimpleFilter { + adminsCacheAPI.isAdmin(it) +} + +fun AdminsChecker( + adminsCacheAPI: AdminsCacheAPI, + chatId: ChatId +) = SimpleFilter { + adminsCacheAPI.isAdmin(chatId, it.from.id) +} diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt index 7374290..377f5f9 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/DefaultAdminsCacheAPI.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.libraries.cache.admins import com.soywiz.klock.DateTime import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.extensions.api.bot.getMe -import dev.inmo.tgbotapi.extensions.api.chat.get.getChatAdministrators +import dev.inmo.tgbotapi.extensions.api.chat.members.getChatMember import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.chat.ExtendedBot import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember @@ -34,7 +34,7 @@ class DefaultAdminsCacheAPI( val lastUpdate = repo.lastUpdate(chatId) return when { settings == null -> null - settings.refreshOnRequests && + settings.refreshOnCacheCalls && (lastUpdate == null || (DateTime.now() - lastUpdate).seconds > settings.refreshSeconds) -> { bot.updateAdmins(chatId, repo, getBotInfo()) } @@ -42,6 +42,24 @@ class DefaultAdminsCacheAPI( } } + override suspend fun isAdmin(chatId: ChatId, userId: UserId): Boolean { + val settings = settingsAPI.getChatSettings(chatId) + val lastUpdate = repo.lastUpdate(chatId) + return when { + settings == null -> return false + settings.refreshOnCacheCalls && (lastUpdate == null || (DateTime.now() - lastUpdate).seconds > settings.refreshSeconds) -> { + bot.updateAdmins(chatId, repo, getBotInfo()) + } + else -> { + val chatAdmins = repo.getChatAdmins(chatId) + if (chatAdmins == null) { + return bot.getChatMember(chatId, userId) is AdministratorChatMember + } + chatAdmins + } + }.any { it.user.id == userId } + } + override suspend fun sentByAdmin(groupContentMessage: GroupContentMessage<*>): Boolean { return when (groupContentMessage) { is AnonymousGroupContentMessage -> true diff --git a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/MessageSenderVerification.kt b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/MessageSenderVerification.kt index e784cdf..a5fe89a 100644 --- a/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/MessageSenderVerification.kt +++ b/cache/admins/common/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/MessageSenderVerification.kt @@ -4,17 +4,40 @@ import dev.inmo.tgbotapi.types.ChatId import dev.inmo.tgbotapi.types.UserId import dev.inmo.tgbotapi.types.message.abstracts.* -suspend fun AdminsCacheAPI.verifyMessageFromAdmin(message: ContentMessage<*>) = when (message) { +suspend inline fun AdminsCacheAPI.isAdmin(message: Message) = when (message) { is CommonGroupContentMessage<*> -> isAdmin(message.chat.id, message.user.id) is AnonymousGroupContentMessage<*> -> true else -> false } -suspend fun ContentMessage<*>.doAfterVerification(adminsCacheAPI: AdminsCacheAPI, block: suspend () -> R): R? { - val verified = adminsCacheAPI.verifyMessageFromAdmin(this) +suspend inline fun AdminsCacheAPI.verifyMessageFromAdmin(message: Message) = isAdmin(message) + +suspend inline fun AdminsCacheAPI.doIfAdmin( + chatId: ChatId, + userId: UserId, + block: () -> R +) = if(isAdmin(chatId, userId)) { + block() +} else { + null +} + +suspend inline fun AdminsCacheAPI.doIfAdmin( + message: Message, + block: () -> R +) = if(isAdmin(message)) { + block() +} else { + null +} + +suspend inline fun ContentMessage<*>.doIfAdmin(adminsCacheAPI: AdminsCacheAPI, block: () -> R): R? { + val verified = adminsCacheAPI.isAdmin(this) return if (verified) { block() } else { null } } + +suspend inline fun ContentMessage<*>.doAfterVerification(adminsCacheAPI: AdminsCacheAPI, block: () -> R) = doIfAdmin(adminsCacheAPI, block) diff --git a/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt b/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt index bfb6249..7f723f5 100644 --- a/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt +++ b/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt @@ -53,6 +53,10 @@ class DefaultAdminsCacheAPIRepoImpl( override suspend fun getChatAdmins(chatId: ChatId): List? = suspendCoroutine { actor.trySend(GetChatAdminsRepoAction(chatId, it)) } + + override suspend fun tryGetChatAdmins(chatId: ChatId): List? { + TODO("Not yet implemented") + } override suspend fun setChatAdmins(chatId: ChatId, chatMembers: List) = suspendCoroutine { actor.trySend(SetChatAdminsRepoAction(chatId, chatMembers, it)) } diff --git a/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt b/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt index 9803ada..dbde1f2 100644 --- a/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt +++ b/cache/admins/micro_utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/AdminsCacheAPI.kt @@ -1,7 +1,5 @@ package dev.inmo.tgbotapi.libraries.cache.admins -import dev.inmo.micro_utils.repos.KeyValueRepo -import dev.inmo.micro_utils.repos.KeyValuesRepo import dev.inmo.micro_utils.repos.exposed.keyvalue.ExposedKeyValueRepo import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo import dev.inmo.micro_utils.repos.mappers.withMapper @@ -29,56 +27,9 @@ val telegramAdminsSerializationFormat = Json { } } -fun AdminsCacheAPI( - bot: TelegramBot, - database: Database, - scope: CoroutineScope -) : AdminsCacheAPI = DefaultAdminsCacheAPI( - bot, - DefaultAdminsCacheAPIRepoImpl( - ExposedKeyValuesRepo( - database, - { long("chatId") }, - { text("member") }, - "AdminsTable" - ).withMapper( - keyFromToTo = { chatId }, - valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, - keyToToFrom = { toChatId() }, - valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } - ), - ExposedKeyValueRepo( - database, - { long("chatId") }, - { long("datetime") }, - "AdminsUpdatesTimesTable" - ).withMapper( - keyFromToTo = { chatId }, - valueFromToTo = { this }, - keyToToFrom = { toChatId() }, - valueToToFrom = { this } - ), - scope - ), - DynamicAdminsCacheSettingsAPI( - ExposedKeyValueRepo( - database, - { long("chatId") }, - { text("settings") }, - "DynamicAdminsCacheSettingsAPI" - ).withMapper( - keyFromToTo = { chatId }, - valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) }, - keyToToFrom = { toChatId() }, - valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) } - ), - scope - ) -) +fun BehaviourContext.createAdminsCacheAPI(database: Database) = AdminsCacheAPI(this, database, this) -fun BehaviourContext.AdminsCacheAPI(database: Database) = AdminsCacheAPI(this, database, this) - -fun BehaviourContext.AdminsCacheAPI( +fun TelegramBot.createAdminsCacheAPI( database: Database, scope: CoroutineScope, defaultAdminsCacheAPIRepo: DefaultAdminsCacheAPIRepo = DefaultAdminsCacheAPIRepoImpl( @@ -121,3 +72,12 @@ fun BehaviourContext.AdminsCacheAPI( scope ) ) = DefaultAdminsCacheAPI(this, defaultAdminsCacheAPIRepo, adminsCacheSettingsAPI) + +fun AdminsCacheAPI( + bot: TelegramBot, + database: Database, + scope: CoroutineScope +) : AdminsCacheAPI = bot.createAdminsCacheAPI( + database, + scope +) From c85d92c7baf6a632df9e91d173b44e90b1fc2e06 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 10 Sep 2022 19:04:48 +0600 Subject: [PATCH 7/7] remove tryGetChatAdmins --- .../cache/admins/micro_utils/DefaultAdminsCacheAPI.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt b/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt index 7f723f5..2c51f1d 100644 --- a/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt +++ b/cache/admins/micro_utils/src/commonMain/kotlin/dev/inmo/tgbotapi/libraries/cache/admins/micro_utils/DefaultAdminsCacheAPI.kt @@ -54,9 +54,6 @@ class DefaultAdminsCacheAPIRepoImpl( actor.trySend(GetChatAdminsRepoAction(chatId, it)) } - override suspend fun tryGetChatAdmins(chatId: ChatId): List? { - TODO("Not yet implemented") - } override suspend fun setChatAdmins(chatId: ChatId, chatMembers: List) = suspendCoroutine { actor.trySend(SetChatAdminsRepoAction(chatId, chatMembers, it)) }