mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-03-05 05:13:21 +00:00
fix: address code review issues in guide mode rework
- Add fallback else branch for subscriptionLink in blocks format (prevents silent button drop when deep link resolution fails) - Extract render_guide_blocks() helper to eliminate duplicated block-rendering logic between handle_device_guide and handle_specific_app_guide - Add HTML escaping for admin-controlled config text in guide blocks - Remove unused get_localized_value import from devices.py
This commit is contained in:
@@ -26,6 +26,7 @@ from .common import (
|
||||
load_app_config,
|
||||
load_app_config_async,
|
||||
normalize_app,
|
||||
render_guide_blocks,
|
||||
resolve_button_url,
|
||||
update_traffic_prices,
|
||||
validate_traffic_price,
|
||||
@@ -190,6 +191,7 @@ __all__ = [
|
||||
'normalize_app',
|
||||
'refresh_traffic_config',
|
||||
'register_handlers',
|
||||
'render_guide_blocks',
|
||||
'resolve_button_url',
|
||||
'resume_subscription_checkout',
|
||||
'return_to_saved_cart',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
import base64
|
||||
import html as html_mod
|
||||
import json
|
||||
import time
|
||||
from datetime import datetime
|
||||
@@ -241,6 +242,31 @@ def format_additional_section(additional: Any, texts, language: str) -> str:
|
||||
return '\n'.join(parts)
|
||||
|
||||
|
||||
def render_guide_blocks(blocks: list[dict], language: str) -> str:
|
||||
"""Render block-format guide steps to HTML text."""
|
||||
parts: list[str] = []
|
||||
step_num = 1
|
||||
for block in blocks:
|
||||
if not isinstance(block, dict):
|
||||
continue
|
||||
title = block.get('title', {})
|
||||
desc = block.get('description', {})
|
||||
title_text = html_mod.escape(
|
||||
get_localized_value(title, language) if isinstance(title, dict) else str(title or '')
|
||||
)
|
||||
desc_text = html_mod.escape(get_localized_value(desc, language) if isinstance(desc, dict) else str(desc or ''))
|
||||
if title_text or desc_text:
|
||||
step = f'<b>Шаг {step_num}'
|
||||
if title_text:
|
||||
step += f' - {title_text}'
|
||||
step += ':</b>'
|
||||
if desc_text:
|
||||
step += f'\n{desc_text}'
|
||||
parts.append(step)
|
||||
step_num += 1
|
||||
return '\n\n'.join(parts)
|
||||
|
||||
|
||||
def build_redirect_link(target_link: str | None, template: str | None) -> str | None:
|
||||
if not target_link or not template:
|
||||
return None
|
||||
|
||||
@@ -40,9 +40,9 @@ from .common import (
|
||||
get_apps_for_device,
|
||||
get_apps_for_platform_async,
|
||||
get_device_name,
|
||||
get_localized_value,
|
||||
get_step_description,
|
||||
logger,
|
||||
render_guide_blocks,
|
||||
)
|
||||
from .countries import _get_available_countries
|
||||
|
||||
@@ -1345,24 +1345,9 @@ async def handle_device_guide(callback: types.CallbackQuery, db_user: User, db:
|
||||
)
|
||||
|
||||
if is_blocks_format:
|
||||
# Build guide text from blocks
|
||||
step_num = 1
|
||||
for block in featured_app.get('blocks', []):
|
||||
if not isinstance(block, dict):
|
||||
continue
|
||||
title = block.get('title', {})
|
||||
desc = block.get('description', {})
|
||||
title_text = get_localized_value(title, db_user.language) if isinstance(title, dict) else str(title or '')
|
||||
desc_text = get_localized_value(desc, db_user.language) if isinstance(desc, dict) else str(desc or '')
|
||||
|
||||
if title_text or desc_text:
|
||||
guide_text += f'\n\n<b>Шаг {step_num}'
|
||||
if title_text:
|
||||
guide_text += f' - {title_text}'
|
||||
guide_text += ':</b>'
|
||||
if desc_text:
|
||||
guide_text += f'\n{desc_text}'
|
||||
step_num += 1
|
||||
blocks_text = render_guide_blocks(featured_app.get('blocks', []), db_user.language)
|
||||
if blocks_text:
|
||||
guide_text += '\n\n' + blocks_text
|
||||
else:
|
||||
# Legacy steps
|
||||
installation_description = get_step_description(
|
||||
@@ -1546,25 +1531,9 @@ async def handle_specific_app_guide(callback: types.CallbackQuery, db_user: User
|
||||
)
|
||||
|
||||
if is_blocks_format:
|
||||
# Build guide from blocks
|
||||
step_num = 1
|
||||
for block in app.get('blocks', []):
|
||||
if not isinstance(block, dict):
|
||||
continue
|
||||
title = block.get('title', {})
|
||||
desc = block.get('description', {})
|
||||
title_text = get_localized_value(title, db_user.language) if isinstance(title, dict) else str(title or '')
|
||||
desc_text = get_localized_value(desc, db_user.language) if isinstance(desc, dict) else str(desc or '')
|
||||
|
||||
if title_text or desc_text:
|
||||
guide_text += f'<b>Шаг {step_num}'
|
||||
if title_text:
|
||||
guide_text += f' - {title_text}'
|
||||
guide_text += ':</b>'
|
||||
if desc_text:
|
||||
guide_text += f'\n{desc_text}'
|
||||
guide_text += '\n\n'
|
||||
step_num += 1
|
||||
blocks_text = render_guide_blocks(app.get('blocks', []), db_user.language)
|
||||
if blocks_text:
|
||||
guide_text += blocks_text + '\n\n'
|
||||
else:
|
||||
raw_app = app.get('_raw', app)
|
||||
installation_description = get_step_description(raw_app, 'installationStep', db_user.language)
|
||||
|
||||
@@ -2437,6 +2437,17 @@ def get_connection_guide_keyboard(
|
||||
)
|
||||
]
|
||||
)
|
||||
else:
|
||||
# Fallback: use raw subscription URL
|
||||
keyboard.append(
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text=texts.t('CONNECT_BUTTON', '🔗 Подключиться'),
|
||||
url=subscription_url,
|
||||
style='success',
|
||||
)
|
||||
]
|
||||
)
|
||||
elif btn_type == 'copyButton':
|
||||
url = resolved_url or resolve_button_url(btn_url, subscription_url)
|
||||
if url:
|
||||
|
||||
Reference in New Issue
Block a user