From df1fed10c2d45cd9fd1446f7c2c8f2cc4a07ddd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B0=D0=BA=D1=81=D0=B8=D0=BC=20=D0=A1=D0=BB=D0=B8?= =?UTF-8?q?=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 16 Aug 2024 16:25:42 +0300 Subject: [PATCH] Merged with feat/add-standard-help --- src/altlinux/altlinux/__main__.py | 5 +- src/ocab_core/ocab_core/main.py | 4 +- .../modules_system/public_api/__init__.py | 1 + .../modules_system/public_api/public_api.py | 5 ++ .../ocab_core/modules_system/safe/policy.py | 2 + .../standard/command_helper/__init__.py | 2 +- .../standard/command_helper/main.py | 6 ++ .../ocab_modules/standard/help/__init__.py | 1 + .../ocab_modules/standard/help/info.json | 21 +++++ .../ocab_modules/standard/help/main.py | 81 +++++++++++++++++++ 10 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 src/ocab_modules/ocab_modules/standard/help/__init__.py create mode 100644 src/ocab_modules/ocab_modules/standard/help/info.json create mode 100644 src/ocab_modules/ocab_modules/standard/help/main.py diff --git a/src/altlinux/altlinux/__main__.py b/src/altlinux/altlinux/__main__.py index ffd1e3b..d49b85a 100644 --- a/src/altlinux/altlinux/__main__.py +++ b/src/altlinux/altlinux/__main__.py @@ -1,4 +1,5 @@ import asyncio +from importlib.metadata import version from ocab_core import OCAB from ocab_modules import module_loader @@ -14,7 +15,9 @@ async def main(): module_loader("standard", "filters", safe=False), module_loader("standard", "report"), module_loader("standard", "welcome", safe=False), - ] + module_loader("standard", "help"), + ], + metainfo={"app_version": version("altlinux")}, ) await ocab.start() diff --git a/src/ocab_core/ocab_core/main.py b/src/ocab_core/ocab_core/main.py index 83a0b5c..fb91365 100644 --- a/src/ocab_core/ocab_core/main.py +++ b/src/ocab_core/ocab_core/main.py @@ -17,9 +17,11 @@ class OCAB: def __init__(self) -> None: pass - async def init_app(self, bot_modules): + async def init_app(self, bot_modules, metainfo=None): setup_logger() singleton = Singleton() + if isinstance(metainfo, dict): + singleton.storage["metainfo"] = metainfo try: singleton.modules_manager = ModulesManager() diff --git a/src/ocab_core/ocab_core/modules_system/public_api/__init__.py b/src/ocab_core/ocab_core/modules_system/public_api/__init__.py index 1a1cadb..866f4d6 100644 --- a/src/ocab_core/ocab_core/modules_system/public_api/__init__.py +++ b/src/ocab_core/ocab_core/modules_system/public_api/__init__.py @@ -3,6 +3,7 @@ from ocab_core.logger import log from .public_api import ( Storage, get_fsm_context, + get_metainfo, get_module, register_outer_message_middleware, register_router, diff --git a/src/ocab_core/ocab_core/modules_system/public_api/public_api.py b/src/ocab_core/ocab_core/modules_system/public_api/public_api.py index d7598ec..e9ce931 100644 --- a/src/ocab_core/ocab_core/modules_system/public_api/public_api.py +++ b/src/ocab_core/ocab_core/modules_system/public_api/public_api.py @@ -26,6 +26,11 @@ def register_outer_message_middleware(middleware: BaseMiddleware): app.storage["_outer_message_middlewares"].append(middleware) +def get_metainfo(): + app = Singleton() + return app.storage["metainfo"].copy() + + async def set_my_commands(commands): app = Singleton() await app.bot.set_my_commands(commands) diff --git a/src/ocab_core/ocab_core/modules_system/safe/policy.py b/src/ocab_core/ocab_core/modules_system/safe/policy.py index 08810c9..d74fe6f 100644 --- a/src/ocab_core/ocab_core/modules_system/safe/policy.py +++ b/src/ocab_core/ocab_core/modules_system/safe/policy.py @@ -12,6 +12,7 @@ from RestrictedPython import ( from RestrictedPython.Eval import default_guarded_getitem, default_guarded_getiter from RestrictedPython.Guards import ( # guarded_setattr,; full_write_guard, _write_wrapper, + guarded_iter_unpack_sequence, guarded_unpack_sequence, safer_getattr, ) @@ -138,6 +139,7 @@ BUILTINS["_getitem_"] = default_guarded_getitem BUILTINS["_getattr_"] = safes_getattr BUILTINS["_getiter_"] = default_guarded_getiter BUILTINS["_write_"] = write_guard() +BUILTINS["_iter_unpack_sequence_"] = guarded_iter_unpack_sequence BUILTINS["_unpack_sequence_"] = guarded_unpack_sequence BUILTINS["staticmethod"] = staticmethod BUILTINS["tuple"] = tuple diff --git a/src/ocab_modules/ocab_modules/standard/command_helper/__init__.py b/src/ocab_modules/ocab_modules/standard/command_helper/__init__.py index 90596da..3461e7b 100644 --- a/src/ocab_modules/ocab_modules/standard/command_helper/__init__.py +++ b/src/ocab_modules/ocab_modules/standard/command_helper/__init__.py @@ -1 +1 @@ -from .main import module_late_init, register_command +from .main import get_user_commands, module_late_init, register_command diff --git a/src/ocab_modules/ocab_modules/standard/command_helper/main.py b/src/ocab_modules/ocab_modules/standard/command_helper/main.py index f7c417e..9fcb5f9 100644 --- a/src/ocab_modules/ocab_modules/standard/command_helper/main.py +++ b/src/ocab_modules/ocab_modules/standard/command_helper/main.py @@ -32,5 +32,11 @@ async def set_user_commands(): ) +def get_user_commands(): + if "USER" in commands: + return commands["USER"].copy() + return {} + + async def module_late_init(): await set_user_commands() diff --git a/src/ocab_modules/ocab_modules/standard/help/__init__.py b/src/ocab_modules/ocab_modules/standard/help/__init__.py new file mode 100644 index 0000000..c8fccb0 --- /dev/null +++ b/src/ocab_modules/ocab_modules/standard/help/__init__.py @@ -0,0 +1 @@ +from .main import module_init diff --git a/src/ocab_modules/ocab_modules/standard/help/info.json b/src/ocab_modules/ocab_modules/standard/help/info.json new file mode 100644 index 0000000..30cbbe6 --- /dev/null +++ b/src/ocab_modules/ocab_modules/standard/help/info.json @@ -0,0 +1,21 @@ +{ + "id": "standard.help", + "name": "Help", + "description": "Модуль для вывода /help сообщения", + "author": "OCAB Team", + "version": "1.0.0", + "privileged": false, + "dependencies": { + "required": { + "standard.config": "^1.0.0" + }, + "optional": { + "standard.command_helper": "^1.0.0" + } + }, + "pythonDependencies": { + "required": { + "string": "*" + } + } +} diff --git a/src/ocab_modules/ocab_modules/standard/help/main.py b/src/ocab_modules/ocab_modules/standard/help/main.py new file mode 100644 index 0000000..6dedb83 --- /dev/null +++ b/src/ocab_modules/ocab_modules/standard/help/main.py @@ -0,0 +1,81 @@ +import string +from typing import TYPE_CHECKING + +from aiogram import Router +from aiogram.filters import Command +from aiogram.types import Message + +from ocab_core.modules_system.public_api import ( + get_metainfo, + get_module, + register_router, +) + +if TYPE_CHECKING: + from ocab_modules.standard.config import IConfig + +config: "IConfig" = get_module("standard.config", "config") + +try: + (register_command, get_user_commands) = get_module( + "standard.command_helper", ["register_command", "get_user_commands"] + ) + COMMAND_HELPER_MODULE_LOADED = True +except Exception: + COMMAND_HELPER_MODULE_LOADED = False + pass + +FOOTER = """=== + +Разработано командой ALT Gnome Infrastructure в рамках проекта Каркас. + +Исходный код: https://gitflic.ru/project/alt-gnome/karkas +Оставить репорт: https://gitflic.ru/project/alt-gnome/karkas/issue/create + +Руководитель проекта: Семен Фомченков +Ведущий разработчик: Максим Слипенко + +Версия: $version +""" + + +def format_commands(commands_dict): + formatted_commands = [] + for command, details in commands_dict.items(): + formatted_commands.append(f"/{command} - {details['description']}") + return "\n".join(formatted_commands) + + +async def help(message: Message): + commands = "" + version = "" + + if COMMAND_HELPER_MODULE_LOADED: + commands = format_commands(get_user_commands()) + + metainfo = get_metainfo() + if "app_version" in metainfo: + version = metainfo["app_version"] + + await message.reply( + string.Template(config.get("help::message") + "\n\n" + FOOTER).substitute( + commands=commands, version=version or "не указана" + ) + ) + + +async def module_init(): + config.register( + "help::message", + "string", + default_value="$commands", + ) + + router = Router() + + router.message.register(help, Command("help")) + + register_router(router) + + if COMMAND_HELPER_MODULE_LOADED: + register_command("help", "Cправка")