Правки проблем
This commit is contained in:
@@ -6,7 +6,7 @@ from html import escape
|
||||
from uuid import uuid4
|
||||
|
||||
from aiogram import F, Router
|
||||
from aiogram.exceptions import TelegramBadRequest
|
||||
from aiogram.exceptions import TelegramBadRequest, TelegramRetryAfter
|
||||
from aiogram.filters import Command
|
||||
from aiogram.types import CallbackQuery, Message
|
||||
|
||||
@@ -281,6 +281,72 @@ def _admin_guide_text() -> str:
|
||||
)
|
||||
|
||||
|
||||
def _admin_hint_text(section: str, target: str | None = None) -> str:
|
||||
hints = {
|
||||
"sync": "\n".join(
|
||||
[
|
||||
"<b>Что такое синхронизация</b>",
|
||||
"",
|
||||
"Синхронизация подтягивает актуальные issues из GlitchTip в локальный кэш бота.",
|
||||
"Ручной sync нужен, когда вы хотите обновить данные "
|
||||
"прямо сейчас, не дожидаясь расписания.",
|
||||
]
|
||||
),
|
||||
"recipients": "\n".join(
|
||||
[
|
||||
"<b>Что такое получатели</b>",
|
||||
"",
|
||||
"Получатели — это Telegram ID пользователей, которым бот отправляет уведомления.",
|
||||
"Backend и frontend настраиваются отдельно.",
|
||||
]
|
||||
),
|
||||
"routing": "\n".join(
|
||||
[
|
||||
"<b>Что такое Topic и routing</b>",
|
||||
"",
|
||||
"Routing определяет, в какую группу попадает проект.",
|
||||
"Topic override определяет, в какую тему Telegram будут "
|
||||
"приходить сообщения для backend, frontend и digest.",
|
||||
]
|
||||
),
|
||||
"settings": "\n".join(
|
||||
[
|
||||
"<b>Что такое настройки бота</b>",
|
||||
"",
|
||||
"Здесь собраны runtime-параметры, которые можно менять "
|
||||
"без правки `.env` и без пересборки контейнера.",
|
||||
"Сюда входят автосинк, расписание digest и тексты интерфейса.",
|
||||
]
|
||||
),
|
||||
"mute": "\n".join(
|
||||
[
|
||||
"<b>Что такое mute rules</b>",
|
||||
"",
|
||||
"Mute rule — это шаблон, по которому бот скрывает шумные или неважные события.",
|
||||
"Если событие совпало с правилом, оно не будет мешать в уведомлениях.",
|
||||
]
|
||||
),
|
||||
"admins": "\n".join(
|
||||
[
|
||||
"<b>Что такое администраторы</b>",
|
||||
"",
|
||||
"Администраторы могут менять настройки бота, получателей и расписание.",
|
||||
"Часть админов может приходить из `.env`, а часть хранится в runtime-базе.",
|
||||
]
|
||||
),
|
||||
"recipient_group": "\n".join(
|
||||
[
|
||||
f"<b>{escape((target or '').capitalize())} получатели</b>",
|
||||
"",
|
||||
"Добавляйте сюда Telegram ID тех, кто должен получать "
|
||||
"уведомления по выбранной группе.",
|
||||
"Удаление отсюда прекращает доставку уведомлений этому пользователю.",
|
||||
]
|
||||
),
|
||||
}
|
||||
return hints[section]
|
||||
|
||||
|
||||
def _sync_summary_text(summary) -> str:
|
||||
return "\n".join(
|
||||
[
|
||||
@@ -405,6 +471,18 @@ async def _show_callback_screen(
|
||||
reply_markup=reply_markup,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
)
|
||||
except TelegramRetryAfter as exc:
|
||||
logger.warning(
|
||||
"Telegram edit flood control for chat %s; "
|
||||
"falling back to sending a new message after %s seconds",
|
||||
callback.message.chat.id,
|
||||
exc.retry_after,
|
||||
)
|
||||
await callback.message.answer(
|
||||
text,
|
||||
reply_markup=reply_markup,
|
||||
disable_web_page_preview=disable_web_page_preview,
|
||||
)
|
||||
except TelegramBadRequest as exc:
|
||||
if "message is not modified" in str(exc).lower():
|
||||
return
|
||||
@@ -720,6 +798,70 @@ async def cb_admin_actions(callback: CallbackQuery) -> None:
|
||||
reply_markup=admin_routing_keyboard(),
|
||||
)
|
||||
return
|
||||
if action == "hint:sync":
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("sync"),
|
||||
back_callback="admin:menu:sync",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action == "hint:recipients":
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("recipients"),
|
||||
back_callback="admin:menu:recipients",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action == "hint:routing":
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("routing"),
|
||||
back_callback="admin:menu:routing",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action == "hint:settings":
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("settings"),
|
||||
back_callback="admin:menu:settings",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action == "hint:mute":
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("mute"),
|
||||
back_callback="admin:open",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action == "hint:admins":
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("admins"),
|
||||
back_callback="admin:open",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action.startswith("hint:recipient_group:"):
|
||||
group_name = action.rsplit(":", 1)[1]
|
||||
await _deliver_result(
|
||||
callback,
|
||||
_admin_hint_text("recipient_group", group_name),
|
||||
back_callback=f"admin:recipients:{group_name}",
|
||||
is_admin=True,
|
||||
admin_mode=True,
|
||||
)
|
||||
return
|
||||
if action == "menu:settings":
|
||||
await _show_callback_screen(
|
||||
callback,
|
||||
|
||||
@@ -72,9 +72,12 @@ def admin_home_keyboard() -> InlineKeyboardMarkup:
|
||||
builder.button(text="Topic и routing", callback_data="admin:menu:routing")
|
||||
builder.button(text="Настройки бота", callback_data="admin:menu:settings")
|
||||
builder.button(text="Администраторы", callback_data="admin:admins")
|
||||
builder.button(text="Что такое админы?", callback_data="admin:hint:admins")
|
||||
builder.button(text="Mute rules", callback_data="admin:mute_list")
|
||||
builder.button(text="Что такое mute?", callback_data="admin:hint:mute")
|
||||
builder.button(text="Инструкция", callback_data="admin:guide")
|
||||
builder.adjust(2, 2, 2, 1)
|
||||
builder.button(text="Назад", callback_data="help:open")
|
||||
builder.adjust(2, 2, 2, 2, 1)
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
@@ -82,9 +85,9 @@ def admin_sync_keyboard() -> InlineKeyboardMarkup:
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.button(text="Запустить sync", callback_data="admin:sync")
|
||||
builder.button(text="Статус sync", callback_data="admin:sync_status")
|
||||
builder.button(text="Что это?", callback_data="admin:hint:sync")
|
||||
builder.button(text="Назад", callback_data="admin:open")
|
||||
builder.button(text="Пользовательское меню", callback_data="help:open")
|
||||
builder.adjust(2, 2)
|
||||
builder.adjust(2, 1, 1)
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
@@ -94,8 +97,9 @@ def admin_routing_keyboard() -> InlineKeyboardMarkup:
|
||||
builder.button(text="Topic backend", callback_data="admin:settings:topic:backend")
|
||||
builder.button(text="Topic frontend", callback_data="admin:settings:topic:frontend")
|
||||
builder.button(text="Topic digest", callback_data="admin:settings:topic:digest")
|
||||
builder.button(text="Что это?", callback_data="admin:hint:routing")
|
||||
builder.button(text="Назад", callback_data="admin:open")
|
||||
builder.adjust(2, 2, 1)
|
||||
builder.adjust(2, 2, 1, 1)
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
@@ -109,8 +113,9 @@ def admin_settings_keyboard() -> InlineKeyboardMarkup:
|
||||
builder.button(text="Название бота", callback_data="admin:settings:bot_title")
|
||||
builder.button(text="Описание бота", callback_data="admin:settings:bot_purpose")
|
||||
builder.button(text="Подсказка админу", callback_data="admin:settings:bot_admin_hint")
|
||||
builder.button(text="Что это?", callback_data="admin:hint:settings")
|
||||
builder.button(text="Назад", callback_data="admin:open")
|
||||
builder.adjust(2, 2, 2, 2, 1)
|
||||
builder.adjust(2, 2, 2, 2, 1, 1)
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
@@ -118,8 +123,9 @@ def admin_recipients_keyboard() -> InlineKeyboardMarkup:
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.button(text="Backend", callback_data="admin:recipients:backend")
|
||||
builder.button(text="Frontend", callback_data="admin:recipients:frontend")
|
||||
builder.button(text="Что это?", callback_data="admin:hint:recipients")
|
||||
builder.button(text="Назад", callback_data="admin:open")
|
||||
builder.adjust(2, 1)
|
||||
builder.adjust(2, 1, 1)
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
@@ -128,8 +134,9 @@ def admin_recipient_group_keyboard(group_name: str) -> InlineKeyboardMarkup:
|
||||
builder.button(text="Список", callback_data=f"admin:recipients:list:{group_name}")
|
||||
builder.button(text="Добавить ID", callback_data=f"admin:recipients:add:{group_name}")
|
||||
builder.button(text="Удалить ID", callback_data=f"admin:recipients:del:{group_name}")
|
||||
builder.button(text="Что это?", callback_data=f"admin:hint:recipient_group:{group_name}")
|
||||
builder.button(text="Назад", callback_data="admin:menu:recipients")
|
||||
builder.adjust(2, 1, 1)
|
||||
builder.adjust(2, 1, 1, 1)
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user