# ÂŠī¸ Dan Gazizullin, 2021-2023 # This file is a part of Hikka Userbot # 🌐 https://github.com/hikariatama/Hikka # You can redistribute it and/or modify it under the terms of the GNU AGPLv3 # 🔑 https://www.gnu.org/licenses/agpl-3.0.html import difflib import inspect import logging from hikkatl.extensions.html import CUSTOM_EMOJIS from hikkatl.tl.types import Message from .. import loader, utils from ..compat.dragon import DRAGON_EMOJI from ..types import DragonModule logger = logging.getLogger(__name__) @loader.tds class HelpMod(loader.Module): """Shows help for modules and commands""" strings = {"name": "Help"} def __init__(self): self.config = loader.ModuleConfig( loader.ConfigValue( "core_emoji", "â–Ēī¸", lambda: "Core module bullet", validator=loader.validators.Emoji(length=1), ), loader.ConfigValue( "plain_emoji", "â–Ģī¸", lambda: "Plain module bullet", validator=loader.validators.Emoji(length=1), ), loader.ConfigValue( "empty_emoji", "🙈", lambda: "Empty modules bullet", validator=loader.validators.Emoji(length=1), ), ) @loader.command() async def helphide(self, message: Message): if not (modules := utils.get_args(message)): await utils.answer(message, self.strings("no_mod")) return currently_hidden = self.get("hide", []) hidden, shown = [], [] for module in filter( lambda module: self.lookup(module, include_dragon=True), modules ): module = self.lookup(module, include_dragon=True) module = ( module.name if isinstance(module, DragonModule) else module.__class__.__name__ ) if module in currently_hidden: currently_hidden.remove(module) shown += [module] else: currently_hidden += [module] hidden += [module] self.set("hide", currently_hidden) await utils.answer( message, self.strings("hidden_shown").format( len(hidden), len(shown), "\n".join([f"👁‍🗨 {m}" for m in hidden]), "\n".join([f"👁 {m}" for m in shown]), ), ) def find_aliases(self, command: str) -> list: """Find aliases for command""" aliases = [] _command = self.allmodules.commands[command] if getattr(_command, "alias", None) and not ( aliases := getattr(_command, "aliases", None) ): aliases = [_command.alias] return aliases or [] async def modhelp(self, message: Message, args: str): exact = True if not (module := self.lookup(args, include_dragon=True)): if method := self.allmodules.dispatch( args.lower().strip(self.get_prefix()) )[1]: module = method.__self__ else: module = self.lookup( next( ( reversed( sorted( [ module.strings["name"] for module in self.allmodules.modules ], key=lambda x: difflib.SequenceMatcher( None, args.lower(), x, ).ratio(), ) ) ), None, ) ) exact = False is_dragon = isinstance(module, DragonModule) try: name = module.strings("name") except (KeyError, AttributeError): name = getattr(module, "name", "ERROR") _name = ( "{} (v{}.{}.{})".format( utils.escape_html(name), module.__version__[0], module.__version__[1], module.__version__[2], ) if hasattr(module, "__version__") else utils.escape_html(name) ) reply = "{} {}:".format( ( DRAGON_EMOJI if is_dragon else "🌘" ), _name, ) if module.__doc__: reply += ( "\nâ„šī¸ " + utils.escape_html(inspect.getdoc(module)) + "\n" ) commands = ( module.commands if is_dragon else { name: func for name, func in module.commands.items() if await self.allmodules.check_security(message, func) } ) if hasattr(module, "inline_handlers") and not is_dragon: for name, fun in module.inline_handlers.items(): reply += ( "\n🤖" " {} {}".format( f"@{self.inline.bot_username} {name}", ( utils.escape_html(inspect.getdoc(fun)) if fun.__doc__ else self.strings("undoc") ), ) ) for name, fun in commands.items(): reply += ( "\nâ–Ģī¸" " {}{}{} {}".format( utils.escape_html(self.get_prefix("dragon" if is_dragon else None)), name, ( " ({})".format( ", ".join( "{}{}".format( utils.escape_html( self.get_prefix("dragon" if is_dragon else None) ), alias, ) for alias in self.find_aliases(name) ) ) if self.find_aliases(name) else "" ), ( utils.escape_html(fun) if is_dragon else ( utils.escape_html(inspect.getdoc(fun)) if fun.__doc__ else self.strings("undoc") ) ), ) ) await utils.answer( message, reply + (f"\n\n{self.strings('not_exact')}" if not exact else "") + ( f"\n\n{self.strings('core_notice')}" if module.__origin__.startswith("