orionis 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orionis/__init__.py +0 -0
- orionis/cli_manager.py +48 -0
- orionis/framework.py +45 -0
- orionis/luminate/__init__.py +0 -0
- orionis/luminate/app.py +0 -0
- orionis/luminate/bootstrap/__init__.py +0 -0
- orionis/luminate/bootstrap/parser.py +49 -0
- orionis/luminate/bootstrap/register.py +95 -0
- orionis/luminate/cache/__init__.py +0 -0
- orionis/luminate/cache/app/__init__.py +0 -0
- orionis/luminate/cache/app/config.py +96 -0
- orionis/luminate/cache/console/__init__.py +0 -0
- orionis/luminate/cache/console/commands.py +98 -0
- orionis/luminate/config/__init__.py +0 -0
- orionis/luminate/config/dataclass/__init__.py +0 -0
- orionis/luminate/config/dataclass/app.py +50 -0
- orionis/luminate/config/dataclass/auth.py +17 -0
- orionis/luminate/config/dataclass/cache.py +51 -0
- orionis/luminate/config/dataclass/cors.py +58 -0
- orionis/luminate/config/dataclass/database.py +203 -0
- orionis/luminate/config/dataclass/filesystems.py +102 -0
- orionis/luminate/config/dataclass/logging.py +107 -0
- orionis/luminate/config/dataclass/mail.py +81 -0
- orionis/luminate/config/dataclass/queue.py +63 -0
- orionis/luminate/config/dataclass/session.py +59 -0
- orionis/luminate/config/environment.py +110 -0
- orionis/luminate/config/sections.py +37 -0
- orionis/luminate/console/__init__.py +0 -0
- orionis/luminate/console/base/__init__.py +0 -0
- orionis/luminate/console/base/command.py +427 -0
- orionis/luminate/console/cache.py +132 -0
- orionis/luminate/console/command.py +40 -0
- orionis/luminate/console/command_filter.py +40 -0
- orionis/luminate/console/commands/__init__.py +0 -0
- orionis/luminate/console/commands/cache_clear.py +56 -0
- orionis/luminate/console/commands/help.py +59 -0
- orionis/luminate/console/commands/schedule_work.py +50 -0
- orionis/luminate/console/commands/tests.py +40 -0
- orionis/luminate/console/commands/version.py +39 -0
- orionis/luminate/console/exceptions/__init__.py +0 -0
- orionis/luminate/console/exceptions/cli_exception.py +125 -0
- orionis/luminate/console/kernel.py +32 -0
- orionis/luminate/console/output/__init__.py +0 -0
- orionis/luminate/console/output/console.py +426 -0
- orionis/luminate/console/output/executor.py +90 -0
- orionis/luminate/console/output/progress_bar.py +100 -0
- orionis/luminate/console/output/styles.py +95 -0
- orionis/luminate/console/parser.py +159 -0
- orionis/luminate/console/register.py +98 -0
- orionis/luminate/console/runner.py +126 -0
- orionis/luminate/console/scripts/__init__.py +0 -0
- orionis/luminate/console/scripts/management.py +94 -0
- orionis/luminate/console/tasks/__init__.py +0 -0
- orionis/luminate/console/tasks/scheduler.py +616 -0
- orionis/luminate/contracts/__init__.py +0 -0
- orionis/luminate/contracts/bootstrap/parser_interface.py +46 -0
- orionis/luminate/contracts/cache/__init__.py +0 -0
- orionis/luminate/contracts/cache/cache_commands_interface.py +69 -0
- orionis/luminate/contracts/config/__init__.py +0 -0
- orionis/luminate/contracts/config/config_interface.py +27 -0
- orionis/luminate/contracts/config/environment_interface.py +64 -0
- orionis/luminate/contracts/console/__init__.py +0 -0
- orionis/luminate/contracts/console/base_command_interface.py +448 -0
- orionis/luminate/contracts/console/cli_cache_interface.py +34 -0
- orionis/luminate/contracts/console/command_filter_interface.py +32 -0
- orionis/luminate/contracts/console/command_interface.py +36 -0
- orionis/luminate/contracts/console/console_interface.py +305 -0
- orionis/luminate/contracts/console/executor_interface.py +51 -0
- orionis/luminate/contracts/console/kernel_interface.py +32 -0
- orionis/luminate/contracts/console/management_interface.py +63 -0
- orionis/luminate/contracts/console/parser_interface.py +76 -0
- orionis/luminate/contracts/console/progress_bar_interface.py +66 -0
- orionis/luminate/contracts/console/register_interface.py +32 -0
- orionis/luminate/contracts/console/runner_interface.py +50 -0
- orionis/luminate/contracts/console/schedule_interface.py +317 -0
- orionis/luminate/contracts/console/task_manager_interface.py +37 -0
- orionis/luminate/contracts/facades/__init__.py +0 -0
- orionis/luminate/contracts/facades/env_interface.py +64 -0
- orionis/luminate/contracts/facades/log_interface.py +48 -0
- orionis/luminate/contracts/facades/paths_interface.py +141 -0
- orionis/luminate/contracts/facades/tests_interface.py +33 -0
- orionis/luminate/contracts/files/__init__.py +0 -0
- orionis/luminate/contracts/files/paths_interface.py +29 -0
- orionis/luminate/contracts/installer/__init__.py +0 -0
- orionis/luminate/contracts/installer/output_interface.py +125 -0
- orionis/luminate/contracts/installer/setup_interface.py +29 -0
- orionis/luminate/contracts/installer/upgrade_interface.py +24 -0
- orionis/luminate/contracts/log/__init__.py +0 -0
- orionis/luminate/contracts/log/logger_interface.py +33 -0
- orionis/luminate/contracts/pipelines/cli_pipeline_interface.py +84 -0
- orionis/luminate/contracts/publisher/__init__.py +0 -0
- orionis/luminate/contracts/publisher/pypi_publisher_interface.py +36 -0
- orionis/luminate/contracts/test/__init__.py +0 -0
- orionis/luminate/contracts/test/unit_test_interface.py +51 -0
- orionis/luminate/contracts/tools/__init__.py +0 -0
- orionis/luminate/contracts/tools/reflection_interface.py +343 -0
- orionis/luminate/contracts/tools/std_interface.py +56 -0
- orionis/luminate/facades/__init__.py +0 -0
- orionis/luminate/facades/environment.py +81 -0
- orionis/luminate/facades/log.py +56 -0
- orionis/luminate/facades/paths.py +268 -0
- orionis/luminate/facades/tests.py +48 -0
- orionis/luminate/files/__init__.py +0 -0
- orionis/luminate/files/paths.py +56 -0
- orionis/luminate/installer/__init__.py +0 -0
- orionis/luminate/installer/icon.ascii +11 -0
- orionis/luminate/installer/info.ascii +13 -0
- orionis/luminate/installer/output.py +188 -0
- orionis/luminate/installer/setup.py +191 -0
- orionis/luminate/installer/upgrade.py +42 -0
- orionis/luminate/log/__init__.py +0 -0
- orionis/luminate/log/logger.py +116 -0
- orionis/luminate/pipelines/__init__.py +0 -0
- orionis/luminate/pipelines/cli_pipeline.py +116 -0
- orionis/luminate/publisher/__init__.py +0 -0
- orionis/luminate/publisher/pypi.py +206 -0
- orionis/luminate/static/logos/flaskavel.png +0 -0
- orionis/luminate/test/__init__.py +0 -0
- orionis/luminate/test/exception.py +48 -0
- orionis/luminate/test/unit_test.py +108 -0
- orionis/luminate/tools/__init__.py +0 -0
- orionis/luminate/tools/reflection.py +390 -0
- orionis/luminate/tools/std.py +53 -0
- orionis-0.1.0.dist-info/LICENCE +21 -0
- orionis-0.1.0.dist-info/METADATA +27 -0
- orionis-0.1.0.dist-info/RECORD +133 -0
- orionis-0.1.0.dist-info/WHEEL +5 -0
- orionis-0.1.0.dist-info/entry_points.txt +2 -0
- orionis-0.1.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/tools/__init__.py +0 -0
- tests/tools/class_example.py +50 -0
- tests/tools/test_reflection.py +128 -0
@@ -0,0 +1,616 @@
|
|
1
|
+
import re
|
2
|
+
import sys
|
3
|
+
import time
|
4
|
+
import logging
|
5
|
+
from typing import Any
|
6
|
+
from datetime import datetime
|
7
|
+
from apscheduler.triggers.cron import CronTrigger
|
8
|
+
from orionis.luminate.console.command import Command
|
9
|
+
from apscheduler.triggers.interval import IntervalTrigger
|
10
|
+
from apscheduler.schedulers.background import BackgroundScheduler
|
11
|
+
from orionis.luminate.contracts.console.schedule_interface import ISchedule
|
12
|
+
from orionis.luminate.console.exceptions.cli_exception import CLIOrionisScheduleException
|
13
|
+
|
14
|
+
class Schedule(ISchedule):
|
15
|
+
"""
|
16
|
+
A class that manages the scheduling of tasks using the APScheduler.
|
17
|
+
|
18
|
+
Attributes
|
19
|
+
----------
|
20
|
+
scheduler : BackgroundScheduler
|
21
|
+
The background scheduler instance used to schedule tasks.
|
22
|
+
callback : function | None
|
23
|
+
A callback function that will be called when the scheduled task is triggered.
|
24
|
+
|
25
|
+
Methods
|
26
|
+
-------
|
27
|
+
command(signature: str, vars: dict[str, Any] = {}, *args: Any, **kwargs: Any) -> 'Schedule':
|
28
|
+
Defines a command to execute.
|
29
|
+
"""
|
30
|
+
|
31
|
+
def __init__(self, logger_level=logging.CRITICAL):
|
32
|
+
"""
|
33
|
+
Initializes the Schedule object.
|
34
|
+
|
35
|
+
This method sets up the background scheduler, starts it, and configures the logging level for APScheduler.
|
36
|
+
|
37
|
+
Parameters
|
38
|
+
----------
|
39
|
+
logger_level : int, optional
|
40
|
+
The logging level for the APScheduler logger. Default is `logging.CRITICAL` to suppress most logs.
|
41
|
+
"""
|
42
|
+
logging.getLogger("apscheduler").setLevel(logger_level)
|
43
|
+
self.scheduler = BackgroundScheduler()
|
44
|
+
self.scheduler.start()
|
45
|
+
self.callback = None
|
46
|
+
self.wait = True
|
47
|
+
|
48
|
+
def command(self, signature: str, vars: dict[str, Any] = {}, *args: Any, **kwargs: Any) -> 'Schedule':
|
49
|
+
"""
|
50
|
+
Defines a Orionis command to be executed.
|
51
|
+
|
52
|
+
Parameters
|
53
|
+
----------
|
54
|
+
signature : str
|
55
|
+
The signature of the command to execute.
|
56
|
+
vars : dict, optional
|
57
|
+
A dictionary of variables to pass to the command, by default an empty dictionary.
|
58
|
+
*args : Any
|
59
|
+
Additional positional arguments to pass to the command.
|
60
|
+
**kwargs : Any
|
61
|
+
Additional keyword arguments to pass to the command.
|
62
|
+
|
63
|
+
Returns
|
64
|
+
-------
|
65
|
+
Schedule
|
66
|
+
Returns the Schedule instance itself, allowing method chaining.
|
67
|
+
"""
|
68
|
+
# Store the command logic as a lambda function
|
69
|
+
def func():
|
70
|
+
try:
|
71
|
+
Command.call(signature, vars, *args, **kwargs)
|
72
|
+
finally:
|
73
|
+
if not self.scheduler.get_jobs():
|
74
|
+
self.wait = False
|
75
|
+
|
76
|
+
self.callback = func
|
77
|
+
return self
|
78
|
+
|
79
|
+
def _checkCommand(self):
|
80
|
+
"""
|
81
|
+
Raises an exception to test the exception handling in the CLI.
|
82
|
+
"""
|
83
|
+
if not self.callback:
|
84
|
+
raise CLIOrionisScheduleException("No command has been defined to execute.")
|
85
|
+
|
86
|
+
def _resetCallback(self):
|
87
|
+
"""
|
88
|
+
Resets the callback function to None.
|
89
|
+
"""
|
90
|
+
self.callback = None
|
91
|
+
|
92
|
+
def _hourFormat(self, at: str):
|
93
|
+
"""
|
94
|
+
Validates the time format in 'HH:MM' 24-hour format.
|
95
|
+
"""
|
96
|
+
if not isinstance(at, str):
|
97
|
+
raise CLIOrionisScheduleException("Time must be a string in 'HH:MM' format. Example: '23:59'.")
|
98
|
+
|
99
|
+
# Regular expression for the "HH:MM" 24-hour format
|
100
|
+
pattern = r"^(?:[01]\d|2[0-3]):[0-5]\d$"
|
101
|
+
|
102
|
+
if not re.match(pattern, at):
|
103
|
+
raise CLIOrionisScheduleException("Invalid time format. Expected 'HH:MM' (24-hour format). Example: '23:59'.")
|
104
|
+
|
105
|
+
return at.split(':')
|
106
|
+
|
107
|
+
def _checkDateTime(self, start_date: datetime = None, end_date: datetime = None):
|
108
|
+
"""
|
109
|
+
Validates the `start_date` and `end_date` parameters.
|
110
|
+
|
111
|
+
Ensures that both parameters are either `None` or valid `datetime` instances.
|
112
|
+
Additionally, it verifies that `start_date` is earlier than `end_date` if both are provided.
|
113
|
+
|
114
|
+
Parameters
|
115
|
+
----------
|
116
|
+
start_date : datetime, optional
|
117
|
+
The start time of the scheduled job. Must be a valid `datetime` object if provided.
|
118
|
+
end_date : datetime, optional
|
119
|
+
The end time of the scheduled job. Must be a valid `datetime` object if provided.
|
120
|
+
|
121
|
+
Raises
|
122
|
+
------
|
123
|
+
CLIOrionisScheduleException
|
124
|
+
If `start_date` or `end_date` are not valid `datetime` objects.
|
125
|
+
If `start_date` is later than or equal to `end_date`.
|
126
|
+
"""
|
127
|
+
|
128
|
+
# Ensure `start_date` is either None or a valid datetime object
|
129
|
+
if start_date is not None and not isinstance(start_date, datetime):
|
130
|
+
raise CLIOrionisScheduleException("start_date must be a valid datetime object.")
|
131
|
+
|
132
|
+
# Ensure `end_date` is either None or a valid datetime object
|
133
|
+
if end_date is not None and not isinstance(end_date, datetime):
|
134
|
+
raise CLIOrionisScheduleException("end_date must be a valid datetime object.")
|
135
|
+
|
136
|
+
# Ensure `start_date` is earlier than `end_date` if both are provided
|
137
|
+
if start_date and end_date and start_date >= end_date:
|
138
|
+
raise CLIOrionisScheduleException("start_date must be earlier than end_date.")
|
139
|
+
|
140
|
+
def _checkGreterThanZero(self, value: int, identifier: str = 'interval'):
|
141
|
+
"""
|
142
|
+
Validates that the value is greater than 0.
|
143
|
+
"""
|
144
|
+
if value < 1:
|
145
|
+
raise CLIOrionisScheduleException(f"The {identifier} must be greater than 0.")
|
146
|
+
|
147
|
+
def onceAt(self, date: datetime):
|
148
|
+
"""
|
149
|
+
Schedule the defined command to execute every X seconds.
|
150
|
+
"""
|
151
|
+
self._checkCommand()
|
152
|
+
|
153
|
+
if not isinstance(date, datetime):
|
154
|
+
raise CLIOrionisScheduleException("The date must be a valid datetime object.")
|
155
|
+
|
156
|
+
self.scheduler.add_job(
|
157
|
+
self.callback,
|
158
|
+
'date',
|
159
|
+
run_date=date
|
160
|
+
)
|
161
|
+
|
162
|
+
self._resetCallback()
|
163
|
+
|
164
|
+
def everySeconds(self, seconds: int, start_date: datetime = None, end_date: datetime = None):
|
165
|
+
"""
|
166
|
+
Schedule the defined command to execute every X seconds.
|
167
|
+
"""
|
168
|
+
self._checkCommand()
|
169
|
+
self._checkGreterThanZero(seconds)
|
170
|
+
self._checkDateTime(start_date, end_date)
|
171
|
+
|
172
|
+
self.scheduler.add_job(
|
173
|
+
self.callback,
|
174
|
+
IntervalTrigger(seconds=seconds, start_date=start_date, end_date=end_date),
|
175
|
+
replace_existing=True
|
176
|
+
)
|
177
|
+
|
178
|
+
self._resetCallback()
|
179
|
+
|
180
|
+
def everySecond(self, start_date: datetime = None, end_date: datetime = None):
|
181
|
+
"""
|
182
|
+
Schedules the defined command to execute every second.
|
183
|
+
"""
|
184
|
+
self.everySeconds(seconds=1, start_date=start_date, end_date=end_date)
|
185
|
+
|
186
|
+
def everyTwoSeconds(self, start_date: datetime = None, end_date: datetime = None):
|
187
|
+
"""
|
188
|
+
Schedules the defined command to execute every two seconds.
|
189
|
+
"""
|
190
|
+
self.everySeconds(seconds=2, start_date=start_date, end_date=end_date)
|
191
|
+
|
192
|
+
def everyFiveSeconds(self, start_date: datetime = None, end_date: datetime = None):
|
193
|
+
"""
|
194
|
+
Schedules the defined command to execute every five seconds.
|
195
|
+
"""
|
196
|
+
self.everySeconds(seconds=5, start_date=start_date, end_date=end_date)
|
197
|
+
|
198
|
+
def everyTenSeconds(self, start_date: datetime = None, end_date: datetime = None):
|
199
|
+
"""
|
200
|
+
Schedules the defined command to execute every ten seconds.
|
201
|
+
"""
|
202
|
+
self.everySeconds(seconds=10, start_date=start_date, end_date=end_date)
|
203
|
+
|
204
|
+
def everyFifteenSeconds(self, start_date: datetime = None, end_date: datetime = None):
|
205
|
+
"""
|
206
|
+
Schedules the defined command to execute every fifteen seconds.
|
207
|
+
"""
|
208
|
+
self.everySeconds(seconds=15, start_date=start_date, end_date=end_date)
|
209
|
+
|
210
|
+
def everyTwentySeconds(self, start_date: datetime = None, end_date: datetime = None):
|
211
|
+
"""
|
212
|
+
Schedules the defined command to execute every twenty seconds.
|
213
|
+
"""
|
214
|
+
self.everySeconds(seconds=20, start_date=start_date, end_date=end_date)
|
215
|
+
|
216
|
+
def everyThirtySeconds(self, start_date: datetime = None, end_date: datetime = None):
|
217
|
+
"""
|
218
|
+
Schedules the defined command to execute every thirty seconds.
|
219
|
+
"""
|
220
|
+
self.everySeconds(seconds=30, start_date=start_date, end_date=end_date)
|
221
|
+
|
222
|
+
def everyMinutes(self, minutes: int, start_date: datetime = None, end_date: datetime = None):
|
223
|
+
"""
|
224
|
+
Schedules the defined command to execute every X minutes.
|
225
|
+
"""
|
226
|
+
self._checkCommand()
|
227
|
+
self._checkGreterThanZero(minutes)
|
228
|
+
self._checkDateTime(start_date, end_date)
|
229
|
+
|
230
|
+
self.scheduler.add_job(
|
231
|
+
self.callback,
|
232
|
+
IntervalTrigger(minutes=minutes, start_date=start_date, end_date=end_date),
|
233
|
+
replace_existing=True
|
234
|
+
)
|
235
|
+
|
236
|
+
self._resetCallback()
|
237
|
+
|
238
|
+
def everyMinute(self, start_date: datetime = None, end_date: datetime = None):
|
239
|
+
"""
|
240
|
+
Schedules the defined command to execute every minute.
|
241
|
+
"""
|
242
|
+
self.everyMinutes(minutes=1, start_date=start_date, end_date=end_date)
|
243
|
+
|
244
|
+
def everyTwoMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
245
|
+
"""
|
246
|
+
Schedules the defined command to execute every two minutes.
|
247
|
+
"""
|
248
|
+
self.everyMinutes(minutes=2, start_date=start_date, end_date=end_date)
|
249
|
+
|
250
|
+
def everyThreeMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
251
|
+
"""
|
252
|
+
Schedules the defined command to execute every three minutes.
|
253
|
+
"""
|
254
|
+
self.everyMinutes(minutes=3, start_date=start_date, end_date=end_date)
|
255
|
+
|
256
|
+
def everyFourMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
257
|
+
"""
|
258
|
+
Schedules the defined command to execute every four minutes.
|
259
|
+
"""
|
260
|
+
self.everyMinutes(minutes=4, start_date=start_date, end_date=end_date)
|
261
|
+
|
262
|
+
def everyFiveMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
263
|
+
"""
|
264
|
+
Schedules the defined command to execute every five minutes.
|
265
|
+
"""
|
266
|
+
self.everyMinutes(minutes=5, start_date=start_date, end_date=end_date)
|
267
|
+
|
268
|
+
def everyTenMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
269
|
+
"""
|
270
|
+
Schedules the defined command to execute every ten minutes.
|
271
|
+
"""
|
272
|
+
self.everyMinutes(minutes=10, start_date=start_date, end_date=end_date)
|
273
|
+
|
274
|
+
def everyFifteenMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
275
|
+
"""
|
276
|
+
Schedules the defined command to execute every fifteen minutes.
|
277
|
+
"""
|
278
|
+
self.everyMinutes(minutes=15, start_date=start_date, end_date=end_date)
|
279
|
+
|
280
|
+
def everyThirtyMinutes(self, start_date: datetime = None, end_date: datetime = None):
|
281
|
+
"""
|
282
|
+
Schedules the defined command to execute every thirty minutes.
|
283
|
+
"""
|
284
|
+
self.everyMinutes(minutes=30, start_date=start_date, end_date=end_date)
|
285
|
+
|
286
|
+
def hours(self, hours: int, start_date: datetime = None, end_date: datetime = None):
|
287
|
+
"""
|
288
|
+
Schedules the defined command to execute every X hours.
|
289
|
+
"""
|
290
|
+
self._checkCommand()
|
291
|
+
self._checkGreterThanZero(hours)
|
292
|
+
self._checkDateTime(start_date, end_date)
|
293
|
+
|
294
|
+
self.scheduler.add_job(
|
295
|
+
self.callback,
|
296
|
+
IntervalTrigger(hours=hours, start_date=start_date, end_date=end_date),
|
297
|
+
replace_existing=True
|
298
|
+
)
|
299
|
+
|
300
|
+
self._resetCallback()
|
301
|
+
|
302
|
+
def hourly(self, start_date: datetime = None, end_date: datetime = None):
|
303
|
+
"""
|
304
|
+
Schedules the defined command to execute every hour.
|
305
|
+
"""
|
306
|
+
self.hours(hours=1, start_date=start_date, end_date=end_date)
|
307
|
+
|
308
|
+
def hourlyAt(self, minute: int, start_date: datetime = None, end_date: datetime = None):
|
309
|
+
"""
|
310
|
+
Schedules the defined command to execute every hour at a specific minute.
|
311
|
+
"""
|
312
|
+
self._checkCommand()
|
313
|
+
self._checkGreterThanZero(minute)
|
314
|
+
self._checkDateTime(start_date, end_date)
|
315
|
+
|
316
|
+
self.scheduler.add_job(
|
317
|
+
self.callback,
|
318
|
+
CronTrigger(hour='*', minute=minute, start_date=start_date, end_date=end_date),
|
319
|
+
replace_existing=True
|
320
|
+
)
|
321
|
+
|
322
|
+
self._resetCallback()
|
323
|
+
|
324
|
+
def everyOddHour(self, minute: int, start_date: datetime = None, end_date: datetime = None):
|
325
|
+
"""
|
326
|
+
Schedules the defined command to execute every odd hour.
|
327
|
+
"""
|
328
|
+
self._checkCommand()
|
329
|
+
self._checkGreterThanZero(minute)
|
330
|
+
self._checkDateTime(start_date, end_date)
|
331
|
+
|
332
|
+
self.scheduler.add_job(
|
333
|
+
self.callback,
|
334
|
+
CronTrigger(hour='1,3,5,7,9,11,13,15,17,19,21,23', minute=minute, start_date=start_date, end_date=end_date),
|
335
|
+
replace_existing=True
|
336
|
+
)
|
337
|
+
|
338
|
+
self._resetCallback()
|
339
|
+
|
340
|
+
def everyTwoHours(self, minute: int, start_date: datetime = None, end_date: datetime = None):
|
341
|
+
"""
|
342
|
+
Schedules the defined command to execute every two hours.
|
343
|
+
"""
|
344
|
+
self._checkCommand()
|
345
|
+
self._checkGreterThanZero(minute)
|
346
|
+
self._checkDateTime(start_date, end_date)
|
347
|
+
|
348
|
+
self.scheduler.add_job(
|
349
|
+
self.callback,
|
350
|
+
CronTrigger(hour='*/2', minute=minute, start_date=start_date, end_date=end_date),
|
351
|
+
replace_existing=True
|
352
|
+
)
|
353
|
+
|
354
|
+
self._resetCallback()
|
355
|
+
|
356
|
+
def everyThreeHours(self, minute: int, start_date: datetime = None, end_date: datetime = None):
|
357
|
+
"""
|
358
|
+
Schedules the defined command to execute every three hours.
|
359
|
+
"""
|
360
|
+
self._checkCommand()
|
361
|
+
self._checkGreterThanZero(minute)
|
362
|
+
self._checkDateTime(start_date, end_date)
|
363
|
+
|
364
|
+
self.scheduler.add_job(
|
365
|
+
self.callback,
|
366
|
+
CronTrigger(hour='*/3', minute=minute, start_date=start_date, end_date=end_date),
|
367
|
+
replace_existing=True
|
368
|
+
)
|
369
|
+
|
370
|
+
self._resetCallback()
|
371
|
+
|
372
|
+
def everyFourHours(self, minute: int, start_date: datetime = None, end_date: datetime = None):
|
373
|
+
"""
|
374
|
+
Schedules the defined command to execute every four hours.
|
375
|
+
"""
|
376
|
+
self._checkCommand()
|
377
|
+
self._checkGreterThanZero(minute)
|
378
|
+
self._checkDateTime(start_date, end_date)
|
379
|
+
|
380
|
+
self.scheduler.add_job(
|
381
|
+
self.callback,
|
382
|
+
CronTrigger(hour='*/4', minute=minute, start_date=start_date, end_date=end_date),
|
383
|
+
replace_existing=True
|
384
|
+
)
|
385
|
+
|
386
|
+
self._resetCallback()
|
387
|
+
|
388
|
+
def everySixHours(self, minute: int, start_date: datetime = None, end_date: datetime = None):
|
389
|
+
"""
|
390
|
+
Schedules the defined command to execute every six hours.
|
391
|
+
"""
|
392
|
+
self._checkCommand()
|
393
|
+
self._checkGreterThanZero(minute)
|
394
|
+
self._checkDateTime(start_date, end_date)
|
395
|
+
|
396
|
+
self.scheduler.add_job(
|
397
|
+
self.callback,
|
398
|
+
CronTrigger(hour='*/6', minute=minute, start_date=start_date, end_date=end_date),
|
399
|
+
replace_existing=True
|
400
|
+
)
|
401
|
+
|
402
|
+
self._resetCallback()
|
403
|
+
|
404
|
+
def days(self, days: int, start_date: datetime = None, end_date: datetime = None):
|
405
|
+
"""
|
406
|
+
Schedules the defined command to execute every X days.
|
407
|
+
"""
|
408
|
+
self._checkCommand()
|
409
|
+
self._checkGreterThanZero(days)
|
410
|
+
self._checkDateTime(start_date, end_date)
|
411
|
+
|
412
|
+
self.scheduler.add_job(
|
413
|
+
self.callback,
|
414
|
+
IntervalTrigger(days=days, start_date=start_date, end_date=end_date),
|
415
|
+
replace_existing=True
|
416
|
+
)
|
417
|
+
|
418
|
+
self._resetCallback()
|
419
|
+
|
420
|
+
def daily(self, start_date: datetime = None, end_date: datetime = None):
|
421
|
+
"""
|
422
|
+
Schedules the defined command to execute daily at midnight.
|
423
|
+
"""
|
424
|
+
self._checkCommand()
|
425
|
+
self._checkDateTime(start_date, end_date)
|
426
|
+
|
427
|
+
self.scheduler.add_job(
|
428
|
+
self.callback,
|
429
|
+
CronTrigger(hour=0, minute=0, second=1, start_date=start_date, end_date=end_date),
|
430
|
+
replace_existing=True
|
431
|
+
)
|
432
|
+
|
433
|
+
self._resetCallback()
|
434
|
+
|
435
|
+
def dailyAt(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
436
|
+
"""
|
437
|
+
Schedules the defined command to execute daily at a specific time.
|
438
|
+
"""
|
439
|
+
self._checkCommand()
|
440
|
+
self._checkDateTime(start_date, end_date)
|
441
|
+
hour, minute = self._hourFormat(at)
|
442
|
+
|
443
|
+
self.scheduler.add_job(
|
444
|
+
self.callback,
|
445
|
+
CronTrigger(hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
446
|
+
replace_existing=True
|
447
|
+
)
|
448
|
+
|
449
|
+
self._resetCallback()
|
450
|
+
|
451
|
+
def twiceDaily(self, first_hour: int, second_hour: int, start_date: datetime = None, end_date: datetime = None):
|
452
|
+
"""
|
453
|
+
Schedules the defined command to execute twice a day at specific hours.
|
454
|
+
"""
|
455
|
+
self._checkCommand()
|
456
|
+
self._checkGreterThanZero(first_hour)
|
457
|
+
self._checkGreterThanZero(second_hour)
|
458
|
+
self._checkDateTime(start_date, end_date)
|
459
|
+
|
460
|
+
self.scheduler.add_job(
|
461
|
+
self.callback,
|
462
|
+
CronTrigger(hour=f'{first_hour},{second_hour}', minute=0, start_date=start_date, end_date=end_date),
|
463
|
+
replace_existing=True
|
464
|
+
)
|
465
|
+
|
466
|
+
self._resetCallback()
|
467
|
+
|
468
|
+
def monday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
469
|
+
"""
|
470
|
+
Schedules the defined command to execute every Monday at a specific time.
|
471
|
+
"""
|
472
|
+
|
473
|
+
self._checkCommand()
|
474
|
+
self._checkDateTime(start_date, end_date)
|
475
|
+
hour, minute = self._hourFormat(at)
|
476
|
+
|
477
|
+
self.scheduler.add_job(
|
478
|
+
self.callback,
|
479
|
+
CronTrigger(day_of_week='mon', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
480
|
+
replace_existing=True
|
481
|
+
)
|
482
|
+
|
483
|
+
self._resetCallback()
|
484
|
+
|
485
|
+
def tuesday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
486
|
+
"""
|
487
|
+
Schedules the defined command to execute every tuesday at a specific time.
|
488
|
+
"""
|
489
|
+
|
490
|
+
self._checkCommand()
|
491
|
+
self._checkDateTime(start_date, end_date)
|
492
|
+
hour, minute = self._hourFormat(at)
|
493
|
+
|
494
|
+
self.scheduler.add_job(
|
495
|
+
self.callback,
|
496
|
+
CronTrigger(day_of_week='tue', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
497
|
+
replace_existing=True
|
498
|
+
)
|
499
|
+
|
500
|
+
self._resetCallback()
|
501
|
+
|
502
|
+
def wednesday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
503
|
+
"""
|
504
|
+
Schedules the defined command to execute every wednesday at a specific time.
|
505
|
+
"""
|
506
|
+
|
507
|
+
self._checkCommand()
|
508
|
+
self._checkDateTime(start_date, end_date)
|
509
|
+
hour, minute = self._hourFormat(at)
|
510
|
+
|
511
|
+
self.scheduler.add_job(
|
512
|
+
self.callback,
|
513
|
+
CronTrigger(day_of_week='wed', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
514
|
+
replace_existing=True
|
515
|
+
)
|
516
|
+
|
517
|
+
self._resetCallback()
|
518
|
+
|
519
|
+
def thursday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
520
|
+
"""
|
521
|
+
Schedules the defined command to execute every thursday at a specific time.
|
522
|
+
"""
|
523
|
+
|
524
|
+
self._checkCommand()
|
525
|
+
self._checkDateTime(start_date, end_date)
|
526
|
+
hour, minute = self._hourFormat(at)
|
527
|
+
|
528
|
+
self.scheduler.add_job(
|
529
|
+
self.callback,
|
530
|
+
CronTrigger(day_of_week='thu', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
531
|
+
replace_existing=True
|
532
|
+
)
|
533
|
+
|
534
|
+
self._resetCallback()
|
535
|
+
|
536
|
+
def friday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
537
|
+
"""
|
538
|
+
Schedules the defined command to execute every friday at a specific time.
|
539
|
+
"""
|
540
|
+
|
541
|
+
self._checkCommand()
|
542
|
+
self._checkDateTime(start_date, end_date)
|
543
|
+
hour, minute = self._hourFormat(at)
|
544
|
+
|
545
|
+
self.scheduler.add_job(
|
546
|
+
self.callback,
|
547
|
+
CronTrigger(day_of_week='fri', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
548
|
+
replace_existing=True
|
549
|
+
)
|
550
|
+
|
551
|
+
self._resetCallback()
|
552
|
+
|
553
|
+
def saturday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
554
|
+
"""
|
555
|
+
Schedules the defined command to execute every saturday at a specific time.
|
556
|
+
"""
|
557
|
+
|
558
|
+
self._checkCommand()
|
559
|
+
self._checkDateTime(start_date, end_date)
|
560
|
+
hour, minute = self._hourFormat(at)
|
561
|
+
|
562
|
+
self.scheduler.add_job(
|
563
|
+
self.callback,
|
564
|
+
CronTrigger(day_of_week='sat', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
565
|
+
replace_existing=True
|
566
|
+
)
|
567
|
+
|
568
|
+
self._resetCallback()
|
569
|
+
|
570
|
+
def sunday(self, at: str, start_date: datetime = None, end_date: datetime = None):
|
571
|
+
"""
|
572
|
+
Schedules the defined command to execute every sunday at a specific time.
|
573
|
+
"""
|
574
|
+
|
575
|
+
self._checkCommand()
|
576
|
+
self._checkDateTime(start_date, end_date)
|
577
|
+
hour, minute = self._hourFormat(at)
|
578
|
+
|
579
|
+
self.scheduler.add_job(
|
580
|
+
self.callback,
|
581
|
+
CronTrigger(day_of_week='sun', hour=hour, minute=minute, start_date=start_date, end_date=end_date),
|
582
|
+
replace_existing=True
|
583
|
+
)
|
584
|
+
|
585
|
+
self._resetCallback()
|
586
|
+
|
587
|
+
def weekly(self, start_date: datetime = None, end_date: datetime = None):
|
588
|
+
"""
|
589
|
+
Schedules the defined command to execute weekly on Sunday at midnight.
|
590
|
+
"""
|
591
|
+
|
592
|
+
self._checkCommand()
|
593
|
+
self._checkDateTime(start_date, end_date)
|
594
|
+
|
595
|
+
self.scheduler.add_job(
|
596
|
+
self.callback,
|
597
|
+
CronTrigger(day_of_week='sun', hour=0, minute=0, second=1, start_date=start_date, end_date=end_date),
|
598
|
+
replace_existing=True
|
599
|
+
)
|
600
|
+
|
601
|
+
self._resetCallback()
|
602
|
+
|
603
|
+
def start(self):
|
604
|
+
"""
|
605
|
+
Starts the scheduler and stops automatically when there are no more jobs.
|
606
|
+
"""
|
607
|
+
try:
|
608
|
+
# Start the scheduler
|
609
|
+
while self.wait:
|
610
|
+
time.sleep(1)
|
611
|
+
except (KeyboardInterrupt, SystemExit):
|
612
|
+
# Stop the scheduler if it is running
|
613
|
+
if self.scheduler.running:
|
614
|
+
self.scheduler.shutdown()
|
615
|
+
# Exit with status code 1 to indicate an error
|
616
|
+
sys.exit(1)
|
File without changes
|
@@ -0,0 +1,46 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Any
|
3
|
+
|
4
|
+
class IParser(ABC):
|
5
|
+
"""
|
6
|
+
A class responsible for parsing an instance's configuration and outputting it as a dictionary.
|
7
|
+
|
8
|
+
This class uses Python's `dataclasses.asdict()` method to convert an instance's `config` attribute to a dictionary.
|
9
|
+
|
10
|
+
Methods
|
11
|
+
-------
|
12
|
+
parse(instance: Any) -> dict
|
13
|
+
Takes an instance with a `config` attribute and returns its dictionary representation.
|
14
|
+
|
15
|
+
Notes
|
16
|
+
-----
|
17
|
+
- This method expects the instance to have a `config` attribute that is a dataclass or any object that supports `asdict()`.
|
18
|
+
- The `asdict()` function will recursively convert dataclass fields into a dictionary format.
|
19
|
+
- If `instance.config` is not a dataclass, this could raise an exception depending on the type.
|
20
|
+
"""
|
21
|
+
|
22
|
+
@abstractmethod
|
23
|
+
def toDict(self, instance: Any) -> dict:
|
24
|
+
"""
|
25
|
+
Converts the `config` attribute of the provided instance to a dictionary and returns it.
|
26
|
+
|
27
|
+
Parameters
|
28
|
+
----------
|
29
|
+
instance : Any
|
30
|
+
The instance to parse. It is expected that the instance has a `config` attribute
|
31
|
+
that is a dataclass or any object that supports `asdict()`.
|
32
|
+
|
33
|
+
Returns
|
34
|
+
-------
|
35
|
+
dict
|
36
|
+
The dictionary representation of the `config` attribute.
|
37
|
+
|
38
|
+
Raises
|
39
|
+
------
|
40
|
+
AttributeError
|
41
|
+
If the `instance` does not have a `config` attribute.
|
42
|
+
TypeError
|
43
|
+
If the `instance.config` is not a valid dataclass or object that supports `asdict()`.
|
44
|
+
"""
|
45
|
+
pass
|
46
|
+
|
File without changes
|