Terarea  2
The automation project
Loading...
Searching...
No Matches
crons.py
Go to the documentation of this file.
1"""_summary_
2 File in charge of containing the functions that will be run in the background.
3"""
4from typing import Any, List, Dict, Union
5from datetime import datetime
6from display_tty import Disp, TOML_CONF, FILE_DESCRIPTOR, SAVE_TO_FILE, FILE_NAME
7from .runtime_data import RuntimeData
8from . import constants as CONST
9
10
11class Crons:
12 """_summary_
13 """
14
15 def __init__(self, runtime_data: RuntimeData, error: int = 84, success: int = 0, debug: bool = False) -> None:
16
17 # -------------------------- Inherited values --------------------------
18 self.error: int = error
19 self.success: int = success
20 self.debug: bool = debug
21 self.runtime_data: RuntimeData = runtime_data
22 # ---------------------- The visual logger class ----------------------
23 self.disp: Disp = Disp(
24 TOML_CONF,
25 SAVE_TO_FILE,
26 FILE_NAME,
27 FILE_DESCRIPTOR,
28 debug=self.debug,
29 logger=self.__class__.__name__
30 )
31
32 def __del__(self) -> None:
33 """_summary_
34 The destructor of the class
35 """
36 self.disp.log_info("Cron sub processes are shutting down.", "__del__")
37 if self.runtime_data.background_tasks_initialised is not None:
38 del self.runtime_data.background_tasks_initialised
39 self.runtime_data.background_tasks_initialised = None
40
41 def inject_crons(self) -> int:
42 """_summary_
43 Add the cron functions to the cron loop.
44
45 Returns:
46 int: _description_: The overall status of the injection.
47 """
48 self.runtime_data.background_tasks_initialised.safe_add_task(
49 func=self.check_actions,
50 args=None,
51 trigger='interval',
52 seconds=CONST.CHECK_ACTIONS_INTERVAL
53 )
54 if CONST.ENABLE_TEST_CRONS is True:
55 self.runtime_data.background_tasks_initialised.safe_add_task(
56 func=self._harass_database,
57 args=None,
58 trigger='interval',
59 seconds=CONST.TEST_CRONS_INTERVAL
60 )
61 self.runtime_data.background_tasks_initialised.safe_add_task(
62 func=self._test_current_date,
63 args=datetime.now,
64 trigger='interval',
65 seconds=CONST.TEST_CRONS_INTERVAL
66 )
67 self.runtime_data.background_tasks_initialised.safe_add_task(
68 func=self._test_hello_world,
69 args=None,
70 trigger='interval',
71 seconds=CONST.TEST_CRONS_INTERVAL
72 )
73 if CONST.CLEAN_TOKENS is True:
74 self.runtime_data.background_tasks_initialised.safe_add_task(
75 func=self.clean_expired_tokens,
76 args=None,
77 trigger='interval',
78 seconds=CONST.CLEAN_TOKENS_INTERVAL
79 )
80 if CONST.CLEAN_VERIFICATION is True:
81 self.runtime_data.background_tasks_initialised.safe_add_task(
83 args=None,
84 trigger='interval',
85 seconds=CONST.CLEAN_VERIFICATION_INTERVAL
86 )
87 if CONST.RENEW_OATH_TOKENS is True:
88 self.runtime_data.background_tasks_initialised.safe_add_task(
89 func=self.renew_oaths,
90 args=None,
91 trigger='interval',
92 seconds=CONST.RENEW_OATH_TOKENS_INTERVAL
93 )
94
95 def _test_hello_world(self) -> None:
96 """_summary_
97 This is a test function that will print "Hello World".
98 """
99 self.disp.log_info("Hello World", "_test_hello_world")
100
101 def _test_current_date(self, *args: Any) -> None:
102 """_summary_
103 This is a test function that will print the current date.
104 Args:
105 date (datetime): _description_
106 """
107 if len(args) >= 1:
108 date = args[0]
109 else:
110 date = datetime.now()
111 if callable(date) is True:
112 self.disp.log_info(
113 f"(Called) Current date: {date()}",
114 "_test_current_date"
115 )
116 else:
117 self.disp.log_info(
118 f"(Not called) Current date: {date}",
119 "_test_current_date"
120 )
121
122 def _harass_database(self, *args: Any) -> None:
123 """_summary_
124 This is a test function that will print the current date.
125 Args:
126 date (datetime): _description_
127 """
128 title = "_harass_database"
129 self.disp.log_info(f"In {title}", title)
130 self.runtime_data.database_link.show_connection_info()
131 connection = self.runtime_data.database_link.is_connected()
132 self.disp.log_info(
133 f"Connection status: {connection}",
134 title
135 )
136 if connection is False:
137 self.runtime_data.database_link.connect_to_db()
138 connection = self.runtime_data.database_link.is_connected()
139 self.disp.log_info(
140 f"Connection status: {connection}",
141 title
142 )
143 connection = self.runtime_data.database_link.is_connected()
144 self.disp.log_info(
145 f"Connection status: {connection}",
146 title
147 )
148 if connection is True:
149 data = self.runtime_data.database_link.get_table_names()
150 self.disp.log_info(
151 f"Data from {CONST.TAB_CONNECTIONS}: {data}",
152 title
153 )
154 data = self.runtime_data.database_link.describe_table(
155 CONST.TAB_CONNECTIONS
156 )
157 self.disp.log_info(
158 f"Data from {CONST.TAB_CONNECTIONS}: {data}",
159 title
160 )
161 data = self.runtime_data.database_link.get_data_from_table(
162 CONST.TAB_CONNECTIONS, "*", "", True
163 )
164 self.disp.log_info(
165 f"Data from {CONST.TAB_CONNECTIONS}: {data}",
166 title
167 )
168 data = self.runtime_data.database_link.get_table_column_names(
169 CONST.TAB_CONNECTIONS
170 )
171 self.disp.log_info(
172 f"Data from {CONST.TAB_CONNECTIONS}: {data}",
173 title
174 )
175 data = self.runtime_data.database_link.get_table_size(
176 CONST.TAB_CONNECTIONS, "*", ""
177 )
178 self.disp.log_info(
179 f"Data from {CONST.TAB_CONNECTIONS}: {data}",
180 title
181 )
182 self.disp.log_info(f"Out of {title}.", title)
183
184 def clean_expired_tokens(self) -> None:
185 """_summary_
186 Remove the tokens that have passed their lifespan.
187 """
188 title = "clean_expired_tokens"
189 date_node = "expiration_date"
190 current_time = datetime.now()
191 self.disp.log_info("Cleaning expired tokens", title)
192 current_tokens = self.runtime_data.database_link.get_data_from_table(
193 table=CONST.TAB_CONNECTIONS,
194 column="*",
195 where="",
196 beautify=True
197 )
198 if isinstance(current_tokens, int) is True:
199 msg = "There is no data to be cleared in "
200 msg += f"{CONST.TAB_CONNECTIONS} table."
201 self.disp.log_warning(msg, title)
202 return
203 self.disp.log_debug(f"current tokens = {current_tokens}", title)
204 for i in current_tokens:
205 if i[date_node] is not None and i[date_node] != "" and isinstance(i[date_node], str) is True:
206 datetime_node = self.runtime_data.database_link.string_to_datetime(
207 i[date_node]
208 )
209 msg = f"Converted {i[date_node]} to a datetime instance"
210 msg += f" ({datetime_node})."
211 self.disp.log_debug(msg, title)
212 else:
213 datetime_node = i[date_node]
214 self.disp.log_debug(f"Did not convert {i[date_node]}.", title)
215 if datetime_node < current_time:
216 self.runtime_data.database_link.remove_data_from_table(
217 table=CONST.TAB_CONNECTIONS,
218 where=f"id='{i['id']}'"
219 )
220 self.disp.log_debug(f"Removed {i}.", title)
221 else:
222 self.disp.log_debug(
223 f"Did not remove {i} because it is not yet time.", title
224 )
225 self.disp.log_debug("Cleaned expired tokens", title)
226
228 """_summary_
229 Remove the nodes in the verification table that have passed their lifespan.
230 """
231 title = "clean_expired_verification_nodes"
232 date_node = "expiration"
233 current_time = datetime.now()
234 self.disp.log_info(
235 f"Cleaning expired lines in the {CONST.TAB_VERIFICATION} table.",
236 title
237 )
238 current_lines = self.runtime_data.database_link.get_data_from_table(
239 table=CONST.TAB_VERIFICATION,
240 column="*",
241 where="",
242 beautify=True
243 )
244 if isinstance(current_lines, int) is True:
245 msg = "There is no data to be cleared in "
246 msg += f"{CONST.TAB_VERIFICATION} table."
247 self.disp.log_warning(
248 msg,
249 title
250 )
251 return
252 self.disp.log_debug(f"current lines = {current_lines}", title)
253 for i in current_lines:
254 if i[date_node] is not None and i[date_node] != "" and isinstance(i[date_node], str) is True:
255 datetime_node = self.runtime_data.database_link.string_to_datetime(
256 i[date_node]
257 )
258 msg = f"Converted {i[date_node]} to a datetime instance"
259 msg += f" ({datetime_node})."
260 self.disp.log_debug(msg, title)
261 else:
262 datetime_node = i[date_node]
263 self.disp.log_debug(f"Did not convert {i[date_node]}.", title)
264 if datetime_node < current_time:
265 self.runtime_data.database_link.remove_data_from_table(
266 table=CONST.TAB_VERIFICATION,
267 where=f"id='{i['id']}'"
268 )
269 self.disp.log_debug(f"Removed {i}.", title)
270 self.disp.log_debug("Cleaned expired lines", title)
271
272 def renew_oaths(self) -> None:
273 """_summary_
274 Function in charge of renewing the oath tokens that are about to expire.
275 """
276 title = "renew_oaths"
277 self.disp.log_debug(
278 "Checking for oaths that need to be renewed", title
279 )
280 oath_connections: Union[List[Dict[str]], int] = self.runtime_data.database_link.get_data_from_table(
281 table=CONST.TAB_ACTIVE_OAUTHS,
282 column="*",
283 where="",
284 beautify=True
285 )
286 if isinstance(oath_connections, int) or len(oath_connections) == 0:
287 return
288 current_time: datetime = datetime.now()
289 for oath in oath_connections:
290 if oath["token_lifespan"] == 0:
291 self.disp.log_debug(f"Token for {oath['id']} does not need to be renewed.", title)
292 continue
293 node_id: str = oath['id']
294 token_expiration: datetime = oath["token_expiration"]
295 if current_time > token_expiration:
296 renew_link: str = oath["refresh_link"]
297 lifespan: int = int(oath["token_lifespan"])
298 provider_name: List[
299 Dict[str, Any]
300 ] = self.runtime_data.database_link.get_data_from_table(
301 table=CONST.TAB_SERVICES,
302 column="*",
303 where=f"id='{oath['service_id']}'",
304 beautify=True
305 )
306 if isinstance(provider_name, int) is True:
307 self.disp.log_error(
308 f"Could not find provider name for {node_id}", title
309 )
310 continue
311 new_token: Union[str, None] = self.runtime_data.oauth_authentication_initialised.refresh_token(
312 provider_name[0]['name'],
313 renew_link
314 )
315 if new_token is None:
316 self.disp.log_debug("Refresh token failed to generate a new token.", title)
317 continue
318 token_expiration: str = self.runtime_data.database_link.datetime_to_string(
319 datetime_instance=self.runtime_data.boilerplate_non_http_initialised.set_lifespan(
320 seconds=lifespan
321 ),
322 date_only=False,
323 sql_mode=True
324 )
325 self.disp.log_debug(
326 f"token expiration = {token_expiration}", title
327 )
328 if new_token != "":
329 self.runtime_data.database_link.update_data_in_table(
330 table=CONST.TAB_ACTIVE_OAUTHS,
331 data=[
332 new_token,
333 token_expiration
334 ],
335 column=[
336 "token",
337 "token_expiration"
338 ],
339 where=f"id='{node_id}'"
340 )
341 self.disp.log_debug(
342 f"token {new_token} updated for {node_id}"
343 )
344 else:
345 self.disp.log_error(f"Could not renew token for {node_id}")
346 else:
347 self.disp.log_debug(
348 f"Token for {node_id} does not need to be renewed.", title
349 )
350 self.disp.log_debug("Checked for oath that need to be renewed", title)
351
352 def check_actions(self) -> None:
353 """_summary_
354 Function in charge of checking if any actions need to be run.
355 """
356 title = "check_actions"
357 self.disp.log_debug("Checking for actions that need to be run.", title)
358 self.runtime_data.actions_main_initialised.execute_actions()
359 self.disp.log_debug("Checked for actions that needed to be run", title)
None __init__(self, RuntimeData runtime_data, int error=84, int success=0, bool debug=False)
Definition crons.py:15
None _test_current_date(self, *Any args)
Definition crons.py:101
None clean_expired_verification_nodes(self)
Definition crons.py:227
None clean_expired_tokens(self)
Definition crons.py:184
None _harass_database(self, *Any args)
Definition crons.py:122