From d181e5ac33b8e2679d5d5cbdc2cb3e85d9373f90 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Tue, 13 Feb 2024 23:08:29 +0300 Subject: [PATCH] Finally fixed media groups --- handlers/admin_commands.py | 10 ++++-- handlers/filters/new_post.py | 11 ------ handlers/message_handlers/newpost_command.py | 19 +++++++---- handlers/message_handlers/post_command.py | 1 - handlers/middlewares/media_group.py | 35 ++++++++++++++++++++ main.py | 1 - neuroapi/_methods/image.py | 1 - neuroapi/_methods/post.py | 6 ++-- neuroapi/types/_post.py | 1 - 9 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 handlers/middlewares/media_group.py diff --git a/handlers/admin_commands.py b/handlers/admin_commands.py index 5da6b19..e3f3352 100644 --- a/handlers/admin_commands.py +++ b/handlers/admin_commands.py @@ -9,6 +9,7 @@ from handlers.message_handlers.post_command import PostCommand from handlers.message_handlers.reply_to_user import ReplyToUserCommand from handlers.message_handlers.settings_command import SettingsCommand from handlers.message_handlers.update_settings import UpdateSettingsCommand +from handlers.middlewares.media_group import MediaGroupMiddleware from handlers.middlewares.user import AdminMiddleware from neuroapi.types import BotSettings as BotSettingsType @@ -19,14 +20,17 @@ class AdminCommands(Handler): def __init__(self, bot: Bot) -> None: super().__init__(bot) self.router.message.middleware(AdminMiddleware()) - + self.add_handlers([ InfoCommand, (UpdateSettingsCommand, PostCommand(self.bot).handler), EditCommand, - NewPostCommand, - NewPostSoloCommand, PostCommand, SettingsCommand, + ]) + self.router.message.middleware(MediaGroupMiddleware()) + self.add_handlers([ + NewPostCommand, + NewPostSoloCommand, ReplyToUserCommand ]) diff --git a/handlers/filters/new_post.py b/handlers/filters/new_post.py index 585a85a..e9e1ef2 100644 --- a/handlers/filters/new_post.py +++ b/handlers/filters/new_post.py @@ -1,22 +1,11 @@ from aiogram import types from aiogram.filters import Filter -from neuroapi import neuroapi - class NewPostFilter(Filter): async def __call__(self, message: types.Message) -> bool: if message.media_group_id is None or message.content_type != 'photo': return False - # if (message.caption and message.caption.startswith('/newpost ')) - # try: - # await neuroapi.post.get_by_media_group_id(message.media_group_id) - # except: - # if not (message.caption.startswith('/newpost ') if message.caption else False): - # return False - # await neuroapi.post.new(message.caption.replace( - # '/newpost ', ''), str(message.from_user.id), str(message.media_group_id), message.caption_entities) - # await message.answer('Пост успешно добавлен!') return True diff --git a/handlers/message_handlers/newpost_command.py b/handlers/message_handlers/newpost_command.py index 051e29f..e691361 100644 --- a/handlers/message_handlers/newpost_command.py +++ b/handlers/message_handlers/newpost_command.py @@ -1,6 +1,7 @@ +from typing import List + from aiogram import types -import neuroapi.types as neuroTypes from handlers.filters.new_post import NewPostFilter, NewSoloPostFilter from neuroapi import neuroapi @@ -9,13 +10,17 @@ from .handler import MessageHandlerABC class NewPostCommand(MessageHandlerABC): filter = NewPostFilter() - async def _command(self, message: types.Message): - created = await neuroapi.image.add(str(message.from_user.id), message.photo[-1].file_id, message.has_media_spoiler, message.message_id, message.caption if message.caption else '', message.media_group_id, message.caption_entities, message) - if created: await message.answer('Пост успешно добавлен!') - + async def _command(self, message: types.Message, album: List[types.Message]): + sorted_album = sorted(album, key=lambda x: x.message_id) + if (not sorted_album[0].caption.startswith('/newpost ') if sorted_album[0].caption else True): + return + for mes in sorted_album: + await neuroapi.image.add(str(message.from_user.id), mes.photo[-1].file_id, mes.has_media_spoiler, mes.message_id, mes.caption if mes.caption else '', mes.media_group_id, mes.caption_entities, mes) + await message.answer(f'Пост успешно добавлен!') + + class NewPostSoloCommand(MessageHandlerABC): filter = NewSoloPostFilter() async def _command(self, message: types.Message): - #FIXME: Починить добавление постов с одной картинкой, выводит ошибку на /info - await neuroapi.image.add(str(message.from_user.id), message.photo[-1].file_id, message.has_media_spoiler, message.message_id, message.caption, None, message.caption_entities) + await neuroapi.image.add(str(message.from_user.id), message.photo[-1].file_id, message.has_media_spoiler, message.message_id, message.caption, None, message.caption_entities, message) await message.answer('Пост успешно добавлен!') \ No newline at end of file diff --git a/handlers/message_handlers/post_command.py b/handlers/message_handlers/post_command.py index ea803ea..7caa5f5 100644 --- a/handlers/message_handlers/post_command.py +++ b/handlers/message_handlers/post_command.py @@ -14,7 +14,6 @@ class PostCommand(MessageHandlerABC): settings = neuroTypes.BotSettings.get_instance() try: post = await neuroapi.post.get_post_to_post() - print(post) if (post): images = MediaGroupBuilder( caption=post.text + '\n\nПредложка: @neur0w0men_reply_bot', caption_entities=post.message_entities) diff --git a/handlers/middlewares/media_group.py b/handlers/middlewares/media_group.py new file mode 100644 index 0000000..b94e116 --- /dev/null +++ b/handlers/middlewares/media_group.py @@ -0,0 +1,35 @@ +import asyncio +from typing import Any, Awaitable, Callable, Dict, List, Union + +from aiogram import BaseMiddleware, types +from aiogram.types import Message, TelegramObject + +DEFAULT_DELAY = .6 +class MediaGroupMiddleware(BaseMiddleware): + """Middleware for handling telegram media groups + + Big thanks to https://github.com/WhiteMemory99 for this + """ + ALBUM_DATA: Dict[str, List[Message]] = {} + + def __init__(self, delay: Union[int, float] = DEFAULT_DELAY): + self.delay = delay + + async def __call__( + self, + handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]], + event: Message, + data: Dict[str, Any], + ) -> Any: + if not event.media_group_id: + return await handler(event, data) + + try: + self.ALBUM_DATA[event.media_group_id].append(event) + return # Don't propagate the event + except KeyError: + self.ALBUM_DATA[event.media_group_id] = [event] + await asyncio.sleep(self.delay) + data["album"] = self.ALBUM_DATA.pop(event.media_group_id) + + return await handler(event, data) \ No newline at end of file diff --git a/main.py b/main.py index 05bafda..e058756 100644 --- a/main.py +++ b/main.py @@ -16,7 +16,6 @@ from neuroapi.types import NeuroApiBot async def delay_bot()->None: config = Config() - print(config) if config.token is None or config.token == '': logging.warning('Delay bot needs token in environment') return diff --git a/neuroapi/_methods/image.py b/neuroapi/_methods/image.py index 36c0ec1..6a3ad71 100644 --- a/neuroapi/_methods/image.py +++ b/neuroapi/_methods/image.py @@ -33,4 +33,3 @@ class Image(ApiMethod): data = await response.json() if 'statusCode' in data: raise Exception(data['message']) - return data['created'] diff --git a/neuroapi/_methods/post.py b/neuroapi/_methods/post.py index 49e9c5f..59cb520 100644 --- a/neuroapi/_methods/post.py +++ b/neuroapi/_methods/post.py @@ -57,9 +57,9 @@ class Post(ApiMethod): return neuroTypes.Post.from_dict(data) async def get_by_media_group_id(self, media_group_id: str): - response = requests.get( - self.api_url+f'/post/get-by-media-group-id/{media_group_id}') - data = response.json() + async with ClientSession() as session: + response = await session.get(self.api_url+f'/post/get-by-media-group-id/{media_group_id}') + data = await response.json() if 'statusCode' in data: raise Exception(data['message']) return neuroTypes.Post.from_dict(data) diff --git a/neuroapi/types/_post.py b/neuroapi/types/_post.py index 7bf9a8b..4029030 100644 --- a/neuroapi/types/_post.py +++ b/neuroapi/types/_post.py @@ -34,5 +34,4 @@ class Post(ApiModel): obj = super().to_dict() obj['message_entities'] = json.dumps(obj['message_entities']) obj['media_group_id'] = str(obj['media_group_id']) - print(obj) return obj \ No newline at end of file