From 28586ed19bd1415615cce2cdac1881b6f04ad724 Mon Sep 17 00:00:00 2001 From: bakatrouble Date: Sun, 17 Mar 2019 02:45:26 +0300 Subject: [PATCH] working media groups --- .idea/deployment.xml | 11 +------ main.py | 75 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/.idea/deployment.xml b/.idea/deployment.xml index d5d0de2..d643e42 100644 --- a/.idea/deployment.xml +++ b/.idea/deployment.xml @@ -1,15 +1,6 @@ - - - - - - - - - - + \ No newline at end of file diff --git a/main.py b/main.py index 22eed7d..772b12d 100755 --- a/main.py +++ b/main.py @@ -6,12 +6,13 @@ from html import escape from queue import Queue, Empty from time import sleep from threading import Thread -from typing import Dict +from typing import Dict, List import sentry_sdk from telegram.error import Unauthorized, TelegramError from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackQueryHandler -from telegram import Message, Update, Bot, InlineKeyboardMarkup, InlineKeyboardButton, User +from telegram import Message, Update, Bot, InlineKeyboardMarkup, InlineKeyboardButton, User, InputMediaPhoto, \ + InputMediaVideo, InputMediaAnimation, InputMediaAudio, InputMediaDocument from config import BOT_TOKEN, SENTRY_DSN, MANAGEMENT_CHAT, DEBUG from db import get_conn, Subscriber, PersistentMapping, commit @@ -148,6 +149,67 @@ def _sign_text(text, m: Message, limit): return text[:limit - len(sign)] + sign +def _process_media_group(bot: Bot, messages: List[Message]): + if not messages: + return + + m = messages[0] + + current_chat = m.chat_id + users = conn.root.subscribers # type: Dict[int, Subscriber] + if current_chat not in users: + if DEBUG: + _add_user(bot, current_chat) + m.reply_text('Добро пожаловать (debug)') + else: + _notify_access_request(bot, m.from_user) + return m.reply_text('Пожалуйста, обратитесь к @lono_contactbot') + + reply_to_message_internal_id = None + if m.reply_to_message and m.reply_to_message.message_id in users[current_chat].messages_forward: + reply_to_message_internal_id = users[current_chat].messages_forward[m.reply_to_message.message_id] + + media_group = [] + for message in messages: + caption = _sign_text(message.caption_html, message, MAX_CAPTION_LENGTH) + + if hasattr(message, 'photo') and message.photo: + media_group.append(InputMediaPhoto(message.photo[-1].file_id, caption=caption, parse_mode='html')) + elif hasattr(message, 'video') and message.video: + media_group.append(InputMediaVideo(message.video.file_id, caption=caption, parse_mode='html')) + elif hasattr(message, 'animation') and message.animation: + media_group.append(InputMediaAnimation(message.animation.file_id, caption=caption, parse_mode='html')) + elif hasattr(message, 'document') and message.document: + media_group.append(InputMediaDocument(message.document.file_id, caption=caption, parse_mode='html')) + elif hasattr(message, 'audio') and message.audio: + media_group.append(InputMediaAudio(message.audio.file_id, caption=caption, parse_mode='html')) + + for uid, user in users.items(): + sleep(.02) + + reply_to_message_id = None + if reply_to_message_internal_id: + reply_to_message_id = user.messages_reverse.get(reply_to_message_internal_id, None) + + try: + sent_messages = bot.send_media_group(uid, media_group, reply_to_message_id=reply_to_message_id) + if sent_messages: + user.update_from_message(sent_messages[0]) + for r in sent_messages: + user.messages_forward[r.message_id] = conn.root.counter + user.messages_reverse[conn.root.counter] = r.message_id + except Unauthorized: + user = _remove_user(uid) + commit() + bot.send_message(MANAGEMENT_CHAT, f'{user.name} был удален ' + f'из-за блокировки бота', parse_mode='html') + except Exception: + traceback.print_exc() + sentry_sdk.capture_exception() + conn.root.counter += len(messages) + commit() + + def _process_message(bot: Bot, m: Message): current_chat = m.chat_id users = conn.root.subscribers # type: Dict[int, Subscriber] @@ -241,7 +303,14 @@ def task_queue(u: Updater): try: m = queue.get(timeout=1) # type: Message - _process_message(u.bot, m) + if m.media_group_id: + media_group_id = m.media_group_id + group_messages = [m] + while queue.qsize() and queue.queue[0].media_group_id == media_group_id: + group_messages.append(queue.get(block=False)) + _process_media_group(u.bot, group_messages) + else: + _process_message(u.bot, m) except Empty: pass except: