Правки проблем
This commit is contained in:
@@ -6,7 +6,7 @@ from html import escape
|
|||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from aiogram import F, Router
|
from aiogram import F, Router
|
||||||
from aiogram.exceptions import TelegramBadRequest
|
from aiogram.exceptions import TelegramBadRequest, TelegramRetryAfter
|
||||||
from aiogram.filters import Command
|
from aiogram.filters import Command
|
||||||
from aiogram.types import CallbackQuery, Message
|
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:
|
def _sync_summary_text(summary) -> str:
|
||||||
return "\n".join(
|
return "\n".join(
|
||||||
[
|
[
|
||||||
@@ -405,6 +471,18 @@ async def _show_callback_screen(
|
|||||||
reply_markup=reply_markup,
|
reply_markup=reply_markup,
|
||||||
disable_web_page_preview=disable_web_page_preview,
|
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:
|
except TelegramBadRequest as exc:
|
||||||
if "message is not modified" in str(exc).lower():
|
if "message is not modified" in str(exc).lower():
|
||||||
return
|
return
|
||||||
@@ -720,6 +798,70 @@ async def cb_admin_actions(callback: CallbackQuery) -> None:
|
|||||||
reply_markup=admin_routing_keyboard(),
|
reply_markup=admin_routing_keyboard(),
|
||||||
)
|
)
|
||||||
return
|
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":
|
if action == "menu:settings":
|
||||||
await _show_callback_screen(
|
await _show_callback_screen(
|
||||||
callback,
|
callback,
|
||||||
|
|||||||
@@ -72,9 +72,12 @@ def admin_home_keyboard() -> InlineKeyboardMarkup:
|
|||||||
builder.button(text="Topic и routing", callback_data="admin:menu:routing")
|
builder.button(text="Topic и routing", callback_data="admin:menu:routing")
|
||||||
builder.button(text="Настройки бота", callback_data="admin:menu:settings")
|
builder.button(text="Настройки бота", callback_data="admin:menu:settings")
|
||||||
builder.button(text="Администраторы", callback_data="admin:admins")
|
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 rules", callback_data="admin:mute_list")
|
||||||
|
builder.button(text="Что такое mute?", callback_data="admin:hint:mute")
|
||||||
builder.button(text="Инструкция", callback_data="admin:guide")
|
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()
|
return builder.as_markup()
|
||||||
|
|
||||||
|
|
||||||
@@ -82,9 +85,9 @@ def admin_sync_keyboard() -> InlineKeyboardMarkup:
|
|||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
builder.button(text="Запустить sync", callback_data="admin:sync")
|
builder.button(text="Запустить sync", callback_data="admin:sync")
|
||||||
builder.button(text="Статус sync", callback_data="admin:sync_status")
|
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="admin:open")
|
||||||
builder.button(text="Пользовательское меню", callback_data="help:open")
|
builder.adjust(2, 1, 1)
|
||||||
builder.adjust(2, 2)
|
|
||||||
return builder.as_markup()
|
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 backend", callback_data="admin:settings:topic:backend")
|
||||||
builder.button(text="Topic frontend", callback_data="admin:settings:topic:frontend")
|
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="Topic digest", callback_data="admin:settings:topic:digest")
|
||||||
|
builder.button(text="Что это?", callback_data="admin:hint:routing")
|
||||||
builder.button(text="Назад", callback_data="admin:open")
|
builder.button(text="Назад", callback_data="admin:open")
|
||||||
builder.adjust(2, 2, 1)
|
builder.adjust(2, 2, 1, 1)
|
||||||
return builder.as_markup()
|
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_title")
|
||||||
builder.button(text="Описание бота", callback_data="admin:settings:bot_purpose")
|
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:settings:bot_admin_hint")
|
||||||
|
builder.button(text="Что это?", callback_data="admin:hint:settings")
|
||||||
builder.button(text="Назад", callback_data="admin:open")
|
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()
|
return builder.as_markup()
|
||||||
|
|
||||||
|
|
||||||
@@ -118,8 +123,9 @@ def admin_recipients_keyboard() -> InlineKeyboardMarkup:
|
|||||||
builder = InlineKeyboardBuilder()
|
builder = InlineKeyboardBuilder()
|
||||||
builder.button(text="Backend", callback_data="admin:recipients:backend")
|
builder.button(text="Backend", callback_data="admin:recipients:backend")
|
||||||
builder.button(text="Frontend", callback_data="admin:recipients:frontend")
|
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.button(text="Назад", callback_data="admin:open")
|
||||||
builder.adjust(2, 1)
|
builder.adjust(2, 1, 1)
|
||||||
return builder.as_markup()
|
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="Список", 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:add:{group_name}")
|
||||||
builder.button(text="Удалить ID", callback_data=f"admin:recipients:del:{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.button(text="Назад", callback_data="admin:menu:recipients")
|
||||||
builder.adjust(2, 1, 1)
|
builder.adjust(2, 1, 1, 1)
|
||||||
return builder.as_markup()
|
return builder.as_markup()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user