From cea8ba47db6f047d2a6e4a8c69898e0d49179ff8 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 10 Sep 2022 18:54:25 +0600 Subject: [PATCH] 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 +)