1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165 |
- # █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
- # █▀█ █ █ █ █▀█ █▀▄ █
- # © Copyright 2022
- # https://t.me/hikariatama
- #
- # 🔒 Licensed under the GNU AGPLv3
- # 🌐 https://www.gnu.org/licenses/agpl-3.0.html
- import ast
- import functools
- from math import ceil
- import typing
- from telethon.tl.types import Message
- from .. import loader, utils, translations
- from ..inline.types import InlineCall
- # Everywhere in this module, we use the following naming convention:
- # `obj_type` of non-core module = False
- # `obj_type` of core module = True
- # `obj_type` of library = "library"
- @loader.tds
- class HikkaConfigMod(loader.Module):
- """Interactive configurator for Hikka Userbot"""
- strings = {
- "name": "HikkaConfig",
- "choose_core": "🎚 <b>Choose a category</b>",
- "configure": "🎚 <b>Choose a module to configure</b>",
- "configure_lib": "🪴 <b>Choose a library to configure</b>",
- "configuring_mod": (
- "🎚 <b>Choose config option for mod</b> <code>{}</code>\n\n<b>Current"
- " options:</b>\n\n{}"
- ),
- "configuring_lib": (
- "🪴 <b>Choose config option for library</b> <code>{}</code>\n\n<b>Current"
- " options:</b>\n\n{}"
- ),
- "configuring_option": (
- "🎚 <b>Configuring option </b><code>{}</code><b> of mod"
- " </b><code>{}</code>\n<i>ℹ️ {}</i>\n\n<b>Default: {}</b>\n\n<b>Current:"
- " {}</b>\n\n{}"
- ),
- "configuring_option_lib": (
- "🪴 <b>Configuring option </b><code>{}</code><b> of library"
- " </b><code>{}</code>\n<i>ℹ️ {}</i>\n\n<b>Default: {}</b>\n\n<b>Current:"
- " {}</b>\n\n{}"
- ),
- "option_saved": (
- "🎚 <b>Option </b><code>{}</code><b> of module </b><code>{}</code><b>"
- " saved!</b>\n<b>Current: {}</b>"
- ),
- "option_saved_lib": (
- "🪴 <b>Option </b><code>{}</code><b> of library </b><code>{}</code><b>"
- " saved!</b>\n<b>Current: {}</b>"
- ),
- "option_reset": (
- "♻️ <b>Option </b><code>{}</code><b> of module </b><code>{}</code><b> has"
- " been reset to default</b>\n<b>Current: {}</b>"
- ),
- "option_reset_lib": (
- "♻️ <b>Option </b><code>{}</code><b> of library </b><code>{}</code><b> has"
- " been reset to default</b>\n<b>Current: {}</b>"
- ),
- "args": "🚫 <b>You specified incorrect args</b>",
- "no_mod": "🚫 <b>Module doesn't exist</b>",
- "no_option": "🚫 <b>Configuration option doesn't exist</b>",
- "validation_error": "🚫 <b>You entered incorrect config value. \nError: {}</b>",
- "try_again": "🔁 Try again",
- "typehint": "🕵️ <b>Must be a{eng_art} {}</b>",
- "set": "set",
- "set_default_btn": "♻️ Reset default",
- "enter_value_btn": "✍️ Enter value",
- "enter_value_desc": "✍️ Enter new configuration value for this option",
- "add_item_desc": "✍️ Enter item to add",
- "remove_item_desc": "✍️ Enter item to remove",
- "back_btn": "👈 Back",
- "close_btn": "🔻 Close",
- "add_item_btn": "➕ Add item",
- "remove_item_btn": "➖ Remove item",
- "show_hidden": "🚸 Show value",
- "hide_value": "🔒 Hide value",
- "builtin": "🛰 Built-in",
- "external": "🛸 External",
- "libraries": "🪴 Libraries",
- }
- strings_ru = {
- "choose_core": "🎚 <b>Выбери категорию</b>",
- "configure": "🎚 <b>Выбери модуль для настройки</b>",
- "configure_lib": "🪴 <b>Выбери библиотеку для настройки</b>",
- "configuring_mod": (
- "🎚 <b>Выбери параметр для модуля</b> <code>{}</code>\n\n<b>Текущие"
- " настройки:</b>\n\n{}"
- ),
- "configuring_lib": (
- "🪴 <b>Выбери параметр для библиотеки</b> <code>{}</code>\n\n<b>Текущие"
- " настройки:</b>\n\n{}"
- ),
- "configuring_option": (
- "🎚 <b>Управление параметром </b><code>{}</code><b> модуля"
- " </b><code>{}</code>\n<i>ℹ️ {}</i>\n\n<b>Стандартное:"
- " {}</b>\n\n<b>Текущее: {}</b>\n\n{}"
- ),
- "configuring_option_lib": (
- "🪴 <b>Управление параметром </b><code>{}</code><b> библиотеки"
- " </b><code>{}</code>\n<i>ℹ️ {}</i>\n\n<b>Стандартное:"
- " {}</b>\n\n<b>Текущее: {}</b>\n\n{}"
- ),
- "option_saved": (
- "🎚 <b>Параметр </b><code>{}</code><b> модуля </b><code>{}</code><b>"
- " сохранен!</b>\n<b>Текущее: {}</b>"
- ),
- "option_saved_lib": (
- "🪴 <b>Параметр </b><code>{}</code><b> библиотеки </b><code>{}</code><b>"
- " сохранен!</b>\n<b>Текущее: {}</b>"
- ),
- "option_reset": (
- "♻️ <b>Параметр </b><code>{}</code><b> модуля </b><code>{}</code><b>"
- " сброшен до значения по умолчанию</b>\n<b>Текущее: {}</b>"
- ),
- "option_reset_lib": (
- "♻️ <b>Параметр </b><code>{}</code><b> библиотеки </b><code>{}</code><b>"
- " сброшен до значения по умолчанию</b>\n<b>Текущее: {}</b>"
- ),
- "_cls_doc": "Интерактивный конфигуратор Hikka",
- "args": "🚫 <b>Ты указал неверные аргументы</b>",
- "no_mod": "🚫 <b>Модуль не существует</b>",
- "no_option": "🚫 <b>У модуля нет такого значения конфига</b>",
- "validation_error": (
- "🚫 <b>Введено некорректное значение конфига. \nОшибка: {}</b>"
- ),
- "try_again": "🔁 Попробовать еще раз",
- "typehint": "🕵️ <b>Должно быть {}</b>",
- "set": "поставить",
- "set_default_btn": "♻️ Значение по умолчанию",
- "enter_value_btn": "✍️ Ввести значение",
- "enter_value_desc": "✍️ Введи новое значение этого параметра",
- "add_item_desc": "✍️ Введи элемент, который нужно добавить",
- "remove_item_desc": "✍️ Введи элемент, который нужно удалить",
- "back_btn": "👈 Назад",
- "close_btn": "🔻 Закрыть",
- "add_item_btn": "➕ Добавить элемент",
- "remove_item_btn": "➖ Удалить элемент",
- "show_hidden": "🚸 Показать значение",
- "hide_value": "🔒 Скрыть значение",
- "builtin": "🛰 Встроенные",
- "external": "🛸 Внешние",
- "libraries": "🪴 Библиотеки",
- }
- _row_size = 3
- _num_rows = 5
- @staticmethod
- def prep_value(value: typing.Any) -> typing.Any:
- if isinstance(value, str):
- return f"</b><code>{utils.escape_html(value.strip())}</code><b>"
- if isinstance(value, list) and value:
- return (
- "</b><code>[</code>\n "
- + "\n ".join(
- [f"<code>{utils.escape_html(str(item))}</code>" for item in value]
- )
- + "\n<code>]</code><b>"
- )
- return f"</b><code>{utils.escape_html(value)}</code><b>"
- def hide_value(self, value: typing.Any) -> str:
- if isinstance(value, list) and value:
- return self.prep_value(["*" * len(str(i)) for i in value])
- return self.prep_value("*" * len(str(value)))
- async def inline__set_config(
- self,
- call: InlineCall,
- query: str,
- mod: str,
- option: str,
- inline_message_id: str,
- obj_type: typing.Union[bool, str] = False,
- ):
- try:
- self.lookup(mod).config[option] = query
- except loader.validators.ValidationError as e:
- await call.edit(
- self.strings("validation_error").format(e.args[0]),
- reply_markup={
- "text": self.strings("try_again"),
- "callback": self.inline__configure_option,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- },
- )
- return
- await call.edit(
- self.strings(
- "option_saved" if isinstance(obj_type, bool) else "option_saved_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- self.prep_value(self.lookup(mod).config[option])
- if not self.lookup(mod).config._config[option].validator
- or self.lookup(mod).config._config[option].validator.internal_id
- != "Hidden"
- else self.hide_value(self.lookup(mod).config[option]),
- ),
- reply_markup=[
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ],
- inline_message_id=inline_message_id,
- )
- async def inline__reset_default(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- obj_type: typing.Union[bool, str] = False,
- ):
- mod_instance = self.lookup(mod)
- mod_instance.config[option] = mod_instance.config.getdef(option)
- await call.edit(
- self.strings(
- "option_reset" if isinstance(obj_type, bool) else "option_reset_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- self.prep_value(self.lookup(mod).config[option])
- if not self.lookup(mod).config._config[option].validator
- or self.lookup(mod).config._config[option].validator.internal_id
- != "Hidden"
- else self.hide_value(self.lookup(mod).config[option]),
- ),
- reply_markup=[
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ],
- )
- async def inline__set_bool(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- value: bool,
- obj_type: typing.Union[bool, str] = False,
- ):
- try:
- self.lookup(mod).config[option] = value
- except loader.validators.ValidationError as e:
- await call.edit(
- self.strings("validation_error").format(e.args[0]),
- reply_markup={
- "text": self.strings("try_again"),
- "callback": self.inline__configure_option,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- },
- )
- return
- validator = self.lookup(mod).config._config[option].validator
- doc = utils.escape_html(
- next(
- (
- validator.doc[lang]
- for lang in self._db.get(translations.__name__, "lang", "en").split(
- " "
- )
- if lang in validator.doc
- ),
- validator.doc["en"],
- )
- )
- await call.edit(
- self.strings(
- "configuring_option"
- if isinstance(obj_type, bool)
- else "configuring_option_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- utils.escape_html(self.lookup(mod).config.getdoc(option)),
- self.prep_value(self.lookup(mod).config.getdef(option)),
- self.prep_value(self.lookup(mod).config[option])
- if not validator or validator.internal_id != "Hidden"
- else self.hide_value(self.lookup(mod).config[option]),
- self.strings("typehint").format(
- doc,
- eng_art="n" if doc.lower().startswith(tuple("euioay")) else "",
- )
- if doc
- else "",
- ),
- reply_markup=self._generate_bool_markup(mod, option, obj_type),
- )
- await call.answer("✅")
- def _generate_bool_markup(
- self,
- mod: str,
- option: str,
- obj_type: typing.Union[bool, str] = False,
- ) -> list:
- return [
- [
- *(
- [
- {
- "text": f"❌ {self.strings('set')} `False`",
- "callback": self.inline__set_bool,
- "args": (mod, option, False),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- if self.lookup(mod).config[option]
- else [
- {
- "text": f"✅ {self.strings('set')} `True`",
- "callback": self.inline__set_bool,
- "args": (mod, option, True),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- )
- ],
- [
- *(
- [
- {
- "text": self.strings("set_default_btn"),
- "callback": self.inline__reset_default,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- if self.lookup(mod).config[option]
- != self.lookup(mod).config.getdef(option)
- else []
- )
- ],
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ],
- ]
- async def inline__add_item(
- self,
- call: InlineCall,
- query: str,
- mod: str,
- option: str,
- inline_message_id: str,
- obj_type: typing.Union[bool, str] = False,
- ):
- try:
- try:
- query = ast.literal_eval(query)
- except Exception:
- pass
- if isinstance(query, (set, tuple)):
- query = list(query)
- if not isinstance(query, list):
- query = [query]
- self.lookup(mod).config[option] = self.lookup(mod).config[option] + query
- except loader.validators.ValidationError as e:
- await call.edit(
- self.strings("validation_error").format(e.args[0]),
- reply_markup={
- "text": self.strings("try_again"),
- "callback": self.inline__configure_option,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- },
- )
- return
- await call.edit(
- self.strings(
- "option_saved" if isinstance(obj_type, bool) else "option_saved_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- self.prep_value(self.lookup(mod).config[option])
- if not self.lookup(mod).config._config[option].validator
- or self.lookup(mod).config._config[option].validator.internal_id
- != "Hidden"
- else self.hide_value(self.lookup(mod).config[option]),
- ),
- reply_markup=[
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ],
- inline_message_id=inline_message_id,
- )
- async def inline__remove_item(
- self,
- call: InlineCall,
- query: str,
- mod: str,
- option: str,
- inline_message_id: str,
- obj_type: typing.Union[bool, str] = False,
- ):
- try:
- try:
- query = ast.literal_eval(query)
- except Exception:
- pass
- if isinstance(query, (set, tuple)):
- query = list(query)
- if not isinstance(query, list):
- query = [query]
- query = list(map(str, query))
- old_config_len = len(self.lookup(mod).config[option])
- self.lookup(mod).config[option] = [
- i for i in self.lookup(mod).config[option] if str(i) not in query
- ]
- if old_config_len == len(self.lookup(mod).config[option]):
- raise loader.validators.ValidationError(
- f"Nothing from passed value ({self.prep_value(query)}) is not in"
- " target list"
- )
- except loader.validators.ValidationError as e:
- await call.edit(
- self.strings("validation_error").format(e.args[0]),
- reply_markup={
- "text": self.strings("try_again"),
- "callback": self.inline__configure_option,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- },
- )
- return
- await call.edit(
- self.strings(
- "option_saved" if isinstance(obj_type, bool) else "option_saved_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- self.prep_value(self.lookup(mod).config[option])
- if not self.lookup(mod).config._config[option].validator
- or self.lookup(mod).config._config[option].validator.internal_id
- != "Hidden"
- else self.hide_value(self.lookup(mod).config[option]),
- ),
- reply_markup=[
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ],
- inline_message_id=inline_message_id,
- )
- def _generate_series_markup(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- obj_type: typing.Union[bool, str] = False,
- ) -> list:
- return [
- [
- {
- "text": self.strings("enter_value_btn"),
- "input": self.strings("enter_value_desc"),
- "handler": self.inline__set_config,
- "args": (mod, option, call.inline_message_id),
- "kwargs": {"obj_type": obj_type},
- }
- ],
- [
- *(
- [
- {
- "text": self.strings("remove_item_btn"),
- "input": self.strings("remove_item_desc"),
- "handler": self.inline__remove_item,
- "args": (mod, option, call.inline_message_id),
- "kwargs": {"obj_type": obj_type},
- },
- {
- "text": self.strings("add_item_btn"),
- "input": self.strings("add_item_desc"),
- "handler": self.inline__add_item,
- "args": (mod, option, call.inline_message_id),
- "kwargs": {"obj_type": obj_type},
- },
- ]
- if self.lookup(mod).config[option]
- else []
- ),
- ],
- [
- *(
- [
- {
- "text": self.strings("set_default_btn"),
- "callback": self.inline__reset_default,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- if self.lookup(mod).config[option]
- != self.lookup(mod).config.getdef(option)
- else []
- )
- ],
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ],
- ]
- async def _choice_set_value(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- value: bool,
- obj_type: typing.Union[bool, str] = False,
- ):
- try:
- self.lookup(mod).config[option] = value
- except loader.validators.ValidationError as e:
- await call.edit(
- self.strings("validation_error").format(e.args[0]),
- reply_markup={
- "text": self.strings("try_again"),
- "callback": self.inline__configure_option,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- },
- )
- return
- validator = self.lookup(mod).config._config[option].validator
- await call.edit(
- self.strings(
- "option_saved" if isinstance(obj_type, bool) else "option_saved_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- self.prep_value(self.lookup(mod).config[option])
- if not validator.internal_id == "Hidden"
- else self.hide_value(self.lookup(mod).config[option]),
- ),
- reply_markup=[
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ],
- )
- await call.answer("✅")
- async def _multi_choice_set_value(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- value: bool,
- obj_type: typing.Union[bool, str] = False,
- ):
- try:
- if value in self.lookup(mod).config._config[option].value:
- self.lookup(mod).config._config[option].value.remove(value)
- else:
- self.lookup(mod).config._config[option].value += [value]
- self.lookup(mod).config.reload()
- except loader.validators.ValidationError as e:
- await call.edit(
- self.strings("validation_error").format(e.args[0]),
- reply_markup={
- "text": self.strings("try_again"),
- "callback": self.inline__configure_option,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- },
- )
- return
- await self.inline__configure_option(call, mod, option, False, obj_type)
- await call.answer("✅")
- def _generate_choice_markup(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- obj_type: typing.Union[bool, str] = False,
- ) -> list:
- possible_values = list(
- self.lookup(mod)
- .config._config[option]
- .validator.validate.keywords["possible_values"]
- )
- return [
- [
- {
- "text": self.strings("enter_value_btn"),
- "input": self.strings("enter_value_desc"),
- "handler": self.inline__set_config,
- "args": (mod, option, call.inline_message_id),
- "kwargs": {"obj_type": obj_type},
- }
- ],
- *utils.chunks(
- [
- {
- "text": (
- f"{'☑️' if self.lookup(mod).config[option] == value else '🔘'} "
- f"{value if len(str(value)) < 20 else str(value)[:20]}"
- ),
- "callback": self._choice_set_value,
- "args": (mod, option, value, obj_type),
- }
- for value in possible_values
- ],
- 2,
- )[
- : 6
- if self.lookup(mod).config[option]
- != self.lookup(mod).config.getdef(option)
- else 7
- ],
- [
- *(
- [
- {
- "text": self.strings("set_default_btn"),
- "callback": self.inline__reset_default,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- if self.lookup(mod).config[option]
- != self.lookup(mod).config.getdef(option)
- else []
- )
- ],
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ],
- ]
- def _generate_multi_choice_markup(
- self,
- call: InlineCall,
- mod: str,
- option: str,
- obj_type: typing.Union[bool, str] = False,
- ) -> list:
- possible_values = list(
- self.lookup(mod)
- .config._config[option]
- .validator.validate.keywords["possible_values"]
- )
- return [
- [
- {
- "text": self.strings("enter_value_btn"),
- "input": self.strings("enter_value_desc"),
- "handler": self.inline__set_config,
- "args": (mod, option, call.inline_message_id),
- "kwargs": {"obj_type": obj_type},
- }
- ],
- *utils.chunks(
- [
- {
- "text": (
- f"{'☑️' if value in self.lookup(mod).config[option] else '◻️'} "
- f"{value if len(str(value)) < 20 else str(value)[:20]}"
- ),
- "callback": self._multi_choice_set_value,
- "args": (mod, option, value, obj_type),
- }
- for value in possible_values
- ],
- 2,
- )[
- : 6
- if self.lookup(mod).config[option]
- != self.lookup(mod).config.getdef(option)
- else 7
- ],
- [
- *(
- [
- {
- "text": self.strings("set_default_btn"),
- "callback": self.inline__reset_default,
- "args": (mod, option),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- if self.lookup(mod).config[option]
- != self.lookup(mod).config.getdef(option)
- else []
- )
- ],
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ],
- ]
- async def inline__configure_option(
- self,
- call: InlineCall,
- mod: str,
- config_opt: str,
- force_hidden: bool = False,
- obj_type: typing.Union[bool, str] = False,
- ):
- module = self.lookup(mod)
- args = [
- utils.escape_html(config_opt),
- utils.escape_html(mod),
- utils.escape_html(module.config.getdoc(config_opt)),
- self.prep_value(module.config.getdef(config_opt)),
- self.prep_value(module.config[config_opt])
- if not module.config._config[config_opt].validator
- or module.config._config[config_opt].validator.internal_id != "Hidden"
- or force_hidden
- else self.hide_value(module.config[config_opt]),
- ]
- if (
- module.config._config[config_opt].validator
- and module.config._config[config_opt].validator.internal_id == "Hidden"
- ):
- additonal_button_row = (
- [
- [
- {
- "text": self.strings("hide_value"),
- "callback": self.inline__configure_option,
- "args": (mod, config_opt, False),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- ]
- if force_hidden
- else [
- [
- {
- "text": self.strings("show_hidden"),
- "callback": self.inline__configure_option,
- "args": (mod, config_opt, True),
- "kwargs": {"obj_type": obj_type},
- }
- ]
- ]
- )
- else:
- additonal_button_row = []
- try:
- validator = module.config._config[config_opt].validator
- doc = utils.escape_html(
- next(
- (
- validator.doc[lang]
- for lang in self._db.get(
- translations.__name__, "lang", "en"
- ).split(" ")
- if lang in validator.doc
- ),
- validator.doc["en"],
- )
- )
- except Exception:
- doc = None
- validator = None
- args += [""]
- else:
- args += [
- self.strings("typehint").format(
- doc,
- eng_art="n" if doc.lower().startswith(tuple("euioay")) else "",
- )
- ]
- if validator.internal_id == "Boolean":
- await call.edit(
- self.strings(
- "configuring_option"
- if isinstance(obj_type, bool)
- else "configuring_option_lib"
- ).format(*args),
- reply_markup=additonal_button_row
- + self._generate_bool_markup(mod, config_opt, obj_type),
- )
- return
- if validator.internal_id == "Series":
- await call.edit(
- self.strings(
- "configuring_option"
- if isinstance(obj_type, bool)
- else "configuring_option_lib"
- ).format(*args),
- reply_markup=additonal_button_row
- + self._generate_series_markup(call, mod, config_opt, obj_type),
- )
- return
- if validator.internal_id == "Choice":
- await call.edit(
- self.strings(
- "configuring_option"
- if isinstance(obj_type, bool)
- else "configuring_option_lib"
- ).format(*args),
- reply_markup=additonal_button_row
- + self._generate_choice_markup(call, mod, config_opt, obj_type),
- )
- return
- if validator.internal_id == "MultiChoice":
- await call.edit(
- self.strings(
- "configuring_option"
- if isinstance(obj_type, bool)
- else "configuring_option_lib"
- ).format(*args),
- reply_markup=additonal_button_row
- + self._generate_multi_choice_markup(
- call, mod, config_opt, obj_type
- ),
- )
- return
- await call.edit(
- self.strings(
- "configuring_option"
- if isinstance(obj_type, bool)
- else "configuring_option_lib"
- ).format(*args),
- reply_markup=additonal_button_row
- + [
- [
- {
- "text": self.strings("enter_value_btn"),
- "input": self.strings("enter_value_desc"),
- "handler": self.inline__set_config,
- "args": (mod, config_opt, call.inline_message_id),
- "kwargs": {"obj_type": obj_type},
- }
- ],
- [
- {
- "text": self.strings("set_default_btn"),
- "callback": self.inline__reset_default,
- "args": (mod, config_opt),
- "kwargs": {"obj_type": obj_type},
- }
- ],
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__configure,
- "args": (mod,),
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ],
- ],
- )
- async def inline__configure(
- self,
- call: InlineCall,
- mod: str,
- obj_type: typing.Union[bool, str] = False,
- ):
- btns = [
- {
- "text": param,
- "callback": self.inline__configure_option,
- "args": (mod, param),
- "kwargs": {"obj_type": obj_type},
- }
- for param in self.lookup(mod).config
- ]
- await call.edit(
- self.strings(
- "configuring_mod" if isinstance(obj_type, bool) else "configuring_lib"
- ).format(
- utils.escape_html(mod),
- "\n".join(
- [
- f"▫️ <code>{utils.escape_html(key)}</code>: <b>{{}}</b>".format(
- self.prep_value(value)
- if (
- not self.lookup(mod).config._config[key].validator
- or self.lookup(mod)
- .config._config[key]
- .validator.internal_id
- != "Hidden"
- )
- else self.hide_value(value)
- )
- for key, value in self.lookup(mod).config.items()
- ]
- ),
- ),
- reply_markup=list(utils.chunks(btns, 2))
- + [
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__global_config,
- "kwargs": {"obj_type": obj_type},
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ],
- )
- async def inline__choose_category(self, call: typing.Union[Message, InlineCall]):
- await utils.answer(
- call,
- self.strings("choose_core"),
- reply_markup=[
- [
- {
- "text": self.strings("builtin"),
- "callback": self.inline__global_config,
- "kwargs": {"obj_type": True},
- },
- {
- "text": self.strings("external"),
- "callback": self.inline__global_config,
- },
- ],
- *(
- [
- [
- {
- "text": self.strings("libraries"),
- "callback": self.inline__global_config,
- "kwargs": {"obj_type": "library"},
- }
- ]
- ]
- if self.allmodules.libraries
- and any(hasattr(lib, "config") for lib in self.allmodules.libraries)
- else []
- ),
- [{"text": self.strings("close_btn"), "action": "close"}],
- ],
- )
- async def inline__global_config(
- self,
- call: InlineCall,
- page: int = 0,
- obj_type: typing.Union[bool, str] = False,
- ):
- if isinstance(obj_type, bool):
- to_config = [
- mod.strings("name")
- for mod in self.allmodules.modules
- if hasattr(mod, "config")
- and callable(mod.strings)
- and (mod.__origin__.startswith("<core") or not obj_type)
- and (not mod.__origin__.startswith("<core") or obj_type)
- ]
- else:
- to_config = [
- lib.name for lib in self.allmodules.libraries if hasattr(lib, "config")
- ]
- to_config.sort()
- kb = []
- for mod_row in utils.chunks(
- to_config[
- page
- * self._num_rows
- * self._row_size : (page + 1)
- * self._num_rows
- * self._row_size
- ],
- 3,
- ):
- row = [
- {
- "text": btn,
- "callback": self.inline__configure,
- "args": (btn,),
- "kwargs": {"obj_type": obj_type},
- }
- for btn in mod_row
- ]
- kb += [row]
- if len(to_config) > self._num_rows * self._row_size:
- kb += self.inline.build_pagination(
- callback=functools.partial(
- self.inline__global_config, obj_type=obj_type
- ),
- total_pages=ceil(len(to_config) / (self._num_rows * self._row_size)),
- current_page=page + 1,
- )
- kb += [
- [
- {
- "text": self.strings("back_btn"),
- "callback": self.inline__choose_category,
- },
- {"text": self.strings("close_btn"), "action": "close"},
- ]
- ]
- await call.edit(
- self.strings(
- "configure" if isinstance(obj_type, bool) else "configure_lib"
- ),
- reply_markup=kb,
- )
- @loader.command(ru_doc="Настроить модули")
- async def configcmd(self, message: Message):
- """Configure modules"""
- args = utils.get_args_raw(message)
- if self.lookup(args) and hasattr(self.lookup(args), "config"):
- form = await self.inline.form("🌘 <b>Loading configuration</b>", message)
- mod = self.lookup(args)
- if isinstance(mod, loader.Library):
- type_ = "library"
- else:
- type_ = mod.__origin__.startswith("<core")
- await self.inline__configure(form, args, obj_type=type_)
- return
- await self.inline__choose_category(message)
- @loader.command(
- ru_doc=(
- "<модуль> <настройка> <значениеЮ - установить значение конфига для модуля"
- )
- )
- async def fconfig(self, message: Message):
- """<module_name> <property_name> <config_value> - set the config value for the module
- """
- args = utils.get_args_raw(message).split(maxsplit=2)
- if len(args) < 3:
- await utils.answer(message, self.strings("args"))
- return
- mod, option, value = args
- instance = self.lookup(mod)
- if not instance:
- await utils.answer(message, self.strings("no_mod"))
- return
- if option not in instance.config:
- await utils.answer(message, self.strings("no_option"))
- return
- instance.config[option] = value
- await utils.answer(
- message,
- self.strings(
- "option_saved"
- if isinstance(instance, loader.Module)
- else "option_saved_lib"
- ).format(
- utils.escape_html(option),
- utils.escape_html(mod),
- self.prep_value(instance.config[option])
- if not instance.config._config[option].validator
- or instance.config._config[option].validator.internal_id != "Hidden"
- else self.hide_value(instance.config[option]),
- ),
- )
|