From 80219a56cf885c5373fe4c0912b0f2eede00a7a4 Mon Sep 17 00:00:00 2001 From: Ivan Filipenkov Date: Mon, 11 Mar 2024 23:51:19 +0100 Subject: [PATCH] refactor: reactions_fix.update_hash is now called in edit_message --- tgpy/_core/message_design.py | 6 ++- tgpy/_handlers/__init__.py | 94 ++++++++++++++++-------------------- tgpy/reactions_fix.py | 2 +- 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/tgpy/_core/message_design.py b/tgpy/_core/message_design.py index 334a961..f2f8a8d 100644 --- a/tgpy/_core/message_design.py +++ b/tgpy/_core/message_design.py @@ -9,7 +9,7 @@ MessageEntityTextUrl, ) -from tgpy import app +from tgpy import app, reactions_fix TITLE = 'TGPy>' RUNNING_TITLE = 'TGPy running>' @@ -89,7 +89,9 @@ async def edit_message( text = str(''.join(x + ('\n' if i == 1 else '\n\n') for i, x in enumerate(parts))) if len(text) > 4096: text = text[:4095] + '…' - return await message.edit(text, formatting_entities=entities, link_preview=False) + res = await message.edit(text, formatting_entities=entities, link_preview=False) + reactions_fix.update_hash(res, in_memory=False) + return res def get_title_entity(message: Message) -> MessageEntityTextUrl | None: diff --git a/tgpy/_handlers/__init__.py b/tgpy/_handlers/__init__.py index 4f07ece..788f10b 100644 --- a/tgpy/_handlers/__init__.py +++ b/tgpy/_handlers/__init__.py @@ -8,7 +8,7 @@ import tgpy.api from tgpy import app, reactions_fix from tgpy._core import message_design -from tgpy._core.eval_message import eval_message +from tgpy._core.eval_message import eval_message, running_messages from tgpy.api.parse_code import parse_code from tgpy.api.transformers import exec_hooks from tgpy.api.utils import outgoing_messages_filter @@ -28,76 +28,64 @@ async def result(message: Message): return result -async def handle_message( - original_message: Message, *, only_show_warning: bool = False -) -> tuple[Message, bool]: +async def handle_message(original_message: Message) -> Message: if not (message := await exec_hooks.apply(original_message, is_edit=False)): - return original_message, False + reactions_fix.update_hash(message, in_memory=True) + return original_message res = await parse_code(message.raw_text) if not res.is_code: - return original_message, False - - if only_show_warning: - return ( - await message_design.edit_message( - message, - message.raw_text, - 'Edit message again to evaluate', - ), - True, - ) - else: - return await eval_message(message.raw_text, message), True + reactions_fix.update_hash(message, in_memory=True) + return original_message + + return await eval_message(message.raw_text, message) @events.register(events.NewMessage(func=outgoing_messages_filter)) @_handle_errors async def on_new_message(event: events.NewMessage.Event) -> None: - message, handled = await handle_message(event.message) - reactions_fix.update_hash(message, in_memory=not handled) + await handle_message(event.message) @events.register(events.MessageEdited(func=outgoing_messages_filter)) @_handle_errors async def on_message_edited(event: events.MessageEdited.Event) -> None: - message: Message = event.message + message: Message | None = event.message if isinstance(message.chat, Channel) and message.chat.broadcast: + # Don't allow editing in channels, as the editor may not be the same account + # which sent the message initially and there is no way to detect it + return + if (message.chat_id, message.id) in running_messages: + # Message is already running, editing should do nothing. + # The message will be corrected on the next flush or after evaluation finishes. return + message_data = tgpy.api.parse_tgpy_message(message) reactions_fix_result = reactions_fix.check_hash(message) - handled = False - try: - if reactions_fix_result == ReactionsFixResult.ignore: - return - elif reactions_fix_result == ReactionsFixResult.show_warning: - if message_data.is_tgpy_message: - message = await message_design.edit_message( - message, message_data.code, 'Edit message again to evaluate' - ) - handled = True - else: - message, handled = await handle_message(message, only_show_warning=True) - return - elif reactions_fix_result == ReactionsFixResult.evaluate: - pass - else: - raise ValueError(f'Bad reactions fix result: {reactions_fix_result}') - - if not message_data.is_tgpy_message: - message, handled = await handle_message(message) - return - - handled = True - if not (new_message := await exec_hooks.apply(message, is_edit=True)): - return - message_data = tgpy.api.parse_tgpy_message(new_message) - if not message_data.is_tgpy_message: - return - message = await eval_message(message_data.code, new_message) - finally: - if message is not None: - reactions_fix.update_hash(message, in_memory=not handled) + + if reactions_fix_result == ReactionsFixResult.ignore: + return + elif reactions_fix_result == ReactionsFixResult.show_warning: + code = message_data.code if message_data.is_tgpy_message else message.raw_text + await message_design.edit_message( + message, code, 'Edit message again to evaluate' + ) + return + elif reactions_fix_result == ReactionsFixResult.evaluate: + pass + else: + raise ValueError(f'Bad reactions fix result: {reactions_fix_result}') + + if not message_data.is_tgpy_message: + await handle_message(message) + return + + if not (new_message := await exec_hooks.apply(message, is_edit=True)): + return + message_data = tgpy.api.parse_tgpy_message(new_message) + if not message_data.is_tgpy_message: + return + await eval_message(message_data.code, new_message) def add_handlers(): diff --git a/tgpy/reactions_fix.py b/tgpy/reactions_fix.py index e678090..ca6d1f9 100644 --- a/tgpy/reactions_fix.py +++ b/tgpy/reactions_fix.py @@ -42,7 +42,7 @@ def check_hash(message: Message) -> ReactionsFixResult: return ReactionsFixResult.evaluate -def update_hash(message: Message, *, in_memory: bool = False) -> None: +def update_hash(message: Message | None, *, in_memory: bool = False) -> None: if not message: return if in_memory: