From 472a099a8f64261cf5338ee8a591bcef87673503 Mon Sep 17 00:00:00 2001 From: Vladless Date: Wed, 11 Feb 2026 03:40:01 +0300 Subject: [PATCH] ruff format --- api/routes/partners.py | 58 +++++----- filters/admin.py | 4 +- handlers/admin/panel/keyboard.py | 50 ++++---- handlers/keys/key_mode/key_cluster_mode.py | 4 +- middlewares/session.py | 1 + utils/button_icons.py | 8 ++ utils/custom_emojis.py | 127 +++++++-------------- utils/modules_loader.py | 1 + 8 files changed, 114 insertions(+), 139 deletions(-) diff --git a/api/routes/partners.py b/api/routes/partners.py index 13f46e80..05b23884 100644 --- a/api/routes/partners.py +++ b/api/routes/partners.py @@ -113,16 +113,14 @@ async def get_all_partners( else: percent = float(default_percent) - partners_list.append( - { - "tg_id": int(partner[0]), - "balance": float(partner[1] or 0), - "percent": percent, - "code": partner[4] or None, - "method": partner[5] or None, - "referred_count": int(partner[6] or 0), - } - ) + partners_list.append({ + "tg_id": int(partner[0]), + "balance": float(partner[1] or 0), + "percent": percent, + "code": partner[4] or None, + "method": partner[5] or None, + "referred_count": int(partner[6] or 0), + }) return JSONResponse(content={"total": total, "items": partners_list}) @@ -651,17 +649,15 @@ async def get_partner_payouts_pending( result = await session.execute(rows_sql, params) items = [] for row in result.fetchall(): - items.append( - { - "id": int(row[0]), - "tg_id": int(row[1]), - "amount": float(row[2] or 0.0), - "status": row[3] or "pending", - "created_at": _row_dt_iso(row[4]), - "method": row[5] or None, - "destination": row[6] or None, - } - ) + items.append({ + "id": int(row[0]), + "tg_id": int(row[1]), + "amount": float(row[2] or 0.0), + "status": row[3] or "pending", + "created_at": _row_dt_iso(row[4]), + "method": row[5] or None, + "destination": row[6] or None, + }) return JSONResponse(content={"total": int(total), "items": items}) @@ -705,17 +701,15 @@ async def get_partner_payouts_history( result = await session.execute(rows_sql, params) items = [] for row in result.fetchall(): - items.append( - { - "id": int(row[0]), - "tg_id": int(row[1]), - "amount": float(row[2] or 0.0), - "status": row[3] or "—", - "created_at": _row_dt_iso(row[4]), - "method": row[5] or None, - "destination": row[6] or None, - } - ) + items.append({ + "id": int(row[0]), + "tg_id": int(row[1]), + "amount": float(row[2] or 0.0), + "status": row[3] or "—", + "created_at": _row_dt_iso(row[4]), + "method": row[5] or None, + "destination": row[6] or None, + }) return JSONResponse(content={"total": int(total), "items": items}) diff --git a/filters/admin.py b/filters/admin.py index cf584061..5daba74d 100644 --- a/filters/admin.py +++ b/filters/admin.py @@ -27,9 +27,7 @@ class IsSuperAdminFilter(BaseFilter): try: async with async_session_maker() as session: admin = ( - await session.execute( - select(Admin).where(Admin.tg_id == event.from_user.id) - ) + await session.execute(select(Admin).where(Admin.tg_id == event.from_user.id)) ).scalar_one_or_none() if not admin: return False diff --git a/handlers/admin/panel/keyboard.py b/handlers/admin/panel/keyboard.py index 100e1809..43f3cf50 100644 --- a/handlers/admin/panel/keyboard.py +++ b/handlers/admin/panel/keyboard.py @@ -36,18 +36,24 @@ async def build_panel_kb(admin_role: str) -> InlineKeyboardMarkup: ) if is_super: - builder.row(InlineKeyboardButton( - text="🖥️ Управление серверами", - callback_data=AdminPanelCallback(action="clusters").pack(), - )) - builder.row(InlineKeyboardButton( - text="💸Управление тарифами", - callback_data=AdminPanelCallback(action="tariffs").pack(), - )) - builder.row(InlineKeyboardButton( - text="🤖 Управление ботом", - callback_data=AdminPanelCallback(action="management").pack(), - )) + builder.row( + InlineKeyboardButton( + text="🖥️ Управление серверами", + callback_data=AdminPanelCallback(action="clusters").pack(), + ) + ) + builder.row( + InlineKeyboardButton( + text="💸Управление тарифами", + callback_data=AdminPanelCallback(action="tariffs").pack(), + ) + ) + builder.row( + InlineKeyboardButton( + text="🤖 Управление ботом", + callback_data=AdminPanelCallback(action="management").pack(), + ) + ) builder.row( InlineKeyboardButton( @@ -82,19 +88,23 @@ async def build_panel_kb(admin_role: str) -> InlineKeyboardMarkup: ), ) else: - builder.row(InlineKeyboardButton( - text="🎁 Подарки", - callback_data=AdminPanelCallback(action="gifts").pack(), - )) + builder.row( + InlineKeyboardButton( + text="🎁 Подарки", + callback_data=AdminPanelCallback(action="gifts").pack(), + ) + ) module_buttons = await run_hooks("admin_panel", admin_role=admin_role) builder = insert_hook_buttons(builder, module_buttons) if not is_moderator: - builder.row(InlineKeyboardButton( - text="⚙️ Настройки", - callback_data=AdminPanelCallback(action="settings").pack(), - )) + builder.row( + InlineKeyboardButton( + text="⚙️ Настройки", + callback_data=AdminPanelCallback(action="settings").pack(), + ) + ) builder.row(InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")) diff --git a/handlers/keys/key_mode/key_cluster_mode.py b/handlers/keys/key_mode/key_cluster_mode.py index 81376019..c7c32408 100644 --- a/handlers/keys/key_mode/key_cluster_mode.py +++ b/handlers/keys/key_mode/key_cluster_mode.py @@ -216,7 +216,9 @@ async def key_cluster_mode( else: if await is_full_remnawave_cluster(least_loaded_cluster, session): use_webapp = bool(MODES_CONFIG.get("REMNAWAVE_WEBAPP_ENABLED", REMNAWAVE_WEBAPP)) - open_in_browser = bool(MODES_CONFIG.get("REMNAWAVE_WEBAPP_OPEN_IN_BROWSER", REMNAWAVE_WEBAPP_OPEN_IN_BROWSER)) + open_in_browser = bool( + MODES_CONFIG.get("REMNAWAVE_WEBAPP_OPEN_IN_BROWSER", REMNAWAVE_WEBAPP_OPEN_IN_BROWSER) + ) if use_webapp and final_link: use_webapp = await process_remnawave_webapp_override( remnawave_webapp=use_webapp, diff --git a/middlewares/session.py b/middlewares/session.py index 427cad24..741aecf3 100644 --- a/middlewares/session.py +++ b/middlewares/session.py @@ -1,5 +1,6 @@ from aiogram import BaseMiddleware + class SessionMiddleware(BaseMiddleware): def __init__(self, sessionmaker): self.sessionmaker = sessionmaker diff --git a/utils/button_icons.py b/utils/button_icons.py index 459291a7..3bbd552f 100644 --- a/utils/button_icons.py +++ b/utils/button_icons.py @@ -1,6 +1,14 @@ from __future__ import annotations import aiogram.types +from pydantic import ConfigDict + + +_UniqueGiftColors = getattr(aiogram.types, "UniqueGiftColors", None) +if _UniqueGiftColors is not None: + _cfg = getattr(_UniqueGiftColors, "model_config", None) + _base = dict(_cfg) if _cfg is not None else {} + _UniqueGiftColors.model_config = ConfigDict(**_base, protected_namespaces=()) _OriginalInlineKeyboardButton = aiogram.types.InlineKeyboardButton diff --git a/utils/custom_emojis.py b/utils/custom_emojis.py index 8429b080..30f34534 100644 --- a/utils/custom_emojis.py +++ b/utils/custom_emojis.py @@ -283,9 +283,7 @@ def patch_bot_methods() -> bool: _set_parse_mode_none(kwargs) return await self._original_answer(text=processed, entities=merged, **kwargs) - async def patched_edit_text( - self, text: str, entities: list[MessageEntity] | None = None, **kwargs - ): + async def patched_edit_text(self, text: str, entities: list[MessageEntity] | None = None, **kwargs): processed, merged = await _process_text(text, entities) if merged: _set_parse_mode_none(kwargs) @@ -298,15 +296,11 @@ def patch_bot_methods() -> bool: **kwargs, ): if not caption: - return await self._original_edit_caption( - caption=caption, caption_entities=caption_entities, **kwargs - ) + return await self._original_edit_caption(caption=caption, caption_entities=caption_entities, **kwargs) processed, merged = await _process_text(caption, caption_entities) if merged: _set_parse_mode_none(kwargs) - return await self._original_edit_caption( - caption=processed, caption_entities=merged, **kwargs - ) + return await self._original_edit_caption(caption=processed, caption_entities=merged, **kwargs) async def patched_answer_photo( self, @@ -322,9 +316,7 @@ def patch_bot_methods() -> bool: processed, merged = await _process_text(caption, caption_entities) if merged: _set_parse_mode_none(kwargs) - return await self._original_answer_photo( - photo=photo, caption=processed, caption_entities=merged, **kwargs - ) + return await self._original_answer_photo(photo=photo, caption=processed, caption_entities=merged, **kwargs) async def patched_answer_video( self, @@ -340,9 +332,7 @@ def patch_bot_methods() -> bool: processed, merged = await _process_text(caption, caption_entities) if merged: _set_parse_mode_none(kwargs) - return await self._original_answer_video( - video=video, caption=processed, caption_entities=merged, **kwargs - ) + return await self._original_answer_video(video=video, caption=processed, caption_entities=merged, **kwargs) async def patched_answer_animation( self, @@ -370,9 +360,7 @@ def patch_bot_methods() -> bool: async def patched_edit_media(self, media: Any, **kwargs): if hasattr(media, "caption") and media.caption: - processed, merged = await _process_text( - media.caption, getattr(media, "caption_entities", None) - ) + processed, merged = await _process_text(media.caption, getattr(media, "caption_entities", None)) media.caption = processed if merged: if hasattr(media, "parse_mode"): @@ -402,6 +390,8 @@ def initialize_custom_emojis() -> bool: except Exception as e: logger.error(f"[CustomEmojis] Init failed: {e}", exc_info=True) return False + + """ Support custom Telegram emojis in bot texts. Allows writing custom emoji IDs in texts via a special syntax. @@ -502,15 +492,13 @@ def _parse_html_entities(text: str) -> list[MessageEntity]: for open_pattern, close_pattern in link_patterns: for open_match in re.finditer(open_pattern, text): url = open_match.group(1) - link_tags.append( - { - "type": "open", - "url": url, - "open_start": open_match.start(), - "open_end": open_match.end(), - "close_pattern": close_pattern, - } - ) + link_tags.append({ + "type": "open", + "url": url, + "open_start": open_match.start(), + "open_end": open_match.end(), + "close_pattern": close_pattern, + }) for close_match in re.finditer(r"", text): link_tags.append({"type": "close", "pos": close_match.start()}) @@ -530,15 +518,13 @@ def _parse_html_entities(text: str) -> list[MessageEntity]: close_pos = tag["pos"] content = text[open_pos:close_pos] - tag_positions.append( - { - "open_pos": open_pos, - "close_pos": close_pos, - "content": content, - "entity_type": "text_link", - "url": matching_open["url"], - } - ) + tag_positions.append({ + "open_pos": open_pos, + "close_pos": close_pos, + "content": content, + "entity_type": "text_link", + "url": matching_open["url"], + }) other_patterns = [ (r"", r"", "bold"), @@ -558,19 +544,15 @@ def _parse_html_entities(text: str) -> list[MessageEntity]: other_tags = [] for open_pattern, close_pattern, entity_type in other_patterns: for open_match in re.finditer(open_pattern, text): - other_tags.append( - { - "type": "open", - "entity_type": entity_type, - "open_end": open_match.end(), - "close_pattern": close_pattern, - } - ) + other_tags.append({ + "type": "open", + "entity_type": entity_type, + "open_end": open_match.end(), + "close_pattern": close_pattern, + }) for close_match in re.finditer(close_pattern, text): - other_tags.append( - {"type": "close", "entity_type": entity_type, "pos": close_match.start()} - ) + other_tags.append({"type": "close", "entity_type": entity_type, "pos": close_match.start()}) other_tags.sort(key=lambda x: x.get("open_end", x.get("pos", 0))) @@ -590,15 +572,13 @@ def _parse_html_entities(text: str) -> list[MessageEntity]: close_pos = tag["pos"] content = text[open_pos:close_pos] - tag_positions.append( - { - "open_pos": open_pos, - "close_pos": close_pos, - "content": content, - "entity_type": entity_type, - "url": None, - } - ) + tag_positions.append({ + "open_pos": open_pos, + "close_pos": close_pos, + "content": content, + "entity_type": entity_type, + "url": None, + }) tag_positions.sort(key=lambda x: x["open_pos"]) @@ -678,10 +658,7 @@ def patch_bot_methods() -> bool: while html_pos < len(processed_text_with_html): if processed_text_with_html[html_pos] == "<": - while ( - html_pos < len(processed_text_with_html) - and processed_text_with_html[html_pos] != ">" - ): + while html_pos < len(processed_text_with_html) and processed_text_with_html[html_pos] != ">": char = processed_text_with_html[html_pos] char_utf16_len = _get_utf16_length(char) for i in range(char_utf16_len): @@ -718,11 +695,7 @@ def patch_bot_methods() -> bool: else: break - return ( - utf16_offset_map[best_match] - if best_match is not None - else entity_offset_utf16 - ) + return utf16_offset_map[best_match] if best_match is not None else entity_offset_utf16 html_entities = [] for entity in html_entities_with_html: @@ -757,31 +730,21 @@ def patch_bot_methods() -> bool: return text, entities - async def patched_message_answer( - self, text: str, entities: list[MessageEntity] | None = None, **kwargs - ): + async def patched_message_answer(self, text: str, entities: list[MessageEntity] | None = None, **kwargs): """Patched Message.answer.""" - processed_text, final_entities = await process_text_and_entities( - text, entities, kwargs.get("parse_mode") - ) + processed_text, final_entities = await process_text_and_entities(text, entities, kwargs.get("parse_mode")) if final_entities: kwargs["parse_mode"] = None return await self._original_answer( text=processed_text, entities=final_entities if final_entities else None, **kwargs ) - async def patched_message_edit_text( - self, text: str, entities: list[MessageEntity] | None = None, **kwargs - ): + async def patched_message_edit_text(self, text: str, entities: list[MessageEntity] | None = None, **kwargs): """Patched Message.edit_text.""" - processed_text, final_entities = await process_text_and_entities( - text, entities, kwargs.get("parse_mode") - ) + processed_text, final_entities = await process_text_and_entities(text, entities, kwargs.get("parse_mode")) if final_entities: kwargs["parse_mode"] = None - return await self._original_edit_text( - text=processed_text, entities=final_entities, **kwargs - ) + return await self._original_edit_text(text=processed_text, entities=final_entities, **kwargs) async def patched_message_edit_caption( self, @@ -791,9 +754,7 @@ def patch_bot_methods() -> bool: ): """Patched Message.edit_caption.""" if not caption: - return await self._original_edit_caption( - caption=caption, caption_entities=caption_entities, **kwargs - ) + return await self._original_edit_caption(caption=caption, caption_entities=caption_entities, **kwargs) processed_caption, final_entities = await process_text_and_entities( caption, caption_entities, kwargs.get("parse_mode") ) diff --git a/utils/modules_loader.py b/utils/modules_loader.py index ecd0014e..91adb56e 100644 --- a/utils/modules_loader.py +++ b/utils/modules_loader.py @@ -12,6 +12,7 @@ from .modules_manager import manager modules_hub = Router(name="modules_hub") + def _is_safe_module_name(name: str) -> bool: return bool(name and name.isidentifier() and "." not in name and "/" not in name and "\\" not in name)