from html import escape
from aiogram import types
import config
CAPTION_LIMIT = 1024 # подпись к фото в Telegram
TEXT_LIMIT = 4096 # обычное сообщение
def login(user_id, du, db):
user_id = int(user_id)
if not du.user_exists(user_id): du.add_user(user_id)
user_id = du.get_user_id(user_id)
if not db.infoUser_exists(user_id): db.add_infoUser(user_id)
return user_id
def pars_post(output):
"""Пост из vk_scripts.get_output → текст в HTML, аудио и медиа для Telegram.
Всё, что пришло из ВК, экранируется: «<» или «&» в посте иначе ломают отправку"""
media, video, url, audio, poll, link = [], [], [], [], [], []
for group in output[0]:
if group[0] == "poll": poll = group[1]
elif group[0] == "link": link.append(group[1])
elif group[0] == "video": video.append(group[1])
elif group[0] == "doc" and group[1][2] != 4: url.append([group[1][0], group[1][1], group[1][3]])
elif group[0] == "audio": audio.append(types.InputMediaAudio(
media=group[1][1], caption=f"Название: {escape(group[1][0])} / Автор: {escape(group[1][2])}"))
if output[1] != "":
# упоминания ВК вида [id1|Имя] превращаются в ссылки
post = [elem_2 for elem_1 in escape(output[1], quote=False).split("[") for elem_2 in elem_1.split("]")]
for i, elem in enumerate(post):
if "|" in elem and i != 0:
elem = elem.split("|", 1)
post[i] = f"{elem[1]}"
text = f"{output[2]}\n\n{''.join(post)}\n"
else: text = f"{output[2]}\n"
if poll:
text += (f"\n> Проводится {config.anonymous[poll[3]]} {config.unvote[poll[2]]}! "
f"Вопрос: {escape(poll[0])} [{poll[1]}]\n")
text += ''.join([f'{i + 1}. Ответ: {escape(ans[0])} [{ans[1]}]\n'
for i, ans in enumerate(poll[4])]) + "\n"
if video:
for frame in video:
text += f"\nВидео « {escape(frame[0])} »\n"
k, dura = 0, frame[1]
if dura > 60: dura, k = dura // 60, 1
text += f"Длительность: {dura} {config.dura[k]}; Просмотров: {frame[2]};\n"
if url:
for data in url:
k, dt = 0, data[2]
while dt > 1024 and k < len(config.data) - 1:
dt, k = dt // 1024, k + 1
text += (f"\nДокумент - [ {escape(data[0])} "
f"({dt} {config.data[k]}) ]")
text += "\n"
if link:
text += ''.join([f"\nСсылка - [ {escape(s[0])} ]"
for s in link]) + "\n"
if audio: text += '\n« Также присутствуют аудио файлы »'
for group in output[0]:
if group[0] == "photo":
media.append(types.InputMediaPhoto(media=group[1]))
elif group[0] == "video" and group[1][3]: # у видео может не быть обложки
media.append(types.InputMediaPhoto(media=group[1][3]))
elif group[0] == "doc" and group[1][2] == 4:
media.append(types.InputMediaPhoto(media=group[1][1]))
return text, audio[:10], media[:10] # в одном альбоме Telegram не больше 10 элементов
def split_text(text, limit=TEXT_LIMIT):
"""Делит длинный текст по строкам, чтобы не разрывать HTML-теги посередине"""
parts, current = [], ""
for line in text.split("\n"):
while len(line) > limit: # одна строка длиннее лимита — режем как есть
if current: parts.append(current); current = ""
parts.append(line[:limit]); line = line[limit:]
if len(current) + len(line) + 1 > limit:
parts.append(current); current = ""
current += line + "\n"
if current.strip(): parts.append(current)
return parts
async def send_post(bot, chat_id, text, audio, media):
"""Отправляет пост с учётом ограничений Telegram: альбом — от 2 до 10 элементов, подпись —
до 1024 символов, сообщение — до 4096"""
first = None
if media:
caption = text if len(text) <= CAPTION_LIMIT else None
if len(media) == 1:
first = await bot.send_photo(chat_id=chat_id, photo=media[0].media, caption=caption)
else:
media[0].caption = caption
first = (await bot.send_media_group(chat_id=chat_id, media=media))[0]
if caption is None:
for part in split_text(text):
await bot.send_message(chat_id=chat_id, text=part, disable_web_page_preview=True,
reply_to_message_id=first.message_id)
else:
for part in split_text(text):
sent = await bot.send_message(chat_id=chat_id, text=part, disable_web_page_preview=True)
first = first or sent
if audio:
reply_to = first.message_id if first else None
if len(audio) == 1:
await bot.send_audio(chat_id=chat_id, audio=audio[0].media, caption=audio[0].caption,
reply_to_message_id=reply_to)
else:
await bot.send_media_group(chat_id=chat_id, media=audio, reply_to_message_id=reply_to)