mirror of
https://github.com/InsanusMokrassar/TelegramBotApiLibraries.git
synced 2024-12-22 16:47:16 +00:00
commit
ab802df7d1
@ -15,8 +15,11 @@ data class AdminsCacheSettings(
|
|||||||
*/
|
*/
|
||||||
val disableRequestsRefreshMode: Boolean = false
|
val disableRequestsRefreshMode: Boolean = false
|
||||||
) {
|
) {
|
||||||
val refreshOnRequests: Boolean
|
val refreshOnCacheCalls: Boolean
|
||||||
get() = !disableRequestsRefreshMode
|
get() = !disableRequestsRefreshMode
|
||||||
|
@Deprecated("Renamed", ReplaceWith("refreshOnCacheCalls"))
|
||||||
|
val refreshOnRequests: Boolean
|
||||||
|
get() = refreshOnCacheCalls
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AdminsCacheSettingsAPI {
|
interface AdminsCacheSettingsAPI {
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package dev.inmo.tgbotapi.libraries.cache.admins
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
||||||
|
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.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<ChatMemberUpdated>? = null,
|
||||||
|
markerFactory: MarkerFactory<ChatMemberUpdated, Any> = ByChatChatMemberUpdatedMarkerFactory
|
||||||
|
): Job {
|
||||||
|
val me = getMe()
|
||||||
|
return onChatMemberUpdated(initialFilter, markerFactory = markerFactory) {
|
||||||
|
when {
|
||||||
|
it.oldChatMemberState is AdministratorChatMember && it.newChatMemberState !is AdministratorChatMember ||
|
||||||
|
it.newChatMemberState is AdministratorChatMember && it.oldChatMemberState !is AdministratorChatMember -> {
|
||||||
|
updateAdmins(
|
||||||
|
it.chat.id,
|
||||||
|
repo,
|
||||||
|
me
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun BehaviourContext.activateAdminsChangesListening(
|
||||||
|
repo: DefaultAdminsCacheAPIRepo,
|
||||||
|
allowedChats: List<ChatId>
|
||||||
|
) = activateAdminsChangesListening(
|
||||||
|
repo,
|
||||||
|
{
|
||||||
|
it.chat.id in allowedChats
|
||||||
|
}
|
||||||
|
)
|
@ -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<Pair<ChatId, UserId>> = SimpleFilter {
|
||||||
|
adminsCacheAPI.isAdmin(it.first, it.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> AdminsChecker(
|
||||||
|
adminsCacheAPI: AdminsCacheAPI,
|
||||||
|
mapper: (T) -> Pair<ChatId, UserId>
|
||||||
|
): SimpleFilter<T> {
|
||||||
|
val baseChecker = AdminsChecker(adminsCacheAPI)
|
||||||
|
|
||||||
|
return SimpleFilter<T> {
|
||||||
|
baseChecker(mapper(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MessageAdminsChecker(
|
||||||
|
adminsCacheAPI: AdminsCacheAPI
|
||||||
|
) = SimpleFilter<Message> {
|
||||||
|
adminsCacheAPI.isAdmin(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AdminsChecker(
|
||||||
|
adminsCacheAPI: AdminsCacheAPI,
|
||||||
|
chatId: ChatId
|
||||||
|
) = SimpleFilter<FromUser> {
|
||||||
|
adminsCacheAPI.isAdmin(chatId, it.from.id)
|
||||||
|
}
|
@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.libraries.cache.admins
|
|||||||
import com.soywiz.klock.DateTime
|
import com.soywiz.klock.DateTime
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.api.bot.getMe
|
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.*
|
||||||
import dev.inmo.tgbotapi.types.chat.ExtendedBot
|
import dev.inmo.tgbotapi.types.chat.ExtendedBot
|
||||||
import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember
|
import dev.inmo.tgbotapi.types.chat.member.AdministratorChatMember
|
||||||
@ -29,28 +29,37 @@ class DefaultAdminsCacheAPI(
|
|||||||
bot.getMe().also { botInfo = it }
|
bot.getMe().also { botInfo = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun triggerUpdate(chatId: ChatId): List<AdministratorChatMember> {
|
|
||||||
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<AdministratorChatMember>? {
|
override suspend fun getChatAdmins(chatId: ChatId): List<AdministratorChatMember>? {
|
||||||
val settings = settingsAPI.getChatSettings(chatId)
|
val settings = settingsAPI.getChatSettings(chatId)
|
||||||
val lastUpdate = repo.lastUpdate(chatId)
|
val lastUpdate = repo.lastUpdate(chatId)
|
||||||
return when {
|
return when {
|
||||||
settings == null -> null
|
settings == null -> null
|
||||||
settings.refreshOnRequests &&
|
settings.refreshOnCacheCalls &&
|
||||||
(lastUpdate == null || (DateTime.now() - lastUpdate).seconds > settings.refreshSeconds) -> {
|
(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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
override suspend fun sentByAdmin(groupContentMessage: GroupContentMessage<*>): Boolean {
|
||||||
return when (groupContentMessage) {
|
return when (groupContentMessage) {
|
||||||
is AnonymousGroupContentMessage -> true
|
is AnonymousGroupContentMessage -> true
|
||||||
@ -63,5 +72,4 @@ class DefaultAdminsCacheAPI(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun settings(): AdminsCacheSettingsAPI = settingsAPI
|
override suspend fun settings(): AdminsCacheSettingsAPI = settingsAPI
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,40 @@ import dev.inmo.tgbotapi.types.ChatId
|
|||||||
import dev.inmo.tgbotapi.types.UserId
|
import dev.inmo.tgbotapi.types.UserId
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.*
|
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 CommonGroupContentMessage<*> -> isAdmin(message.chat.id, message.user.id)
|
||||||
is AnonymousGroupContentMessage<*> -> true
|
is AnonymousGroupContentMessage<*> -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun <R> ContentMessage<*>.doAfterVerification(adminsCacheAPI: AdminsCacheAPI, block: suspend () -> R): R? {
|
suspend inline fun AdminsCacheAPI.verifyMessageFromAdmin(message: Message) = isAdmin(message)
|
||||||
val verified = adminsCacheAPI.verifyMessageFromAdmin(this)
|
|
||||||
|
suspend inline fun <R : Any> AdminsCacheAPI.doIfAdmin(
|
||||||
|
chatId: ChatId,
|
||||||
|
userId: UserId,
|
||||||
|
block: () -> R
|
||||||
|
) = if(isAdmin(chatId, userId)) {
|
||||||
|
block()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend inline fun <R : Any> AdminsCacheAPI.doIfAdmin(
|
||||||
|
message: Message,
|
||||||
|
block: () -> R
|
||||||
|
) = if(isAdmin(message)) {
|
||||||
|
block()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend inline fun <R> ContentMessage<*>.doIfAdmin(adminsCacheAPI: AdminsCacheAPI, block: () -> R): R? {
|
||||||
|
val verified = adminsCacheAPI.isAdmin(this)
|
||||||
return if (verified) {
|
return if (verified) {
|
||||||
block()
|
block()
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend inline fun <R> ContentMessage<*>.doAfterVerification(adminsCacheAPI: AdminsCacheAPI, block: () -> R) = doIfAdmin(adminsCacheAPI, block)
|
||||||
|
@ -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<AdministratorChatMember> {
|
||||||
|
val botInfo = botInfo ?: getMe()
|
||||||
|
val admins = getChatAdministrators(chatId).filter {
|
||||||
|
botInfo.id != it.user.id
|
||||||
|
}
|
||||||
|
repo.setChatAdmins(chatId, admins)
|
||||||
|
return admins
|
||||||
|
}
|
@ -28,7 +28,7 @@ private class SetChatAdminsRepoAction(
|
|||||||
override val toReturn: Continuation<Unit>
|
override val toReturn: Continuation<Unit>
|
||||||
) : RepoActions<Unit>()
|
) : RepoActions<Unit>()
|
||||||
|
|
||||||
class DefaultAdminsCacheAPIRepo(
|
class DefaultAdminsCacheAPIRepoImpl(
|
||||||
private val adminsRepo: KeyValuesRepo<ChatId, AdministratorChatMember>,
|
private val adminsRepo: KeyValuesRepo<ChatId, AdministratorChatMember>,
|
||||||
private val updatesRepo: KeyValueRepo<ChatId, MilliSeconds>,
|
private val updatesRepo: KeyValueRepo<ChatId, MilliSeconds>,
|
||||||
private val scope: CoroutineScope
|
private val scope: CoroutineScope
|
||||||
@ -53,6 +53,7 @@ class DefaultAdminsCacheAPIRepo(
|
|||||||
override suspend fun getChatAdmins(chatId: ChatId): List<AdministratorChatMember>? = suspendCoroutine {
|
override suspend fun getChatAdmins(chatId: ChatId): List<AdministratorChatMember>? = suspendCoroutine {
|
||||||
actor.trySend(GetChatAdminsRepoAction(chatId, it))
|
actor.trySend(GetChatAdminsRepoAction(chatId, it))
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setChatAdmins(chatId: ChatId, chatMembers: List<AdministratorChatMember>) = suspendCoroutine<Unit> {
|
override suspend fun setChatAdmins(chatId: ChatId, chatMembers: List<AdministratorChatMember>) = suspendCoroutine<Unit> {
|
||||||
actor.trySend(SetChatAdminsRepoAction(chatId, chatMembers, it))
|
actor.trySend(SetChatAdminsRepoAction(chatId, chatMembers, it))
|
||||||
}
|
}
|
||||||
@ -60,3 +61,9 @@ class DefaultAdminsCacheAPIRepo(
|
|||||||
actor.trySend(GetUpdateDateTimeRepoAction(chatId, it))
|
actor.trySend(GetUpdateDateTimeRepoAction(chatId, it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DefaultAdminsCacheAPIRepo(
|
||||||
|
adminsRepo: KeyValuesRepo<ChatId, AdministratorChatMember>,
|
||||||
|
updatesRepo: KeyValueRepo<ChatId, MilliSeconds>,
|
||||||
|
scope: CoroutineScope
|
||||||
|
) = DefaultAdminsCacheAPIRepoImpl(adminsRepo, updatesRepo, scope)
|
||||||
|
@ -5,20 +5,18 @@ import dev.inmo.micro_utils.repos.exposed.onetomany.ExposedKeyValuesRepo
|
|||||||
import dev.inmo.micro_utils.repos.mappers.withMapper
|
import dev.inmo.micro_utils.repos.mappers.withMapper
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
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.libraries.cache.admins.micro_utils.DynamicAdminsCacheSettingsAPI
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.chat.member.*
|
import dev.inmo.tgbotapi.types.chat.member.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.cbor.Cbor
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
import kotlinx.serialization.modules.polymorphic
|
import kotlinx.serialization.modules.polymorphic
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import org.jetbrains.exposed.sql.statements.api.ExposedBlob
|
|
||||||
|
|
||||||
private val serializationFormat = Json {
|
val telegramAdminsSerializationFormat = Json {
|
||||||
ignoreUnknownKeys = true
|
ignoreUnknownKeys = true
|
||||||
serializersModule = SerializersModule {
|
serializersModule = SerializersModule {
|
||||||
polymorphic(AdministratorChatMember::class) {
|
polymorphic(AdministratorChatMember::class) {
|
||||||
@ -29,13 +27,12 @@ private val serializationFormat = Json {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun AdminsCacheAPI(
|
fun BehaviourContext.createAdminsCacheAPI(database: Database) = AdminsCacheAPI(this, database, this)
|
||||||
bot: TelegramBot,
|
|
||||||
|
fun TelegramBot.createAdminsCacheAPI(
|
||||||
database: Database,
|
database: Database,
|
||||||
scope: CoroutineScope
|
scope: CoroutineScope,
|
||||||
) : AdminsCacheAPI = DefaultAdminsCacheAPI(
|
defaultAdminsCacheAPIRepo: DefaultAdminsCacheAPIRepo = DefaultAdminsCacheAPIRepoImpl(
|
||||||
bot,
|
|
||||||
DefaultAdminsCacheAPIRepo(
|
|
||||||
ExposedKeyValuesRepo(
|
ExposedKeyValuesRepo(
|
||||||
database,
|
database,
|
||||||
{ long("chatId") },
|
{ long("chatId") },
|
||||||
@ -43,9 +40,9 @@ fun AdminsCacheAPI(
|
|||||||
"AdminsTable"
|
"AdminsTable"
|
||||||
).withMapper<ChatId, AdministratorChatMember, Identifier, String>(
|
).withMapper<ChatId, AdministratorChatMember, Identifier, String>(
|
||||||
keyFromToTo = { chatId },
|
keyFromToTo = { chatId },
|
||||||
valueFromToTo = { serializationFormat.encodeToString(this) },
|
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) },
|
||||||
keyToToFrom = { toChatId() },
|
keyToToFrom = { toChatId() },
|
||||||
valueToToFrom = { serializationFormat.decodeFromString(this) }
|
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) }
|
||||||
),
|
),
|
||||||
ExposedKeyValueRepo(
|
ExposedKeyValueRepo(
|
||||||
database,
|
database,
|
||||||
@ -60,7 +57,7 @@ fun AdminsCacheAPI(
|
|||||||
),
|
),
|
||||||
scope
|
scope
|
||||||
),
|
),
|
||||||
DynamicAdminsCacheSettingsAPI(
|
adminsCacheSettingsAPI: AdminsCacheSettingsAPI = DynamicAdminsCacheSettingsAPI(
|
||||||
ExposedKeyValueRepo(
|
ExposedKeyValueRepo(
|
||||||
database,
|
database,
|
||||||
{ long("chatId") },
|
{ long("chatId") },
|
||||||
@ -68,12 +65,19 @@ fun AdminsCacheAPI(
|
|||||||
"DynamicAdminsCacheSettingsAPI"
|
"DynamicAdminsCacheSettingsAPI"
|
||||||
).withMapper<ChatId, AdminsCacheSettings, Identifier, String>(
|
).withMapper<ChatId, AdminsCacheSettings, Identifier, String>(
|
||||||
keyFromToTo = { chatId },
|
keyFromToTo = { chatId },
|
||||||
valueFromToTo = { serializationFormat.encodeToString(this) },
|
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) },
|
||||||
keyToToFrom = { toChatId() },
|
keyToToFrom = { toChatId() },
|
||||||
valueToToFrom = { serializationFormat.decodeFromString(this) }
|
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) }
|
||||||
),
|
),
|
||||||
scope
|
scope
|
||||||
)
|
)
|
||||||
)
|
) = DefaultAdminsCacheAPI(this, defaultAdminsCacheAPIRepo, adminsCacheSettingsAPI)
|
||||||
|
|
||||||
fun BehaviourContext.AdminsCacheAPI(database: Database) = AdminsCacheAPI(this, database, this)
|
fun AdminsCacheAPI(
|
||||||
|
bot: TelegramBot,
|
||||||
|
database: Database,
|
||||||
|
scope: CoroutineScope
|
||||||
|
) : AdminsCacheAPI = bot.createAdminsCacheAPI(
|
||||||
|
database,
|
||||||
|
scope
|
||||||
|
)
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
package dev.inmo.tgbotapi.libraries.cache.admins
|
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.plagubot.Plugin
|
||||||
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
|
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.flow.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Transient
|
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
import org.koin.core.Koin
|
import org.koin.core.Koin
|
||||||
import org.koin.core.module.Module
|
import org.koin.core.module.Module
|
||||||
|
import org.koin.core.qualifier.named
|
||||||
import org.koin.core.scope.Scope
|
import org.koin.core.scope.Scope
|
||||||
|
import org.koin.dsl.binds
|
||||||
|
|
||||||
val Scope.adminsPlugin: AdminsPlugin?
|
val Scope.adminsPlugin: AdminsPlugin?
|
||||||
get() = getOrNull()
|
get() = getOrNull()
|
||||||
@ -28,6 +36,7 @@ class AdminsPlugin : Plugin {
|
|||||||
private val databaseToAdminsCacheAPI = mutableMapOf<Database, MutableStateFlow<AdminsCacheAPI?>>()
|
private val databaseToAdminsCacheAPI = mutableMapOf<Database, MutableStateFlow<AdminsCacheAPI?>>()
|
||||||
private val mutex = Mutex()
|
private val mutex = Mutex()
|
||||||
|
|
||||||
|
@Deprecated("Will be removed soon due to its redundancy")
|
||||||
suspend fun adminsAPI(database: Database): AdminsCacheAPI {
|
suspend fun adminsAPI(database: Database): AdminsCacheAPI {
|
||||||
val flow = mutex.withLock {
|
val flow = mutex.withLock {
|
||||||
databaseToAdminsCacheAPI.getOrPut(database){ MutableStateFlow(null) }
|
databaseToAdminsCacheAPI.getOrPut(database){ MutableStateFlow(null) }
|
||||||
@ -37,16 +46,61 @@ class AdminsPlugin : Plugin {
|
|||||||
|
|
||||||
override fun Module.setupDI(database: Database, params: JsonObject) {
|
override fun Module.setupDI(database: Database, params: JsonObject) {
|
||||||
single { this@AdminsPlugin }
|
single { this@AdminsPlugin }
|
||||||
|
val scopeQualifier = named("admins plugin scope")
|
||||||
|
single(scopeQualifier) { CoroutineScope(Dispatchers.IO + SupervisorJob()) }
|
||||||
|
single<DefaultAdminsCacheAPIRepo> {
|
||||||
|
DefaultAdminsCacheAPIRepoImpl(
|
||||||
|
ExposedKeyValuesRepo(
|
||||||
|
database,
|
||||||
|
{ long("chatId") },
|
||||||
|
{ text("member") },
|
||||||
|
"AdminsTable"
|
||||||
|
).withMapper<ChatId, AdministratorChatMember, Identifier, String>(
|
||||||
|
keyFromToTo = { chatId },
|
||||||
|
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) },
|
||||||
|
keyToToFrom = { toChatId() },
|
||||||
|
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) }
|
||||||
|
),
|
||||||
|
ExposedKeyValueRepo(
|
||||||
|
database,
|
||||||
|
{ long("chatId") },
|
||||||
|
{ long("datetime") },
|
||||||
|
"AdminsUpdatesTimesTable"
|
||||||
|
).withMapper<ChatId, Long, Identifier, Long>(
|
||||||
|
keyFromToTo = { chatId },
|
||||||
|
valueFromToTo = { this },
|
||||||
|
keyToToFrom = { toChatId() },
|
||||||
|
valueToToFrom = { this }
|
||||||
|
),
|
||||||
|
get(scopeQualifier)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
single<AdminsCacheSettingsAPI> {
|
||||||
|
DynamicAdminsCacheSettingsAPI(
|
||||||
|
ExposedKeyValueRepo(
|
||||||
|
database,
|
||||||
|
{ long("chatId") },
|
||||||
|
{ text("settings") },
|
||||||
|
"DynamicAdminsCacheSettingsAPI"
|
||||||
|
).withMapper<ChatId, AdminsCacheSettings, Identifier, String>(
|
||||||
|
keyFromToTo = { chatId },
|
||||||
|
valueFromToTo = { telegramAdminsSerializationFormat.encodeToString(this) },
|
||||||
|
keyToToFrom = { toChatId() },
|
||||||
|
valueToToFrom = { telegramAdminsSerializationFormat.decodeFromString(this) }
|
||||||
|
),
|
||||||
|
get(scopeQualifier)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
single { DefaultAdminsCacheAPI(get(), get(), get()) } binds arrayOf(
|
||||||
|
AdminsCacheAPI::class
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
|
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
|
||||||
with(koin) {
|
with(koin) {
|
||||||
mutex.withLock {
|
activateAdminsChangesListening(
|
||||||
val flow = databaseToAdminsCacheAPI.getOrPut(koin.get()){ MutableStateFlow(null) }
|
get()
|
||||||
if (flow.value == null) {
|
)
|
||||||
flow.value = AdminsCacheAPI(koin.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ kotlin_serialisation_core_version=1.4.0
|
|||||||
|
|
||||||
github_release_plugin_version=2.4.1
|
github_release_plugin_version=2.4.1
|
||||||
|
|
||||||
tgbotapi_version=3.2.0
|
tgbotapi_version=3.2.1
|
||||||
micro_utils_version=0.12.5
|
micro_utils_version=0.12.11
|
||||||
exposed_version=0.39.2
|
exposed_version=0.39.2
|
||||||
plagubot_version=2.2.0
|
plagubot_version=2.3.1
|
||||||
|
|
||||||
# ANDROID
|
# ANDROID
|
||||||
|
|
||||||
@ -33,5 +33,5 @@ dokka_version=1.7.10
|
|||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.5.2
|
version=0.5.3
|
||||||
android_code_version=29
|
android_code_version=30
|
||||||
|
Loading…
Reference in New Issue
Block a user