55import httpx
66from aiogram import Bot , F , Router , flags
77from aiogram .enums import ChatAction
8+ from aiogram .exceptions import TelegramBadRequest
89from aiogram .filters import Command , StateFilter
910from aiogram .fsm .context import FSMContext
1011from aiogram .fsm .state import default_state
2728from src .bot .routers .scanning .scanning_states import ScanWork , gracefully_interrupt_scanning_state
2829from src .bot .routers .scanning .scanning_tools import (
2930 ScanConfigureCallback ,
30- ScanningCallback ,
3131 ScanningPausedCallback ,
3232 format_configure_message ,
3333 format_scanning_message ,
3434 format_scanning_paused_message ,
3535)
36- from src .bot .routers .tools import cancel_expiring , edit_message_text_anyway , make_expiring
36+ from src .bot .routers .tools import (
37+ cancel_expiring ,
38+ edit_message_text_anyway ,
39+ ensure_same_structural_message ,
40+ make_expiring ,
41+ )
3742from src .bot .shared_messages import go_to_default_state
3843from src .modules .scanning .entity_models import ScanningOptions
3944
@@ -96,6 +101,8 @@ async def continue_scan_handler(callback: CallbackQuery, state: FSMContext, pret
96101 await cancel_expiring (callback .message )
97102 await state .set_state (ScanWork .scanning )
98103 data = await state .get_data ()
104+ text = format_scanning_message (data , None , "starting" )
105+ message = await edit_message_text_anyway (message , text )
99106 scanner_status = await api_client .get_scanner_status (message .chat .id , data .get ("scanner" ))
100107 scanning_options = ScanningOptions (
101108 sides = "false" if data ["mode" ] == "manual" else data .get ("scan_sides" , "false" ),
@@ -107,7 +114,7 @@ async def continue_scan_handler(callback: CallbackQuery, state: FSMContext, pret
107114 # start scanning
108115 try :
109116 scan_job_id = await api_client .start_manual_scan (message .chat .id , scanner_status .scanner , scanning_options )
110- await state .update_data (scan_job_id = scan_job_id )
117+ data = await state .update_data (scan_job_id = scan_job_id )
111118 except httpx .HTTPStatusError as e :
112119 if e .response .status_code == 503 :
113120 await message .answer ("Scanner is busy. Try pressing Cancel button on the device and try again." )
@@ -120,8 +127,6 @@ async def continue_scan_handler(callback: CallbackQuery, state: FSMContext, pret
120127 await edit_message_text_anyway (message , text , markup )
121128 return
122129 raise
123- text , markup = format_scanning_message (data , scanner_status , "starting" )
124- await edit_message_text_anyway (message , text , markup )
125130
126131 scanning_result = asyncio .create_task (
127132 api_client .wait_and_merge_manual_scan (
@@ -138,14 +143,26 @@ async def continue_scan_handler(callback: CallbackQuery, state: FSMContext, pret
138143
139144 while time .monotonic () - start_time < max_wait_time :
140145 iteration += 1
141- # Exit if state changed (user clicked cancel)
146+
147+ # Return if the job was changed (user sent a new document or /scan)
148+ try :
149+ await ensure_same_structural_message (message , "confirmation_message_id" , state )
150+ except TelegramBadRequest :
151+ await scanning_result
152+ await api_client .cancel_manual_scan (message .chat .id , scanner_status .scanner , data ["scan_job_id" ])
153+ return
154+ # Return if the job was canceled
142155 if (await state .get_state ()) == default_state :
143- break
156+ await scanning_result
157+ await api_client .cancel_manual_scan (message .chat .id , scanner_status .scanner , data ["scan_job_id" ])
158+ return
144159
145- text , markup = format_scanning_message (data , scanner_status , "scanning" , iteration )
146- await edit_message_text_anyway (message , text , markup )
160+ text = format_scanning_message (data , scanner_status , "scanning" , iteration )
161+ message = await edit_message_text_anyway (message , text )
147162
148163 if scanning_result .done ():
164+ if not (scanning_result := await scanning_result ):
165+ return
149166 break
150167
151168 # Sleep for one second before next check
@@ -161,7 +178,7 @@ async def continue_scan_handler(callback: CallbackQuery, state: FSMContext, pret
161178 await edit_message_text_anyway (message , text , markup )
162179 return
163180
164- scanning_result = await scanning_result
181+ await api_client . cancel_manual_scan ( message . chat . id , scanner_status . scanner , data [ "scan_job_id" ])
165182 data = await state .update_data (
166183 scan_server_name = scanning_result .filename ,
167184 scan_result_pages_count = scanning_result .page_count ,
@@ -184,20 +201,12 @@ async def send_new_started_scan_confirmation_message_handler(callback: CallbackQ
184201 scanner_status = await api_client .get_scanner_status (callback .message .chat .id , data .get ("scanner" ))
185202 caption , markup = format_scanning_paused_message (data , scanner_status , is_finished = True )
186203 await edit_message_text_anyway (callback .message , caption , markup )
187- text , markup = format_scanning_message (data , scanner_status , "starting" )
188- msg = await callback .message .answer (text , reply_markup = markup )
204+ text = format_scanning_message (data , scanner_status , "starting" )
205+ msg = await callback .message .answer (text )
189206 await state .update_data (confirmation_message_id = msg .message_id )
190207 await start_new_scan_handler (callback , state , bot , msg )
191208
192209
193- @router .callback_query (ScanWork .scanning , ScanningCallback .filter (F .menu == "cancel" ))
194- async def scanning_cancel_handler (callback : CallbackQuery , state : FSMContext , bot : Bot ):
195- await callback .answer ()
196- await cancel_expiring (callback .message )
197- await gracefully_interrupt_scanning_state (callback , state , bot )
198- await go_to_default_state (callback , state )
199-
200-
201210@router .callback_query (CallbackFromConfirmationMessageFilter (), ScanningPausedCallback .filter (F .menu == "remove-last" ))
202211async def scanning_paused_remove_last_handler (
203212 callback : CallbackQuery , callback_data : ScanningPausedCallback , state : FSMContext , bot : Bot
0 commit comments