diff --git a/src/altlinux/Dockerfile b/src/altlinux/Dockerfile index 6b82f07..287cb3a 100644 --- a/src/altlinux/Dockerfile +++ b/src/altlinux/Dockerfile @@ -4,7 +4,7 @@ RUN pip install poetry RUN mkdir -p /app COPY . /app -# Фикс +# Fix RUN sed -i '/karkas-core = {/{s/, develop = true//}' /app/src/altlinux/pyproject.toml && \ sed -i '/karkas-blocks = {/{s/, develop = true//}' /app/src/altlinux/pyproject.toml && \ diff --git a/src/altlinux/altlinux/__main__.py b/src/altlinux/altlinux/__main__.py index 76a5b6a..c39c7ec 100644 --- a/src/altlinux/altlinux/__main__.py +++ b/src/altlinux/altlinux/__main__.py @@ -7,11 +7,11 @@ from karkas_core import Karkas async def main(): karkas = Karkas() + # Argument `safe` has a value `False` because of `super().__init__()` await karkas.init_app( [ block_loader("standard", "config", safe=False), block_loader("standard", "command_helper"), - # safe=False из-за super().__init__() block_loader("standard", "filters", safe=False), block_loader("standard", "report"), block_loader("standard", "welcome", safe=False), diff --git a/src/gnomik/Dockerfile b/src/gnomik/Dockerfile index e3c7492..102c751 100644 --- a/src/gnomik/Dockerfile +++ b/src/gnomik/Dockerfile @@ -4,7 +4,7 @@ RUN pip install poetry RUN mkdir -p /app COPY . /app -# Фикс +# Fix RUN sed -i '/karkas-core = {/{s/, develop = true//}' /app/src/altlinux/pyproject.toml && \ sed -i '/karkas-blocks = {/{s/, develop = true//}' /app/src/altlinux/pyproject.toml && \ diff --git a/src/gnomik/gnomik/__main__.py b/src/gnomik/gnomik/__main__.py index fd60b62..5a579be 100644 --- a/src/gnomik/gnomik/__main__.py +++ b/src/gnomik/gnomik/__main__.py @@ -20,6 +20,7 @@ async def main(): block_loader("external", "create_report_apps"), block_loader("standard", "info"), block_loader("standard", "help"), + # block_loader("external", "yandexgpt", safe=False), # # block_loader("standard", "admin"), diff --git a/src/karkas_blocks/karkas_blocks/external/yandexgpt/routers.py b/src/karkas_blocks/karkas_blocks/external/yandexgpt/routers.py index 9f61d5f..1e35864 100644 --- a/src/karkas_blocks/karkas_blocks/external/yandexgpt/routers.py +++ b/src/karkas_blocks/karkas_blocks/external/yandexgpt/routers.py @@ -4,7 +4,8 @@ from aiogram import F, Router from .handlers import answer_to_message router = Router() -# Если сообщение содержит в начале текст "Гномик" или "гномик" или отвечает на сообщение бота, то вызывается функция answer_to_message + +# If the message starts with the word "Гномик" ("гномик") or responds to a bot message, `answer_to_message` is called router.message.register( answer_to_message, F.text.startswith("Гномик") | F.text.startswith("гномик") ) diff --git a/src/karkas_blocks/karkas_blocks/external/yandexgpt/yandexgpt.py b/src/karkas_blocks/karkas_blocks/external/yandexgpt/yandexgpt.py index 209a970..d71ec01 100644 --- a/src/karkas_blocks/karkas_blocks/external/yandexgpt/yandexgpt.py +++ b/src/karkas_blocks/karkas_blocks/external/yandexgpt/yandexgpt.py @@ -72,7 +72,7 @@ class YandexGPT: response = await self.async_request( url=url, headers=headers, prompt=request ) - except Exception as e: # TODO: Переделать обработку ошибок + except Exception as e: # TODO: Recreate error handling # print(e) log(f"Error: {e}") @@ -216,17 +216,22 @@ class YandexGPT: self, text, voice, emotion, speed, format, quality ): tts = "tts.api.cloud.yandex.net/speech/v1/tts:synthesize" - # TODO: Сделать функцию TTS + # TODO: Make TTS function return 0 async def async_yandex_cloud_vision(self, image, features, language): - # TODO: Сделать функцию Vision + # TODO: Make Vision function return 0 async def collect_messages(self, message_id, chat_id): + # Collect a chain of messages in the format: + # + # [ + # {"role": "user", "text": ": Hello!"}, + # {"role": "assistant", "text": "Hello!"} + # ] + messages = [] - # Собираем цепочку сообщений в формате: [{"role": "user", "text": "<Имя_пользователя>: Привет!"}, - # {"role": "assistant", "text": "Привет!"}] while True: message = db_api.get_message_text(chat_id, message_id) if db_api.get_message_ai_model(chat_id, message_id) != None: @@ -244,9 +249,14 @@ class YandexGPT: async def collecting_messages_for_history( self, start_message_id, end_message_id, chat_id ): + # Collect a chain of messages in the format: + # + # [ + # {"role": "user", "text": ": Hello!"}, + # {"role": "assistant", "text": "Hello!"} + # ] + messages = [] - # Собираем цепочку сообщений в формате: [{"role": "user", "text": "<Имя_пользователя>: Привет!"}, - # {"role": "assistant", "text": "Привет!"}] while True: message = db_api.get_message_text(chat_id, start_message_id) if db_api.get_message_ai_model(chat_id, start_message_id) != None: diff --git a/src/karkas_blocks/karkas_blocks/standard/admin/handlers.py b/src/karkas_blocks/karkas_blocks/standard/admin/handlers.py index 368cb2b..896dace 100644 --- a/src/karkas_blocks/karkas_blocks/standard/admin/handlers.py +++ b/src/karkas_blocks/karkas_blocks/standard/admin/handlers.py @@ -41,23 +41,23 @@ async def chat_not_in_approve_list(message: Message, bot: Bot): async def mute_user(chat_id: int, user_id: int, time: int, bot: Bot): - # *, can_send_messages: bool | None = None, can_send_audios: bool | None = None, can_send_documents: bool | None = None, can_send_photos: bool | None = None, can_send_videos: bool | None = None, can_send_video_notes: bool | None = None, can_send_voice_notes: bool | None = None, can_send_polls: bool | None = None, can_send_other_messages: bool | None = None, can_add_web_page_previews: bool | None = None, can_change_info: bool | None = None, can_invite_users: bool | None = None, can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, **extra_data: Any) - + # TODO: type variable using `typing` mutePermissions = { - "can_send_messages": False, - "can_send_audios": False, - "can_send_documents": False, - "can_send_photos": False, - "can_send_videos": False, - "can_send_video_notes": False, - "can_send_voice_notes": False, - "can_send_polls": False, - "can_send_other_messages": False, - "can_add_web_page_previews": False, - "can_change_info": False, - "can_invite_users": False, - "can_pin_messages": False, - "can_manage_topics": False, + "can_send_messages": False, # bool | None + "can_send_audios": False, # bool | None + "can_send_documents": False, # bool | None + "can_send_photos": False, # bool | None + "can_send_videos": False, # bool | None + "can_send_video_notes": False, # bool | None + "can_send_voice_notes": False, # bool | None + "can_send_polls": False, # bool | None + "can_send_other_messages": False, # bool | None + "can_add_web_page_previews": False, # bool | None + "can_change_info": False, # bool | None + "can_invite_users": False, # bool | None + "can_pin_messages": False, # bool | None + "can_manage_topics": False, # bool | None + # **extra_data: Any } end_time = time + int(time.time()) await bot.restrict_chat_member( diff --git a/src/karkas_blocks/karkas_blocks/standard/admin/routers.py b/src/karkas_blocks/karkas_blocks/standard/admin/routers.py index 326de75..ae7b1bc 100644 --- a/src/karkas_blocks/karkas_blocks/standard/admin/routers.py +++ b/src/karkas_blocks/karkas_blocks/standard/admin/routers.py @@ -17,7 +17,7 @@ from .handlers import ( router = Router() -# Если сообщение содержит какой либо текст и выполняется фильтр ChatNotInApproveFilter, то вызывается функция chat_not_in_approve_list +# If message is not empty and the `ChatNotInApproveFilter` is applied, then the `chat_not_in_approve_list` function is called router.message.register(chat_not_in_approve_list, ChatNotInApproveFilter(), F.text) router.message.register(get_chat_id, ChatModerOrAdminFilter(), Command("chatID")) diff --git a/src/karkas_blocks/karkas_blocks/standard/config/config_manager.py b/src/karkas_blocks/karkas_blocks/standard/config/config_manager.py index d8951ab..560ef78 100644 --- a/src/karkas_blocks/karkas_blocks/standard/config/config_manager.py +++ b/src/karkas_blocks/karkas_blocks/standard/config/config_manager.py @@ -74,7 +74,7 @@ class ConfigManager: for key, value in updates.items(): self._check_rights(key, module_id, "set") if key in self._metadata: - # TODO: add checks to validate the type and value based on metadata + # TODO: add metadata-based type and value validation self._config[key] = value else: raise KeyError(f"Key {key} is not registered.") diff --git a/src/karkas_blocks/karkas_blocks/standard/config/miniapp_ui.py b/src/karkas_blocks/karkas_blocks/standard/config/miniapp_ui.py index 420bd8f..8d73e01 100644 --- a/src/karkas_blocks/karkas_blocks/standard/config/miniapp_ui.py +++ b/src/karkas_blocks/karkas_blocks/standard/config/miniapp_ui.py @@ -206,7 +206,7 @@ def get_miniapp_blueprint(config: "ConfigManager", prefix: str): "-", ) - # TODO: добавить валидацию значений + # TODO: add values validation updated_settings = {} for value, id_dict in zip(values, keys): @@ -217,7 +217,8 @@ def get_miniapp_blueprint(config: "ConfigManager", prefix: str): meta = config.get_meta(key) if meta["type"] == "password": - if value: # Only update if a new value is provided + # Is updated only if new value is specified + if value: updated_settings[key] = value else: updated_settings[key] = value diff --git a/src/karkas_blocks/karkas_blocks/standard/filters/filters.py b/src/karkas_blocks/karkas_blocks/standard/filters/filters.py index 4cdd5e4..4ab3f04 100644 --- a/src/karkas_blocks/karkas_blocks/standard/filters/filters.py +++ b/src/karkas_blocks/karkas_blocks/standard/filters/filters.py @@ -94,7 +94,7 @@ class ChatIDFilter(BaseFilter): approved_chats = self.approved_chats or get_approved_chat_id() - # Если список для фильтрации пуст - разрешаем всем. + # If filtering list is empty, allow anything if len(approved_chats) == 0: return True diff --git a/src/karkas_blocks/karkas_blocks/standard/help/main.py b/src/karkas_blocks/karkas_blocks/standard/help/main.py index 5299298..a049c0f 100644 --- a/src/karkas_blocks/karkas_blocks/standard/help/main.py +++ b/src/karkas_blocks/karkas_blocks/standard/help/main.py @@ -26,8 +26,6 @@ except Exception: COMMAND_HELPER_MODULE_LOADED = False pass -# Уважительная просьба не удалять и не изменять нижеизложенный текст -# без согласия команды проекта «Каркас». # We kindly ask you not to delete or change the following text without # the consent of the «Karkas» project team. FOOTER = """=============== diff --git a/src/karkas_blocks/karkas_blocks/standard/info/handlers.py b/src/karkas_blocks/karkas_blocks/standard/info/handlers.py index ef76a33..d5e3f71 100644 --- a/src/karkas_blocks/karkas_blocks/standard/info/handlers.py +++ b/src/karkas_blocks/karkas_blocks/standard/info/handlers.py @@ -28,9 +28,6 @@ async def get_info_answer_by_id(message: Message, bot: Bot, user_id: int): async def get_user_info(message: Message, bot: Bot): - # Проверяем содержимое сообщения, если содержит вторым элементом тег пользователя, то выводим информацию о нем - # Если сообщение отвечает на другое сообщение, то выводим информацию о пользователе, на чье сообщение был ответ - # Если это бот то выводим информацию, что это бот и какая модель yandexgpt используется try: if message.reply_to_message: user_id = message.reply_to_message.from_user.id diff --git a/src/karkas_blocks/karkas_blocks/standard/miniapp/dash_telegram_auth.py b/src/karkas_blocks/karkas_blocks/standard/miniapp/dash_telegram_auth.py index 3e84cb7..4fcda97 100644 --- a/src/karkas_blocks/karkas_blocks/standard/miniapp/dash_telegram_auth.py +++ b/src/karkas_blocks/karkas_blocks/standard/miniapp/dash_telegram_auth.py @@ -8,7 +8,7 @@ from flask import request if TYPE_CHECKING: from dash import Dash -# TODO: добавить прокидывание BASE_PATH, т.к. это параметр из настроек +# TODO: add `BASE_PATH` transfer, because this is a parameter from the settings WEBAPP_LOADER_TEMPLATE = """ diff --git a/src/karkas_blocks/karkas_blocks/standard/miniapp/lib.py b/src/karkas_blocks/karkas_blocks/standard/miniapp/lib.py index b14d14d..b518945 100644 --- a/src/karkas_blocks/karkas_blocks/standard/miniapp/lib.py +++ b/src/karkas_blocks/karkas_blocks/standard/miniapp/lib.py @@ -56,7 +56,6 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash: dbc.icons.BOOTSTRAP, ], external_scripts=[ - # "https://telegram.org/js/telegram-web-app.js" ], server=server, @@ -156,7 +155,7 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash: setup_auth_clientcallbacks(app) - # Открытие на кнопку меню + # Open on the menu button app.clientside_callback( """ function(n_clicks) { @@ -173,7 +172,7 @@ def create_dash_app(requests_pathname_prefix: str = None) -> dash.Dash: Input("open-offcanvas", "n_clicks"), ) - # Закрываем offcanvas при клике на ссылку в меню + # Closing `offcanvas` when clicking on the link in the menu app.clientside_callback( """ function(n_clicks) { diff --git a/src/karkas_blocks/karkas_blocks/standard/roles/tests/test_roles.py b/src/karkas_blocks/karkas_blocks/standard/roles/tests/test_roles.py index 4828306..4ddf83a 100644 --- a/src/karkas_blocks/karkas_blocks/standard/roles/tests/test_roles.py +++ b/src/karkas_blocks/karkas_blocks/standard/roles/tests/test_roles.py @@ -67,8 +67,10 @@ class TestRoles(unittest.IsolatedAsyncioTestCase): ) cls.assertEqual(await cls.roles.get_role_name(cls.roles.user_role_id), "USER") cls.assertEqual(await cls.roles.get_role_name(cls.roles.bot_role_id), "BOT") + + # Non-existent role ID with cls.assertRaises(ValueError): - await cls.roles.get_role_name(999) # Несуществующий ID роли + await cls.roles.get_role_name(999) @classmethod def tearDownClass(cls): diff --git a/src/karkas_blocks/karkas_blocks/standard/statistics/db/tables.py b/src/karkas_blocks/karkas_blocks/standard/statistics/db/tables.py index dc73184..d8a7b7d 100644 --- a/src/karkas_blocks/karkas_blocks/standard/statistics/db/tables.py +++ b/src/karkas_blocks/karkas_blocks/standard/statistics/db/tables.py @@ -9,9 +9,8 @@ class ChatStats(Table): class Messages(Table): - # Временная мера, пока не примут - # https://github.com/piccolo-orm/piccolo/pull/984 - # {message_chat_id}-{message_id} + # Key format: `{message_chat_id}-{message_id}` + # (A temporary measure until https://github.com/piccolo-orm/piccolo/pull/984 is accepted) key = Text(primary_key=True) chat_id = Integer() @@ -23,9 +22,8 @@ class Messages(Table): class UserStats(Table): - # Временная мера, пока не примут - # https://github.com/piccolo-orm/piccolo/pull/984 - # {chat_id}-{user_id} + # Key format: `{chat_id}-{user_id}` + # (A temporary measure until https://github.com/piccolo-orm/piccolo/pull/984 is accepted) key = Text(primary_key=True) chat_id = Integer() diff --git a/src/karkas_blocks/karkas_blocks/standard/welcome/main.py b/src/karkas_blocks/karkas_blocks/standard/welcome/main.py index 2f4acba..98fdec7 100644 --- a/src/karkas_blocks/karkas_blocks/standard/welcome/main.py +++ b/src/karkas_blocks/karkas_blocks/standard/welcome/main.py @@ -80,7 +80,7 @@ last_success = {} async def new_member_handler(event: "ChatMemberUpdated", bot: Bot): - # НЕ СРАБОТАЕТ, ЕСЛИ ЧЕЛОВЕК УЖЕ ОГРАНИЧЕН В ПРАВАХ (RESTRICTED) + # WARN: IT WON'T WORK IF THE PERSON IS ALREADY RESTRICTED if event.new_chat_member.status == ChatMemberStatus.MEMBER: task = task_manager.build_random_task(event, bot) keys = await task.run() @@ -353,7 +353,7 @@ async def module_init(): handle_inline_button_verification ) - # Нельзя применить ChatIDFilter из-за отстутсвия id чата + # ChatIDFilter can't be applied because there is no chat ID router.poll_answer()(handle_poll_verification) register_router(router) diff --git a/src/karkas_blocks/karkas_blocks/standard/welcome/utils.py b/src/karkas_blocks/karkas_blocks/standard/welcome/utils.py index 86ec5e9..6aeeb91 100644 --- a/src/karkas_blocks/karkas_blocks/standard/welcome/utils.py +++ b/src/karkas_blocks/karkas_blocks/standard/welcome/utils.py @@ -1,3 +1,4 @@ +# TODO: rewrite for compatibility with English def get_plural_form(number, singular, genitive_singular, plural): if 11 <= number % 100 <= 19: return f"{number} {plural}" @@ -11,14 +12,12 @@ def get_plural_form(number, singular, genitive_singular, plural): class MultiKeyDict: def __init__(self): - self.value_to_keys = {} # Словарь значений и связанных с ними ключей - self.key_to_value = {} # Словарь ключей и связанных с ними значений + self.value_to_keys = {} + self.key_to_value = {} def add(self, value, keys): - # Добавляем значение в словарь с множеством ключей self.value_to_keys[value] = set(keys) - # Для каждого ключа создаем запись в словаре key_to_value for key in keys: self.key_to_value[key] = value diff --git a/src/karkas_core/karkas_core/modules_system/loaders/unsafe_fs_loader/UnsafeFSLoader.py b/src/karkas_core/karkas_core/modules_system/loaders/unsafe_fs_loader/UnsafeFSLoader.py index 37f790e..148122f 100644 --- a/src/karkas_core/karkas_core/modules_system/loaders/unsafe_fs_loader/UnsafeFSLoader.py +++ b/src/karkas_core/karkas_core/modules_system/loaders/unsafe_fs_loader/UnsafeFSLoader.py @@ -39,6 +39,7 @@ class UnsafeFSLoader(AbstractLoader): full_path = self._resolve_module_from_path(".") + # TODO: remove duplication if full_path.name == "__init__.py": module_name = full_path.parent.name path = full_path.parent.parent.absolute() @@ -46,16 +47,12 @@ class UnsafeFSLoader(AbstractLoader): module_name = full_path.stem path = full_path.parent.absolute() - # Добавляем директорию модуля в sys.path sys.path.insert(0, str(path)) - # Загружаем спецификацию модуля spec = importlib.util.spec_from_file_location(module_name, full_path) - # Создаем модуль module = importlib.util.module_from_spec(spec) - # Выполняем модуль spec.loader.exec_module(module) return module diff --git a/src/karkas_core/karkas_core/modules_system/modules_manager.py b/src/karkas_core/karkas_core/modules_system/modules_manager.py index e0ec9e6..25a74d6 100644 --- a/src/karkas_core/karkas_core/modules_system/modules_manager.py +++ b/src/karkas_core/karkas_core/modules_system/modules_manager.py @@ -93,7 +93,7 @@ class ModulesManager: async def load(self, loader: AbstractLoader): info = loader.info() - # Check if the module is already loaded + # Is the module loaded if any(mod["info"].id == info.id for mod in self.modules): return diff --git a/src/karkas_piccolo/karkas_piccolo/patches/cli/finder.py b/src/karkas_piccolo/karkas_piccolo/patches/cli/finder.py index 0063187..dbdf095 100644 --- a/src/karkas_piccolo/karkas_piccolo/patches/cli/finder.py +++ b/src/karkas_piccolo/karkas_piccolo/patches/cli/finder.py @@ -48,13 +48,10 @@ class UnsafeFSLoader: sys.path.insert(0, str(path)) - # Загружаем спецификацию модуля spec = importlib.util.spec_from_file_location(module_name, full_path) - # Создаем модуль module = importlib.util.module_from_spec(spec) - # Выполняем модуль spec.loader.exec_module(module) return module