55import pathlib
66
77# Requirements
8+ from apscheduler .jobstores .base import JobLookupError
89from apscheduler .schedulers .asyncio import AsyncIOScheduler
10+ from apscheduler .triggers .date import DateTrigger
911from apscheduler .triggers .interval import IntervalTrigger
1012from databases import Database
1113from telebot import types
3638_ = translation .gettext
3739
3840
41+ scheduler = AsyncIOScheduler ()
42+
3943class NotificationManager :
40- def __init__ (self ):
41- self .jobs = {}
4244
43- async def add_job (self , chat_id , job_type , func , * args , ** kwargs ):
44- await self .remove_job (chat_id , job_type )
45- job = scheduler .add_job (func , * args , ** kwargs )
46- self .jobs [f"{ job_type } _{ chat_id } " ] = job
47- return job
45+ def add_job (self , chat_id , job_type , func , trigger ):
46+ job_id = f"{ job_type } _{ chat_id } "
47+ self .remove_job (chat_id , job_type )
48+ scheduler .add_job (func , trigger , id = job_id , args = [chat_id ])
4849
49- async def remove_job (self , chat_id , job_type ):
50+ def remove_job (self , chat_id , job_type ):
5051 job_id = f"{ job_type } _{ chat_id } "
51- if job_id in self .jobs :
52- try :
53- self .jobs [job_id ].remove ()
54- except Exception as e :
55- print (f"Error deleting task { job_id } : { e } " )
56- finally :
57- self .jobs .pop (job_id , None )
52+ try :
53+ scheduler .remove_job (job_id )
54+ except JobLookupError :
55+ pass
5856
59- async def remove_all_jobs (self , chat_id ):
57+ def remove_all_jobs (self , chat_id ):
6058 for job_type in ['water_check' , 'polyv_complete' ]:
61- await self .remove_job (chat_id , job_type )
59+ self .remove_job (chat_id , job_type )
6260
6361
6462notification_manager = NotificationManager ()
6563
6664
6765# Инициализация бота
6866bot = AsyncTeleBot (BOT_TOKEN )
69- scheduler = AsyncIOScheduler ()
7067
7168# Словари для хранения состояний
7269user_states = {}
7370user_irrigation_data = {} # Для хранения данных о поливе
74- notification_jobs = {} # Для хранения задач уведомлений
7571
7672# Таблица расхода воды (уровень в см -> расход в м³/мин)
7773WATER_FLOW_RATES = {
@@ -145,44 +141,29 @@ def create_reply_keyboard():
145141 return markup
146142
147143
148- async def start_irrigation_notifications (chat_id ):
149- await notification_manager .add_job (
150- chat_id ,
151- 'water_check' ,
152- send_water_check_notification ,
153- trigger = IntervalTrigger (minutes = 15 ),
154- args = [chat_id ]
155- )
144+ def start_irrigation_notifications (chat_id ):
145+ notification_manager .add_job (chat_id , 'water_check' , send_water_check_notification ,
146+ trigger = IntervalTrigger (minutes = 15 ))
156147
157148
158149async def send_water_check_notification (chat_id ):
159150 """Отправляет уведомление о проверке уровня воды"""
160151 if chat_id in user_irrigation_data :
161- await bot .send_message (
162- chat_id ,
163- _ ("🔄 Please check the current water level in the channel and send its value" )
164- )
152+ message = _ ("🔄 Please check the current water level in the channel and send its value" )
153+ await bot .send_message (chat_id , message )
165154
166155
167- async def schedule_polyv_completion_notification (chat_id , hours , minutes ):
156+ def schedule_polyv_completion_notification (chat_id , hours , minutes ):
168157 completion_time = datetime .now () + timedelta (hours = hours , minutes = minutes )
169- await notification_manager .add_job (
170- chat_id ,
171- 'polyv_complete' ,
172- notify_polyv_completion ,
173- trigger = 'date' ,
174- run_date = completion_time ,
175- args = [chat_id ]
176- )
158+ notification_manager .add_job (chat_id , 'polyv_complete' , notify_polyv_completion ,
159+ trigger = DateTrigger (run_date = completion_time ))
177160
178161
179162async def notify_polyv_completion (chat_id ):
180163 if chat_id in user_irrigation_data and user_irrigation_data [chat_id ].get ('is_active' , False ):
181- await bot .send_message (
182- chat_id ,
183- _ ("⏰ Watering time is over! Please click the 'Save data' button to save the results." )
184- )
185- await notification_manager .remove_job (chat_id , 'water_check' )
164+ message = _ ("⏰ Watering time is over! Please click the 'Save data' button to save the results." )
165+ await bot .send_message (chat_id , message )
166+ notification_manager .remove_job (chat_id , 'water_check' )
186167
187168
188169async def check_irrigation (chat_id ):
@@ -216,11 +197,8 @@ async def check_irrigation(chat_id):
216197 else :
217198 text = _ ("ERROR!" )
218199
219- await bot .send_message (
220- chat_id ,
221- text .format (first_name = row ['firstName' ], water = round (m3_needed , 2 )),
222- reply_markup = markup
223- )
200+ message = text .format (first_name = row ['firstName' ], water = round (m3_needed , 2 ))
201+ await bot .send_message (chat_id , message , reply_markup = markup )
224202 return True
225203 return False
226204
@@ -249,11 +227,11 @@ async def calculate_irrigation(chat_id, water_level, irrigation_need, area, ie,
249227 'total_needed_m3' : total_needed_m3 ,
250228 'total_used_m3' : 0 ,
251229 'history' : [(water_level , datetime .now ())],
252- 'is_active' : True
230+ 'is_active' : True ,
253231 }
254232
255- # Запускаем уведомления только для нового полива
256- await start_irrigation_notifications (chat_id )
233+ # We launch notifications only for new watering
234+ start_irrigation_notifications (chat_id )
257235 else :
258236 data = user_irrigation_data [chat_id ]
259237 time_elapsed = (datetime .now () - data ['last_update' ]).total_seconds ()
@@ -274,7 +252,7 @@ async def calculate_irrigation(chat_id, water_level, irrigation_need, area, ie,
274252 if remaining_time > 0 :
275253 hours = int (remaining_time )
276254 minutes = int ((remaining_time - hours ) * 60 )
277- await schedule_polyv_completion_notification (chat_id , hours , minutes )
255+ schedule_polyv_completion_notification (chat_id , hours , minutes )
278256
279257 return {
280258 'used_m3' : user_irrigation_data [chat_id ]['total_used_m3' ],
@@ -410,8 +388,8 @@ async def handle_water_level(message):
410388async def handle_send_data (message ):
411389 chat_id = message .chat .id
412390
413- # Останавливаем все уведомления
414- await notification_manager .remove_all_jobs (chat_id )
391+ # Stop all notifications
392+ notification_manager .remove_all_jobs (chat_id )
415393
416394 rows = await get_irrigation_data ()
417395 for row in rows :
0 commit comments