Skip to content

Commit b5f4afe

Browse files
Allow to set start time greater than end time in athkar.
1 parent 4c6a585 commit b5f4afe

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

core_functions/athkar/athkar_scheduler.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
from random import choice
77
from apscheduler.schedulers.background import BackgroundScheduler
88
from apscheduler.triggers.cron import CronTrigger
9-
from sqlalchemy.exc import IntegrityError
9+
from sqlalchemy.exc import IntegrityError
1010
from .athkar_db_manager import AthkarDBManager
1111
from .athkar_refresher import AthkarRefresher
1212
from utils.audio_player import AthkarPlayer
1313
from utils.const import Globals
14+
from utils.logger import Logger
15+
from exceptions.base import ErrorMessage
1416

1517
class AthkarScheduler:
1618
def __init__(self, athkar_db_folder: Union[Path, str], default_category_path: Optional[Union[Path, str]] = None, text_athkar_path: Optional[Union[Path, str]] = None, default_category_settings: Optional[Dict[str, int]] = None) -> None:
@@ -19,19 +21,18 @@ def __init__(self, athkar_db_folder: Union[Path, str], default_category_path: Op
1921
self.default_category_settings = default_category_settings if default_category_settings is not None else {}
2022
self.categories = None
2123
self.db_manager = AthkarDBManager(athkar_db_folder)
22-
self.scheduler = BackgroundScheduler()
24+
self.scheduler = BackgroundScheduler()
2325
self.setup()
2426

2527
def setup(self) -> None:
26-
2728
if self.default_category_path:
2829
self.default_category_path.mkdir(parents=True, exist_ok=True)
2930
try:
3031
category_id = self.db_manager.create_category("default", str(self.default_category_path), **self.default_category_settings)
3132
if self.text_athkar_path and self.text_athkar_path.exists():
3233
with open(self.text_athkar_path, encoding="UTF-8") as f:
3334
self.db_manager.add_text_athkar(json.load(f), category_id)
34-
except IntegrityError as e:
35+
except IntegrityError:
3536
pass
3637

3738
self.categories = self.db_manager.get_all_categories()
@@ -46,38 +47,62 @@ def audio_athkar_job(self, category_id: int, audio_path: str) -> None:
4647
def text_athkar_job(self, category_id: int) -> None:
4748
random_text_athkar = choice(self.db_manager.get_text_athkar(category_id))
4849
text = random_text_athkar.text
49-
50+
5051
if len(text) > 256:
51-
# Extract the first 5 words for the title
5252
title = " ".join(text.split()[:10])
5353
description = " ".join(text.split()[10:])
5454
else:
5555
title = "البيان"
5656
description = text
57-
57+
5858
Globals.TRAY_ICON.showMessage(title, description, msecs=5000)
5959

6060
@staticmethod
6161
def _parse_time(time_str: str) -> time:
62-
time_ob = datetime.strptime(time_str, "%H:%M")
63-
return time_ob
62+
return datetime.strptime(time_str, "%H:%M").time()
6463

65-
def start(self,) -> None:
64+
def _create_triggers(self, from_time: time, to_time: time, play_interval: int):
65+
minute = "0" if play_interval == 60 else f"*/{play_interval}"
66+
67+
if from_time < to_time:
68+
return [CronTrigger(minute=minute, hour=f"{from_time.hour}-{to_time.hour}")]
69+
else:
70+
return [
71+
CronTrigger(minute=minute, hour=f"{from_time.hour}-23"),
72+
CronTrigger(minute=minute, hour=f"0-{to_time.hour}")
73+
]
74+
75+
def _add_jobs(self, category, trigger):
76+
if category.audio_athkar_enabled:
77+
self.scheduler.add_job(
78+
self.audio_athkar_job,
79+
trigger,
80+
args=[category.id, category.audio_path],
81+
id=f"audio_athkar_{category.id}_{trigger}"
82+
)
83+
if category.text_athkar_enabled:
84+
self.scheduler.add_job(
85+
self.text_athkar_job,
86+
trigger,
87+
args=[category.id],
88+
id=f"text_athkar_{category.id}_{trigger}"
89+
)
90+
91+
def start(self) -> None:
6692
for category in self.categories:
67-
from_time = self._parse_time(category.from_time)
68-
to_time = self._parse_time(category.to_time)
69-
minute = "0" if category.play_interval == 60 else f"*/{category.play_interval}"
70-
trigger = CronTrigger(minute=minute, hour=f"{from_time.hour}-{to_time.hour}")
71-
if category.audio_athkar_enabled :
72-
self.scheduler.add_job(self.audio_athkar_job, trigger, args=[category.id, category.audio_path])
73-
if category.text_athkar_enabled:
74-
self.scheduler.add_job(self.text_athkar_job, trigger, args=[category.id])
93+
try:
94+
from_time = self._parse_time(category.from_time)
95+
to_time = self._parse_time(category.to_time)
96+
triggers = self._create_triggers(from_time, to_time, category.play_interval)
97+
for trigger in triggers:
98+
self._add_jobs(category, trigger)
99+
except Exception as e:
100+
Logger.error(ErrorMessage(e))
75101

76102
if not self.scheduler.running:
77103
self.scheduler.start()
78104

79105
def refresh(self) -> None:
80-
81106
if self.scheduler is not None:
82107
self.scheduler.remove_all_jobs()
83108

0 commit comments

Comments
 (0)