Coverage for cfg_checker/helpers/errors.py : 27%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import os
2from configparser import NoSectionError
4from cfg_checker.common import file_utils as fu
5from cfg_checker.common import logger, logger_cli
6from cfg_checker.common.config_file import ConfigFile
7from cfg_checker.common.exception import ErrorMappingException
8from cfg_checker.common.settings import pkg_dir
11class ErrorIndex(object):
12 # logs folder filenames
13 _error_logs_folder_name = ".cfgerrors"
14 _conf_filename = "conf"
15 # config file object
16 conf = None
17 # iteration counter
18 _iteration = 0
19 # local vars for codes
20 _area_code = ""
21 _delimiter = ""
22 _index = 0
23 _errors = {}
24 _types = {
25 0: "Unknown error"
26 }
28 def __init__(self, area_code, delimiter='-'):
29 self._area_code = area_code
30 self._delimiter = delimiter
31 self._index += 1
33 # init the error log storage folder
34 _folder = os.path.join(pkg_dir, self._error_logs_folder_name)
35 self._conf_filename = os.path.join(
36 _folder,
37 self._conf_filename
38 )
40 logger_cli.debug(fu.ensure_folder_exists(_folder))
41 if not os.path.exists(self._conf_filename):
42 # put file with init values
43 self.conf = ConfigFile(self._area_code.lower())
44 self.conf.set_value('iteration', self._iteration)
45 self.conf.save_config(filepath=self._conf_filename)
46 logger_cli.debug(
47 "... create new config file '{}'".format(
48 self._conf_filename
49 )
50 )
51 else:
52 # it exists, try to load latest run
53 self.conf = ConfigFile(
54 self._area_code.lower(),
55 filepath=self._conf_filename
56 )
57 # check if there is any values there
58 try:
59 self._iteration = self.conf.get_value(
60 'iteration',
61 value_type=int
62 )
63 self._iteration += 1
64 except NoSectionError:
65 self._iteration += 1
66 self.conf.set_value('iteration', self._iteration)
67 self.conf.save_config(filepath=self._conf_filename)
68 logger_cli.debug("... updated config file")
70 logger_cli.debug(" ... starting iteration {}".format(self._iteration))
72 def save_iteration_data(self):
73 # save error log
74 _filename = "-".join([self._area_code.lower(), "errors"])
75 _filename += "." + str(self._iteration)
76 _log_filename = os.path.join(
77 pkg_dir,
78 self._error_logs_folder_name,
79 _filename
80 )
81 fu.write_lines_to_file(_log_filename, self.get_errors(as_list=True))
82 fu.append_line_to_file(_log_filename, "")
83 fu.append_lines_to_file(_log_filename, self.get_summary(as_list=True))
84 logger_cli.debug("... saved errors to '{}'".format(_log_filename))
86 # save last iteration number
87 self.conf.set_value('iteration', self._iteration)
88 self.conf.save_config()
90 def _format_error_code(self, index):
91 _t = "{:02d}".format(self._errors[index]['type'])
92 _i = "{:04d}".format(index)
93 _fmt = self._delimiter.join([self._area_code, _t, _i])
94 return _fmt
96 def _format_error(self, index):
97 # error code
98 _code = self._format_error_code(index)
99 # prepare data as string list
100 _d = self._errors[index]['data']
101 _data = [" {}: {}".format(_k, _v) for _k, _v in _d.items()]
102 # format message
103 _msg = "### {}:\n Description: {}\n{}".format(
104 _code,
105 self.get_error_type_text(self._errors[index]['type']),
106 "\n".join(_data)
107 )
108 return _msg
110 def get_error_type_text(self, err_type):
111 if err_type not in self._types:
112 raise ErrorMappingException(
113 "type code {} not found".format(err_type)
114 )
115 else:
116 return self._types[err_type]
118 def get_error_code(self, index):
119 if index in self._errors.keys():
120 return self._format_error(index)
121 else:
122 raise ErrorMappingException(
123 "no error found for index {}".format(index)
124 )
126 def add_error_type(self, err_type, message):
127 if err_type in self._types:
128 raise ErrorMappingException(
129 "type code {} reserved for {}".format(
130 err_type,
131 self._types[err_type]
132 )
133 )
134 else:
135 self._types[err_type] = message
137 def add_error(self, err_type, **kwargs):
138 # check error type
139 if err_type not in self._types.keys():
140 logger.error(
141 "Error type not listed: '{}'; unknown used".format(err_type)
142 )
143 err_type = 0
144 _err = {
145 "type": err_type,
146 "data": kwargs
147 }
148 self._errors[self._index] = _err
149 self._index += 1
151 def get_errors_total(self):
152 return self._index-1
154 def get_indices(self):
155 return self._errors.keys()
157 def get_error(self, index):
158 if index in self._errors.keys():
159 return self._format_error(index)
160 else:
161 return "Unknown error index of {}".format(index)
163 def get_summary(self, print_zeros=True, as_list=False):
164 # create summary with counts per error type
165 _list = "\n{:=^8s}\n{:^8s}\n{:=^8s}".format(
166 "=",
167 "Totals",
168 "="
169 ).splitlines()
171 for _type in self._types.keys():
172 _len = len(
173 filter(
174 lambda i: self._errors[i]['type'] == _type,
175 self._errors
176 )
177 )
178 if _len:
179 _num_str = "{:5d}".format(_len)
180 elif print_zeros:
181 _num_str = "{:>5s}".format("-")
182 else:
183 continue
184 _list.append(
185 "{}: {}".format(
186 _num_str,
187 self._types[_type]
188 )
189 )
191 _total_errors = self.get_errors_total()
193 _list.append('-'*20)
194 _list.append("{:5d} total events found\n".format(_total_errors))
195 if as_list:
196 return _list
197 else:
198 return "\n".join(_list)
200 def get_errors(self, as_list=False):
201 _list = ["# Events"]
202 # Detailed errors
203 if self.get_errors_total() > 0:
204 # create list of strings with error messages
205 for _idx in range(1, self._index):
206 _list.append(self._format_error(_idx))
207 _list.append("\n")
208 else:
209 _list.append("-> No events saved")
211 if as_list:
212 return _list
213 else:
214 return "\n".join(_list)