Hide keyboard shortcuts

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 

3 

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 

9 

10 

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 } 

27 

28 def __init__(self, area_code, delimiter='-'): 

29 self._area_code = area_code 

30 self._delimiter = delimiter 

31 self._index += 1 

32 

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 ) 

39 

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") 

69 

70 logger_cli.debug(" ... starting iteration {}".format(self._iteration)) 

71 

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)) 

85 

86 # save last iteration number 

87 self.conf.set_value('iteration', self._iteration) 

88 self.conf.save_config() 

89 

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 

95 

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 

109 

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] 

117 

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 ) 

125 

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 

136 

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 

150 

151 def get_errors_total(self): 

152 return self._index-1 

153 

154 def get_indices(self): 

155 return self._errors.keys() 

156 

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) 

162 

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() 

170 

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 ) 

190 

191 _total_errors = self.get_errors_total() 

192 

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) 

199 

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") 

210 

211 if as_list: 

212 return _list 

213 else: 

214 return "\n".join(_list)