aboutsummaryrefslogtreecommitdiff
path: root/handlers/admin
diff options
context:
space:
mode:
Diffstat (limited to 'handlers/admin')
-rw-r--r--handlers/admin/__init__.py8
-rw-r--r--handlers/admin/new_announcement.py108
2 files changed, 116 insertions, 0 deletions
diff --git a/handlers/admin/__init__.py b/handlers/admin/__init__.py
index d0a5587..2f7c74f 100644
--- a/handlers/admin/__init__.py
+++ b/handlers/admin/__init__.py
@@ -1,6 +1,14 @@
1from aiogram import F, Router 1from aiogram import F, Router
2from aiogram.filters import MagicData 2from aiogram.filters import MagicData
3 3
4# isort: off
5from . import new_announcement
6# isort: on
7
4router = Router(name="admin") 8router = Router(name="admin")
5router.message.filter(MagicData(F.user.is_admin())) 9router.message.filter(MagicData(F.user.is_admin()))
6router.callback_query.filter(MagicData(F.user.is_admin())) 10router.callback_query.filter(MagicData(F.user.is_admin()))
11
12router.include_routers(
13 new_announcement.router,
14)
diff --git a/handlers/admin/new_announcement.py b/handlers/admin/new_announcement.py
new file mode 100644
index 0000000..79cf8d4
--- /dev/null
+++ b/handlers/admin/new_announcement.py
@@ -0,0 +1,108 @@
1from datetime import UTC, datetime
2
3from aiogram import Bot, F, Router
4from aiogram.exceptions import TelegramAPIError
5from aiogram.filters import Command
6from aiogram.fsm.context import FSMContext
7from aiogram.fsm.state import State, StatesGroup
8from aiogram.types import (
9 ContentType,
10 KeyboardButton,
11 Message,
12 ReplyKeyboardMarkup,
13 ReplyKeyboardRemove,
14)
15from pydantic.main import BaseModel
16from sqlalchemy import select
17from sqlalchemy.ext.asyncio import AsyncSession
18
19from libs.fsm import get_data, set_data
20from libs.msg import publish
21from models import Announcement, RichText, User
22
23router = Router(name="new_announcement")
24
25
26class NewAnnouncementStates(StatesGroup):
27 message = State()
28
29
30class NewAnnouncementData(BaseModel):
31 rich_text: RichText | None = None
32
33
34SEND_BUTTON = "Опубликовать"
35CANCEL_BUTTON = "Отменить создание"
36
37
38@router.message(Command("new_announcement"))
39async def new_announcement_command(msg: Message, state: FSMContext) -> None:
40 await msg.answer(
41 "Укажите сообщение для анонса.",
42 reply_markup=ReplyKeyboardMarkup(
43 keyboard=[
44 [
45 KeyboardButton(text=SEND_BUTTON),
46 KeyboardButton(text=CANCEL_BUTTON),
47 ]
48 ],
49 resize_keyboard=True,
50 ),
51 )
52 await state.set_state(NewAnnouncementStates.message)
53
54
55@router.message(NewAnnouncementStates.message, F.text == SEND_BUTTON)
56async def announcement_send(
57 msg: Message,
58 bot: Bot,
59 state: FSMContext,
60 session: AsyncSession,
61) -> None:
62 users = await session.scalars(select(User.id).where(User.id != msg.chat.id))
63 data = await get_data(state, NewAnnouncementData)
64
65 if data.rich_text is None:
66 await msg.answer("Для публикации анонса укажите текст сообщения.")
67 return
68
69 status_template = "Публикация анонса...\nОпубликовано: {}"
70 status_msg = await msg.answer(status_template.format(0))
71
72 async for n in publish(bot, users, data.rich_text):
73 try:
74 await status_msg.edit_text(status_template.format(n))
75 except TelegramAPIError:
76 pass
77
78 announcement = Announcement(message=data, datetime=datetime.now(UTC))
79 session.add(announcement)
80
81 await status_msg.delete()
82 await msg.answer(
83 "Анонс отправлен всем пользователям",
84 reply_markup=ReplyKeyboardRemove(),
85 )
86 await state.clear()
87
88
89@router.message(NewAnnouncementStates.message, F.text == CANCEL_BUTTON)
90async def announcement_cancel(msg: Message, state: FSMContext) -> None:
91 await msg.answer("Создание анонса отменено", reply_markup=ReplyKeyboardRemove())
92 await state.clear()
93
94
95@router.message(NewAnnouncementStates.message)
96async def announcement_message(msg: Message, bot: Bot, state: FSMContext) -> None:
97 if msg.content_type != ContentType.TEXT or msg.text is None:
98 await msg.answer(
99 "Неверный тип сообщения.\n"
100 "Бот поддерживает отправку только текстовых анонсов."
101 )
102 return
103
104 rich_text = RichText.from_message(msg)
105 await set_data(state, NewAnnouncementData(rich_text=rich_text))
106
107 msg_rich_text = RichText.from_text("Сообщение вашего анонса:\n", rich_text)
108 await msg_rich_text.send(bot, msg.chat.id)