lukhed-basic-utils 0.2.0__tar.gz
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.
- lukhed_basic_utils-0.2.0/LICENSE +21 -0
- lukhed_basic_utils-0.2.0/PKG-INFO +28 -0
- lukhed_basic_utils-0.2.0/README.md +14 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/__init__.py +1 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/classCommon.py +402 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/fileCommon.py +416 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/listWorkCommon.py +337 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/mathCommon.py +237 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/osCommon.py +444 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/stringCommon.py +184 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils/timeCommon.py +1098 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils.egg-info/PKG-INFO +28 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils.egg-info/SOURCES.txt +16 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils.egg-info/dependency_links.txt +1 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils.egg-info/requires.txt +2 -0
- lukhed_basic_utils-0.2.0/lukhed_basic_utils.egg-info/top_level.txt +1 -0
- lukhed_basic_utils-0.2.0/setup.cfg +4 -0
- lukhed_basic_utils-0.2.0/setup.py +23 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 lukhed
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: lukhed_basic_utils
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A collection of basic utility functions
|
|
5
|
+
Home-page: https://github.com/lukhed/lukhed_basic_utils
|
|
6
|
+
Author: lukhed
|
|
7
|
+
Author-email: lukhed.mail@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
|
|
15
|
+
# aceCommon
|
|
16
|
+
|
|
17
|
+
A collection of basic utility functions for Python projects.
|
|
18
|
+
|
|
19
|
+
## Installation and Usage
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install lukhed_basic_utils
|
|
23
|
+
from lukhed_basic_utils import create_file_path_string
|
|
24
|
+
|
|
25
|
+
example_path = create_file_path_string(list_of_dir=['subdir', 'file.txt'])
|
|
26
|
+
|
|
27
|
+
print(path)
|
|
28
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# aceCommon
|
|
2
|
+
|
|
3
|
+
A collection of basic utility functions for Python projects.
|
|
4
|
+
|
|
5
|
+
## Installation and Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install lukhed_basic_utils
|
|
9
|
+
from lukhed_basic_utils import create_file_path_string
|
|
10
|
+
|
|
11
|
+
example_path = create_file_path_string(list_of_dir=['subdir', 'file.txt'])
|
|
12
|
+
|
|
13
|
+
print(path)
|
|
14
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .osCommon import create_file_path_string, append_to_dir
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
from lukhed_basic_utils import osCommon as osC
|
|
2
|
+
from lukhed_basic_utils import fileCommon as fC
|
|
3
|
+
from lukhed_basic_utils import timeCommon as tC
|
|
4
|
+
|
|
5
|
+
class AceLogging:
|
|
6
|
+
"""
|
|
7
|
+
Provides basic logging functionality for classes, writing logs to a JSON file.
|
|
8
|
+
|
|
9
|
+
Logs are structured hierarchically by date, with each run assigned a unique ID.
|
|
10
|
+
By default, logs are stored in the directory `logs/projectLogs.json`.
|
|
11
|
+
|
|
12
|
+
Attributes:
|
|
13
|
+
ace_logging (bool): Whether logging is enabled.
|
|
14
|
+
ace_log_directory (str): The directory where the log file will be stored.
|
|
15
|
+
ace_log_file_path (str): Full path to the log file.
|
|
16
|
+
ace_log_time_stamp (str): Timestamp for the current date in "%Y%m%d" format.
|
|
17
|
+
log_run_id (int): ID for the current run.
|
|
18
|
+
|
|
19
|
+
Methods:
|
|
20
|
+
logging_add_event: Adds an event log to the current run.
|
|
21
|
+
logging_print_active_log: Prints all events logged during the current run.
|
|
22
|
+
print_log_items_by_specified_tag: Filters and prints logs by a specified tag (e.g., "ERROR").
|
|
23
|
+
|
|
24
|
+
Example Usage:
|
|
25
|
+
An example of logging in a custom class:
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
class MyCustomClass(AceLogging):
|
|
29
|
+
def __init__(self, logging=True):
|
|
30
|
+
AceLogging.__init__(self, logging=logging)
|
|
31
|
+
|
|
32
|
+
def example_custom_method(self):
|
|
33
|
+
test = "do some stuff"
|
|
34
|
+
# some error occurs you want to log
|
|
35
|
+
self.logging_add_event(log_type_named="error", function_named="example_custom_method",
|
|
36
|
+
short_description="A test to check logging functionality"
|
|
37
|
+
any_content={"someData": "you want to save"})
|
|
38
|
+
```
|
|
39
|
+
"""
|
|
40
|
+
def __init__(self, log_directory=None, logging=False, custom_file_name=None):
|
|
41
|
+
self.ace_logging = logging
|
|
42
|
+
if self.ace_logging:
|
|
43
|
+
if custom_file_name is None:
|
|
44
|
+
self.ace_logging_fn = "projectLogs.json"
|
|
45
|
+
else:
|
|
46
|
+
self.ace_logging_fn = custom_file_name
|
|
47
|
+
|
|
48
|
+
if log_directory is None:
|
|
49
|
+
self.ace_log_directory = osC.create_file_path_string(["logs"])
|
|
50
|
+
else:
|
|
51
|
+
self.ace_log_directory = log_directory
|
|
52
|
+
|
|
53
|
+
self.ace_log_file_path = osC.append_to_dir(self.ace_log_directory, self.ace_logging_fn)
|
|
54
|
+
self.ace_log_time_stamp = tC.get_today_date(convert_to_string_format="%Y%m%d")
|
|
55
|
+
self._check_create_dir_structure()
|
|
56
|
+
|
|
57
|
+
def _check_create_dir_structure(self):
|
|
58
|
+
if not osC.check_if_dir_exists(self.ace_log_directory):
|
|
59
|
+
osC.create_dir(self.ace_log_directory)
|
|
60
|
+
if not osC.check_if_file_exists(self.ace_log_file_path):
|
|
61
|
+
self.ace_active_log = {self.ace_log_time_stamp: {"totalRuns": 1, "eventsLogged": []}}
|
|
62
|
+
fC.dump_json_to_file(self.ace_log_file_path, self.ace_active_log)
|
|
63
|
+
self.log_run_id = 1
|
|
64
|
+
else:
|
|
65
|
+
self.ace_active_log = fC.load_json_from_file(self.ace_log_file_path)
|
|
66
|
+
try:
|
|
67
|
+
tr = self.ace_active_log[self.ace_log_time_stamp]["totalRuns"]
|
|
68
|
+
tr = tr + 1
|
|
69
|
+
self.log_run_id = tr
|
|
70
|
+
self.ace_active_log[self.ace_log_time_stamp]["totalRuns"] = tr
|
|
71
|
+
self._write_to_log()
|
|
72
|
+
except KeyError:
|
|
73
|
+
self.ace_active_log.update({self.ace_log_time_stamp: {}})
|
|
74
|
+
self.ace_active_log[self.ace_log_time_stamp] = {"totalRuns": 1, "eventsLogged": []}
|
|
75
|
+
self.log_run_id = 1
|
|
76
|
+
self._write_to_log()
|
|
77
|
+
|
|
78
|
+
def _write_to_log(self):
|
|
79
|
+
fC.dump_json_to_file(self.ace_log_file_path, self.ace_active_log)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def logging_add_event(self, log_type_named=None, function_named=None, short_description=None,
|
|
83
|
+
any_content=None):
|
|
84
|
+
"""
|
|
85
|
+
Adds an event to the log file for the current run.
|
|
86
|
+
|
|
87
|
+
Parameters:
|
|
88
|
+
log_type_named (str, optional): The type of log (e.g., "ERROR", "INFO").
|
|
89
|
+
function_named (str, optional): The name of the function generating the log.
|
|
90
|
+
short_description (str, optional): A brief description of the event.
|
|
91
|
+
any_content (dict, optional): Additional details related to the event.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
None
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
if self.ace_logging:
|
|
98
|
+
if log_type_named is None:
|
|
99
|
+
pass
|
|
100
|
+
else:
|
|
101
|
+
log_type_named = log_type_named.upper()
|
|
102
|
+
|
|
103
|
+
log_event = {
|
|
104
|
+
"runNumber": self.log_run_id,
|
|
105
|
+
"timeLogged": tC.create_timestamp(output_format="%Y%m%d%H%M%S"),
|
|
106
|
+
"logType": log_type_named,
|
|
107
|
+
"functionName": function_named,
|
|
108
|
+
"description": short_description,
|
|
109
|
+
"details": any_content
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
self.ace_active_log[self.ace_log_time_stamp]["eventsLogged"].append(log_event)
|
|
113
|
+
self._write_to_log()
|
|
114
|
+
|
|
115
|
+
def logging_print_active_log(self):
|
|
116
|
+
print("\n****** All Log Events for Current Run ******")
|
|
117
|
+
current_log = [x for x in self.ace_active_log[self.ace_log_time_stamp]["eventsLogged"]
|
|
118
|
+
if x["runNumber"] == self.log_run_id]
|
|
119
|
+
count = 1
|
|
120
|
+
for log in current_log:
|
|
121
|
+
print("\nEvent = " + str(count))
|
|
122
|
+
print(log['logType'] + "," + log['timeLogged'] + "," + log["functionName"])
|
|
123
|
+
print(log["description"])
|
|
124
|
+
print(log["details"])
|
|
125
|
+
count = count + 1
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def print_log_items_by_specified_tag(self, tag="ERROR", printing=True, last_run_only=True, spec_date=None,
|
|
129
|
+
date_format="%Y%m%d", headless_mode=False):
|
|
130
|
+
"""
|
|
131
|
+
Prints or retrieves logs filtered by a specific tag (e.g., "ERROR").
|
|
132
|
+
|
|
133
|
+
Parameters:
|
|
134
|
+
tag (str): The tag to filter logs (default is "ERROR").
|
|
135
|
+
printing (bool): If True, logs will be printed; otherwise, results are returned.
|
|
136
|
+
last_run_only (bool): If True, filters logs from the most recent run only.
|
|
137
|
+
spec_date (str, optional): Specific date to filter logs (format specified by `date_format`).
|
|
138
|
+
date_format (str): Format of the provided date (default is "%Y%m%d").
|
|
139
|
+
headless_mode (bool): If True, disables interactive prompts and returns results as a list.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
list: Filtered logs matching the specified criteria.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
log = fC.load_json_from_file(self.ace_log_file_path)
|
|
146
|
+
|
|
147
|
+
if last_run_only:
|
|
148
|
+
last_date = {}
|
|
149
|
+
for key in log:
|
|
150
|
+
last_date = log[key]
|
|
151
|
+
|
|
152
|
+
total_runs = last_date["totalRuns"]
|
|
153
|
+
specified_logs = [x for x in last_date["eventsLogged"] if x["runNumber"] == total_runs]
|
|
154
|
+
elif spec_date is not None:
|
|
155
|
+
date_key = tC.convert_date_format(spec_date, from_format=date_format, to_format="%Y%m%d")
|
|
156
|
+
specified_logs = log[date_key]["eventsLogged"]
|
|
157
|
+
else:
|
|
158
|
+
specified_logs = []
|
|
159
|
+
for key in log:
|
|
160
|
+
specified_logs.extend(log[key]["eventsLogged"])
|
|
161
|
+
|
|
162
|
+
found_logs = [x for x in specified_logs if x["logType"].lower() == tag.lower()]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
if printing:
|
|
166
|
+
for temp_log in found_logs:
|
|
167
|
+
print("Time= " + temp_log["timeLogged"])
|
|
168
|
+
print("Function Name= " + temp_log["functionName"])
|
|
169
|
+
print("Description= " + temp_log["description"])
|
|
170
|
+
print("\n")
|
|
171
|
+
|
|
172
|
+
if headless_mode is False:
|
|
173
|
+
input("Press any key to close")
|
|
174
|
+
|
|
175
|
+
return found_logs
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class AceJobScheduler(AceLogging):
|
|
179
|
+
"""
|
|
180
|
+
Extends `AceLogging` to include job scheduling functionality.
|
|
181
|
+
|
|
182
|
+
This class tracks and manages job execution based on various scheduling requirements
|
|
183
|
+
(e.g., daily, weekly, after a certain time).
|
|
184
|
+
|
|
185
|
+
Attributes:
|
|
186
|
+
ace_job_scheduler_date (str): Current date in "%Y%m%d" format.
|
|
187
|
+
ace_job_scheduler_fn (str): Name of the job status file.
|
|
188
|
+
|
|
189
|
+
Methods:
|
|
190
|
+
_check_if_job_needs_running: Determines whether a job should run based on the provided schedule.
|
|
191
|
+
_write_job_status: Updates the job status file after execution.
|
|
192
|
+
"""
|
|
193
|
+
def __init__(self, log_setting=True, job_status_file_name="jobStatus.json"):
|
|
194
|
+
AceLogging.__init__(self, logging=log_setting)
|
|
195
|
+
self.ace_job_scheduler_date = tC.get_today_date(convert_to_string_format="%Y%m%d")
|
|
196
|
+
self.ace_job_scheduler_fn = job_status_file_name
|
|
197
|
+
|
|
198
|
+
def _create_new_job_status_file_for_job(self, job_dir):
|
|
199
|
+
job_status = {
|
|
200
|
+
"lastRunDate": None,
|
|
201
|
+
"lastRunDay": None,
|
|
202
|
+
"lastRunHour": None,
|
|
203
|
+
"lastRunMinute": None,
|
|
204
|
+
"lastRunSecond": None,
|
|
205
|
+
"lastRunSuccess": None,
|
|
206
|
+
"lastRunMonth": None,
|
|
207
|
+
"lastRunDayName": None,
|
|
208
|
+
"lastRunTimeStamp": None
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
new_file = osC.append_to_dir(job_dir, self.ace_job_scheduler_fn)
|
|
212
|
+
fC.dump_json_to_file(new_file, job_status)
|
|
213
|
+
self.logging_add_event("info", "_create_job_status_file_for_job", "created new job status file",
|
|
214
|
+
{"file": new_file})
|
|
215
|
+
|
|
216
|
+
def _get_job_status_json(self, job_dir):
|
|
217
|
+
osC.check_create_dir_structure(job_dir, full_path=True)
|
|
218
|
+
job_status_file = osC.append_to_dir(job_dir, self.ace_job_scheduler_fn)
|
|
219
|
+
if not osC.check_if_file_exists(job_status_file):
|
|
220
|
+
self._create_new_job_status_file_for_job(job_dir)
|
|
221
|
+
return fC.load_json_from_file(job_status_file)
|
|
222
|
+
|
|
223
|
+
def _check_if_job_needs_running(self, job_dir, requirement="daily", after_hour=0):
|
|
224
|
+
"""
|
|
225
|
+
Determines whether a job should run based on the given requirement.
|
|
226
|
+
|
|
227
|
+
Parameters:
|
|
228
|
+
job_dir (str): Directory for the job status file.
|
|
229
|
+
requirement (str): Scheduling requirement, options include:
|
|
230
|
+
- "daily": Runs once per day.
|
|
231
|
+
- "hourly": Runs once per hour.
|
|
232
|
+
- "weekly": Runs once per week.
|
|
233
|
+
- A specific day (e.g., "monday").
|
|
234
|
+
- A list of days (e.g., ["monday", "wednesday"]).
|
|
235
|
+
- "X min": Runs if more than X minutes have passed since the last run.
|
|
236
|
+
after_hour (int): The earliest hour (in 24-hour format) at which the job can run.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
bool: True if the job should run, False otherwise.
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
|
+
requirement = requirement.lower()
|
|
243
|
+
job_status = self._get_job_status_json(job_dir)
|
|
244
|
+
cur_ts = tC.create_timestamp(output_format="%Y%m%d%H%M%S")
|
|
245
|
+
time_components = tC.extract_date_time_components(cur_ts, input_format="%Y%m%d%H%M%S")
|
|
246
|
+
{'year': 2024, 'month': 12, 'day': 22, 'hour': 15, 'minute': 30, 'second': 45}
|
|
247
|
+
month = time_components['month']
|
|
248
|
+
day = time_components['day']
|
|
249
|
+
hour = time_components['hour']
|
|
250
|
+
minute = time_components['minute']
|
|
251
|
+
second = time_components['second']
|
|
252
|
+
|
|
253
|
+
# Must be greater than or equal to after hour to need a run. Need to check this first.
|
|
254
|
+
if hour < after_hour:
|
|
255
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
256
|
+
"determined job does not need to run: after hour requirement", {"job": job_dir})
|
|
257
|
+
return False
|
|
258
|
+
|
|
259
|
+
# check daily related requirements
|
|
260
|
+
days_of_week = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
|
|
261
|
+
if type(requirement) is list:
|
|
262
|
+
temp_flag = False
|
|
263
|
+
today = tC.get_current_day().lower()
|
|
264
|
+
for req in requirement:
|
|
265
|
+
if req in days_of_week:
|
|
266
|
+
if today != requirement:
|
|
267
|
+
pass
|
|
268
|
+
else:
|
|
269
|
+
temp_flag = True
|
|
270
|
+
|
|
271
|
+
if temp_flag:
|
|
272
|
+
pass
|
|
273
|
+
else:
|
|
274
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
275
|
+
"determined job does not need to run: daily requirement",
|
|
276
|
+
{"job": job_dir})
|
|
277
|
+
return False
|
|
278
|
+
else:
|
|
279
|
+
if requirement in days_of_week:
|
|
280
|
+
today = tC.get_current_day().lower()
|
|
281
|
+
if today != requirement:
|
|
282
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
283
|
+
"determined job does not need to run: daily requirement",
|
|
284
|
+
{"job": job_dir})
|
|
285
|
+
return False
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
# If got here, then day and hour is satisfied. So if last run is None, need to run.
|
|
289
|
+
success = job_status["lastRunSuccess"]
|
|
290
|
+
if job_status["lastRunDate"] is None:
|
|
291
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
292
|
+
"determined job needs to run: no job status data", {"job": job_dir})
|
|
293
|
+
return True
|
|
294
|
+
else:
|
|
295
|
+
if success is False or success is None:
|
|
296
|
+
return True
|
|
297
|
+
else:
|
|
298
|
+
pass
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
"""
|
|
302
|
+
If reached to this point, the job is not disqualified yet based on requirements.
|
|
303
|
+
All code above looked for disqualifying items based on day or week and after hour.
|
|
304
|
+
Now check if the code should run given the requirement.
|
|
305
|
+
|
|
306
|
+
For example: it may be the correct day to run the code per the requirement, but it may have already
|
|
307
|
+
been run on the day.
|
|
308
|
+
"""
|
|
309
|
+
if requirement == "daily" or requirement in days_of_week:
|
|
310
|
+
if tC.get_today_date(convert_to_string_format="%Y%m%d") == job_status["lastRunDate"]:
|
|
311
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
312
|
+
"determined job does not need to run: daily requirement", {"job": job_dir})
|
|
313
|
+
return False
|
|
314
|
+
else:
|
|
315
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
316
|
+
"determined job needs to run: daily requirement", {"job": job_dir})
|
|
317
|
+
return True
|
|
318
|
+
elif requirement == "hourly":
|
|
319
|
+
if tC.get_today_date(convert_to_string_format="%Y%m%d") == job_status["lastRunDate"]:
|
|
320
|
+
# Day is today, so check hourly
|
|
321
|
+
last_hour_ran = int(job_status["lastRunHour"])
|
|
322
|
+
if hour == last_hour_ran:
|
|
323
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
324
|
+
"determined job does not need to run: daily requirement", {"job": job_dir})
|
|
325
|
+
return False
|
|
326
|
+
else:
|
|
327
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
328
|
+
"determined job needs to run: daily requirement", {"job": job_dir})
|
|
329
|
+
return True
|
|
330
|
+
else:
|
|
331
|
+
# If job has not run in the new day yet, by definition, job needs to run.
|
|
332
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
333
|
+
"determined job needs to run: daily requirement", {"job": job_dir})
|
|
334
|
+
return True
|
|
335
|
+
elif requirement == "weekly":
|
|
336
|
+
weekly = job_status["lastRunDate"]
|
|
337
|
+
if weekly is None:
|
|
338
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
339
|
+
"determined job needs to run: weekly requirement", {"job": job_dir})
|
|
340
|
+
return True
|
|
341
|
+
|
|
342
|
+
temp_year = weekly[:4]
|
|
343
|
+
cur_year = tC.get_current_year()
|
|
344
|
+
|
|
345
|
+
if temp_year != cur_year:
|
|
346
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
347
|
+
"determined job needs to run: weekly requirement", {"job": job_dir})
|
|
348
|
+
return True
|
|
349
|
+
|
|
350
|
+
wk_int_last_ran = tC.get_week_number_for_date(provided_date=weekly, provided_date_format="%Y%m%d")
|
|
351
|
+
wk_int_today = tC.get_week_number_for_date()
|
|
352
|
+
|
|
353
|
+
if wk_int_today == wk_int_last_ran:
|
|
354
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
355
|
+
"determined job does not need to run: weekly requirement", {"job": job_dir})
|
|
356
|
+
return False
|
|
357
|
+
else:
|
|
358
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
359
|
+
"determined job needs to run: weekly requirement", {"job": job_dir})
|
|
360
|
+
return True
|
|
361
|
+
elif "min" in requirement:
|
|
362
|
+
diff_req = int(requirement.split(" ")[0])
|
|
363
|
+
diff_act = tC.subtract_time_stamps(job_status["lastRunTimeStamp"], cur_ts)["minutes"]
|
|
364
|
+
if diff_act >= diff_req:
|
|
365
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
366
|
+
"determined job needs to run: minutes requirement", {"job": job_dir})
|
|
367
|
+
return True
|
|
368
|
+
else:
|
|
369
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
370
|
+
"determined job does not need to run: minutes requirement", {"job": job_dir})
|
|
371
|
+
return False
|
|
372
|
+
|
|
373
|
+
else:
|
|
374
|
+
self.logging_add_event("info", "_check_if_job_needs_running",
|
|
375
|
+
"determined job does not need to run: no valid requirement", {"job": job_dir})
|
|
376
|
+
return False
|
|
377
|
+
|
|
378
|
+
def _write_job_status(self, job_dir, success_bool):
|
|
379
|
+
job_status_file_path = osC.append_to_dir(job_dir, "jobStatus.json")
|
|
380
|
+
cur_ts = tC.create_timestamp(output_format="%Y%m%d%H%M%S")
|
|
381
|
+
time_components = tC.extract_date_time_components(cur_ts, input_format="%Y%m%d%H%M%S")
|
|
382
|
+
month = time_components['month']
|
|
383
|
+
day = time_components['day']
|
|
384
|
+
hour = time_components['hour']
|
|
385
|
+
minute = time_components['minute']
|
|
386
|
+
second = time_components['second']
|
|
387
|
+
|
|
388
|
+
job_status = {
|
|
389
|
+
"lastRunDate": tC.get_today_date(convert_to_string_format="%Y%m%d"),
|
|
390
|
+
"lastRunHour": hour,
|
|
391
|
+
"lastRunMinute": minute,
|
|
392
|
+
"lastRunSecond": second,
|
|
393
|
+
"lastRunSuccess": success_bool,
|
|
394
|
+
"lastRunMonth": month,
|
|
395
|
+
"lastRunDay": day,
|
|
396
|
+
"lastRunDayName": tC.get_current_day(),
|
|
397
|
+
"lastRunTimeStamp": tC.create_timestamp(output_format="%Y%m%d%H%M%S")
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
fC.dump_json_to_file(job_status_file_path, job_status)
|
|
401
|
+
self.logging_add_event("info", "_write_job_status", "updated job status",
|
|
402
|
+
{"job": job_dir, "success": success_bool})
|