From 230850bf65064cfbda318e715741624fecaed5f6 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Thu, 4 Jan 2024 20:58:32 +0300 Subject: [PATCH 1/2] Added message entities to posts and info --- handlers/admin_commands.py | 18 ++++++++++++------ handlers/filters/new_post.py | 2 +- neuroapi/_methods/post.py | 14 +++++++++++++- neuroapi/types/_post.py | 21 ++++++++++++++++++--- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/handlers/admin_commands.py b/handlers/admin_commands.py index 1507264..9cc31c7 100644 --- a/handlers/admin_commands.py +++ b/handlers/admin_commands.py @@ -51,6 +51,7 @@ class AdminCommands(Handler): post_c[post.from_user_id] += 1 res = "Количество постов от админов:\n" res2 = "\nПосты:\n" + posts_entities: List[types.MessageEntity] = [] for admin in admins: if admin.user_id in post_c: res += f'[{admin.user_name}](tg://user?id={admin.user_id}): {post_c[admin.user_id]}\n' @@ -61,11 +62,16 @@ class AdminCommands(Handler): res2 += f'Посты от {admin.user_name}:\n' if len(admin_posts): for i, post in enumerate(admin_posts): - #TODO: Если возможно, сделать чтоб было ссылкой на сообщений с /newpost - res2 += f'{i+1}. {post.text}\n' + # TODO: Если возможно, сделать чтоб было ссылкой на сообщений с /newpost + s = f'{i+1}. {post.text}\n' + res2 += s + for entity in post.message_entities: + entity.offset += 3+res2.index(s) + posts_entities.append(entity) else: res2 += 'Их нет\)\n' - await message.answer((res+res2).replace('#', '\#').replace("_", "\_").replace('.', '\.').replace(',', '\,').replace('!', '\!'), parse_mode='markdownv2') + await message.answer(res, parse_mode='markdownv2') + await message.answer(res2, entities=posts_entities) """ TODO: Изменение постов сделать нормально, не через редактирование сообщений @@ -207,7 +213,7 @@ class AdminCommands(Handler): post = await neuroapi.post.get_post_to_post() if (post): images = MediaGroupBuilder( - caption=post.text + '\n\nПредложка: @neur0w0men_reply_bot') + caption=post.text + '\n\nПредложка: @neur0w0men_reply_bot', caption_entities=post.message_entities) image: neuroTypes.Image for image in sorted(post.images, key=lambda x: x.message_id): images.add_photo(image.file_id, @@ -223,7 +229,7 @@ class AdminCommands(Handler): @self.router.message(NewSoloPostFilter()) async def post_solo(message: types.Message): - post: neuroTypes.Post = await neuroapi.post.new(message.caption.replace('/newpost ', ''), message.from_user.id) + post: neuroTypes.Post = await neuroapi.post.new(message.caption.replace('/newpost ', ''), message.from_user.id, message_entities=message.caption_entities) await neuroapi.image.add(str(post.uuid), message.photo[-1].file_id, message.has_media_spoiler, message.message_id) await message.answer('Пост успешно добавлен!') @@ -233,7 +239,7 @@ class AdminCommands(Handler): await message.reply('Пользователь стесняшка и не разрешает отвечать на его сообщения...') else: try: - await bot.send_message(message.reply_to_message.forward_from.id, f'Вам ответил админ:\n{message.text}') + await bot.send_message(message.reply_to_message.forward_from.id, f'Вам ответил админ:\n{message.text}', entities=message.entities) await message.reply('Ваше сообщение было отправлено!') except Exception as e: print(e) diff --git a/handlers/filters/new_post.py b/handlers/filters/new_post.py index aade686..faf017f 100644 --- a/handlers/filters/new_post.py +++ b/handlers/filters/new_post.py @@ -14,7 +14,7 @@ class NewPostFilter(Filter): 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)) + '/newpost ', ''), str(message.from_user.id), str(message.media_group_id), message.caption_entities) await message.answer('Пост успешно добавлен!') return True diff --git a/neuroapi/_methods/post.py b/neuroapi/_methods/post.py index 2bf4489..b9e3a84 100644 --- a/neuroapi/_methods/post.py +++ b/neuroapi/_methods/post.py @@ -1,4 +1,8 @@ +import json +from typing import List, Optional + import requests +from aiogram.types import MessageEntity from aiohttp import ClientSession import neuroapi.types as neuroTypes @@ -9,10 +13,18 @@ from .enums import EGetAll class Post(ApiMethod): - async def new(self, text: str, from_user_id: str, media_group_id: str = "None"): + async def new(self, text: str, from_user_id: str, media_group_id: str = "None", message_entities: Optional[List[MessageEntity]] = None): payload = {'text': text, 'from_user_id': from_user_id} if media_group_id != 'None': payload['media_group_id'] = media_group_id + if message_entities is not None: + mes_ent = list(map(lambda x: x.model_dump(), message_entities)) + arr =[] + for item in mes_ent: + if item['type'] == 'bot_command': continue + item['offset'] -= 9 + arr.append(item) + payload['message_entities'] = json.dumps(arr) response = requests.post(self.api_url+'/post/new', data=payload) data = response.json() if 'statusCode' in data: diff --git a/neuroapi/types/_post.py b/neuroapi/types/_post.py index cb1badb..60e821d 100644 --- a/neuroapi/types/_post.py +++ b/neuroapi/types/_post.py @@ -1,9 +1,18 @@ +import json from dataclasses import dataclass -from uuid import UUID from datetime import datetime from typing import Any, List, Optional -from ._image import Image +from uuid import UUID + +from aiogram.types import MessageEntity + from ._helpers import * +from ._image import Image + + +def to_message_dict_class(x: Any) -> dict: + assert isinstance(x, MessageEntity) + return cast(MessageEntity, x).model_dump() @dataclass @@ -15,6 +24,7 @@ class Post: timestamp: datetime from_user_id: int images: Optional[List[Image]] = None + message_entities: Optional[List[MessageEntity]] = None @staticmethod def from_dict(obj: Any) -> 'Post': @@ -28,7 +38,9 @@ class Post: from_user_id = int(from_str(obj.get("from_user_id"))) images = from_union([lambda x: from_list( Image.from_dict, x), from_none], obj.get("images")) - return Post(uuid, posted, text, media_group_id, timestamp, from_user_id, images) + mes_ent = json.loads(obj.get('message_entities','[]')) + message_entities = from_list(MessageEntity.model_validate, mes_ent) + return Post(uuid, posted, text, media_group_id, timestamp, from_user_id, images, message_entities) def to_dict(self) -> dict: result: dict = {} @@ -41,4 +53,7 @@ class Post: if self.images is not None: result["images"] = from_union([lambda x: from_list( lambda x: to_class(Image, x), x), from_none], self.images) + if self.message_entities is not None: + result['message_entities'] = from_union([lambda x: from_list( + lambda x: to_message_dict_class(x), x), from_none], self.message_entities) return result From 29ab3eb1244ecdcf42aefa4b93ef211e229a47be Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Thu, 4 Jan 2024 21:43:45 +0300 Subject: [PATCH 2/2] Replacement fix --- handlers/admin_commands.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/handlers/admin_commands.py b/handlers/admin_commands.py index 9cc31c7..dfa0bd8 100644 --- a/handlers/admin_commands.py +++ b/handlers/admin_commands.py @@ -69,8 +69,9 @@ class AdminCommands(Handler): entity.offset += 3+res2.index(s) posts_entities.append(entity) else: - res2 += 'Их нет\)\n' - await message.answer(res, parse_mode='markdownv2') + res2 += 'Их нет)\n' + await message.answer(res.replace('#', '\#').replace( + "_", "\_").replace('.', '\.').replace(',', '\,').replace('!', '\!').replace('-', '\-').replace(':', '\:').replace('+', '\+'), parse_mode='markdownv2') await message.answer(res2, entities=posts_entities) """