-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessage_render.py
More file actions
147 lines (114 loc) · 4.47 KB
/
message_render.py
File metadata and controls
147 lines (114 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
""" ... """
import dataclasses
import typing
import aiogram.types
import aiogram.exceptions
@dataclasses.dataclass
class MessageRender:
""" ... """
text: str
photo: typing.Optional[typing.Union[str, aiogram.types.InputFile]] = None
animation: typing.Optional[typing.Union[str, aiogram.types.InputFile]] = None
keyboard: typing.Optional[typing.Union[aiogram.types.InlineKeyboardMarkup,
aiogram.types.ReplyKeyboardMarkup]] = None
def validate(self):
""" ... """
if self.photo and self.animation:
raise ValueError('Message can not contain both a photo and an animation at the same time')
async def send(self, chat_id: int, bot: aiogram.Bot = None):
""" Отправляет сообщение в указанный чат """
self.validate()
bot = bot or aiogram.Bot.get_current()
config = {}
if self.keyboard:
config['reply_markup'] = self.keyboard
if self.photo:
if self.text:
config['caption'] = self.text
message = await bot.send_photo(
chat_id,
photo=self.photo,
**config
)
return message
if self.animation:
if self.text:
config['caption'] = self.text
message = await bot.send_animation(
chat_id,
animation=self.animation,
**config
)
return message
if self.text:
config['text'] = self.text
return await bot.send_message(chat_id, **config)
async def edit(self, message: aiogram.types.Message, bot: aiogram.Bot = None):
""" Редактирует указанное сообщение """
self.validate()
bot = bot or aiogram.Bot.get_current()
config = {}
if self.keyboard:
config['reply_markup'] = self.keyboard
if not message.photo and not message.animation and self.text:
return await bot.edit_message_text(
chat_id=message.chat.id,
message_id=message.message_id,
text=self.text,
**config
)
if self.photo and message.photo:
message = await bot.edit_message_media(
chat_id=message.chat.id,
message_id=message.message_id,
media=aiogram.types.InputMediaPhoto(
media=self.photo,
caption=self.text
),
**config
)
return message
elif self.animation and message.animation:
message = await bot.edit_message_media(
chat_id=message.chat.id,
message_id=message.message_id,
media=aiogram.types.InputMediaAnimation(
media=self.animation,
caption=self.text
),
**config
)
return message
elif self.photo or self.animation:
raise ValueError('Render must have the same media type as a message')
return await bot.edit_message_caption(
chat_id=message.chat.id,
message_id=message.message_id,
caption=self.text,
**config
)
class MessageRenderList(list[MessageRender]):
""" ... """
async def send(self, chat_id: int, bot: aiogram.Bot = None) -> list[typing.Optional[aiogram.types.Message]]:
""" Отправляет все сообщения в указанный чат """
sent_messages = []
for message in self:
try:
sent_message = await message.send(chat_id, bot=bot)
except aiogram.exceptions.TelegramForbiddenError:
sent_message = None
sent_messages.append(sent_message)
return sent_messages
def extract(self) -> typing.Optional[MessageRender]:
""" Если список содержит единственное сообщение - возвращает его.
None если пусто и ошибка, если больше одного """
if len(self) == 1:
return self[0]
if not self:
return
raise ValueError('Can not extract from MessageRenderList, '
'because it contains more than one MessageRender')
__all__ = (
'MessageRender',
'MessageRenderList'
)