-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreport_manager.py
139 lines (99 loc) · 4.25 KB
/
report_manager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import threading
from json import loads
from os import path
from collections import defaultdict
from typing import AnyStr, DefaultDict, Dict, List
from config_manager import ConfigManager, ConfigType
from report import Report
import bonobo
class ReportManager():
"""[The ReportManager singleton class is responsible for holding and driving the main Report pipeline.]
Raises:
Exception: Singleton object already created.
Returns:
None
"""
__instance = None
__singleton_lock = threading.Lock()
_reports: DefaultDict[str, list] = defaultdict(list)
def __init__(self, auto_parse: bool = False):
if ReportManager.__instance != None:
raise Exception(
__name__,
'::__init__ an object of the class already exists.')
else:
ReportManager.__instance = self
# Initialize the config manager
ConfigManager.instance()
# If auto parsing is enabled, parse the reports according to the .JSON source
if auto_parse:
self._parse_reports()
@staticmethod
def instance():
if ReportManager.__instance == None:
with ReportManager.__singleton_lock:
if ReportManager.__instance == None:
ReportManager()
return ReportManager.__instance
def reports(self) -> DefaultDict[str, List]:
return self._reports
def append(self, department_name: str, report_item: Report) -> None:
if department_name is None:
print(__name__,
'::append(...) invalid department_name, ',
department_name)
return
if report_item is None:
print(__name__,
'::append(...) invalid report_item, ',
report_item)
return
self._reports[department_name].append(report_item)
def _valid(self, rep: Report) -> bool:
# ToDo - Validate if the report is on the proper schedule day.
return True
def _parse_reports(self) -> None:
reports_full_path: str = ConfigManager.instance().get_config(ConfigType.Reports, 'location')
if reports_full_path is None:
print(__name__, '::_parse_reports() could not retrieve report JSON definition, ', reports_full_path)
return
if path.exists(reports_full_path):
with open(reports_full_path, 'r') as reports_source:
file: AnyStr = reports_source.read()
if file is not None:
data = loads(file)
if data is not None:
for department in data:
for report_data in data[department]:
report_instance: Report = Report()
report_instance.from_json(report_data)
if report_instance is not None:
self.append(department, report_instance)
else:
print(__name__,
"::parse_reports() invalid reports source.")
return
def run(self) -> bool:
# TODO: Change the continue to a report error insertion on DB
if self._reports is None:
print(__name__,
"::run() no reports available.")
return False
for dep_report in self._reports.values():
if dep_report is not None:
for report in dep_report:
if not report.enabled:
print(__name__, '::run() report is disabled, ',
report.name)
continue
graph: Bonobo.graph = report.graph
if graph is None:
print(__name__,
"::run() DAG could not be constructed, ",
report.name)
continue
if self._valid(report):
print(__name__,
' Running report '
, report.name)
bonobo.run(graph)