Coverage for GuiLogView.py: 0%

117 statements  

« prev     ^ index     » next       coverage.py v7.6.3, created at 2024-10-15 19:33 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4# Copyright 2008-2011 Carl Gherardi 

5# This program is free software: you can redistribute it and/or modify 

6# it under the terms of the GNU Affero General Public License as published by 

7# the Free Software Foundation, version 3 of the License. 

8# 

9# This program is distributed in the hope that it will be useful, 

10# but WITHOUT ANY WARRANTY; without even the implied warranty of 

11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

12# GNU General Public License for more details. 

13# 

14# You should have received a copy of the GNU Affero General Public License 

15# along with this program. If not, see <http://www.gnu.org/licenses/>. 

16# In the "official" distribution you can find the license in agpl-3.0.txt. 

17 

18from __future__ import division 

19 

20# import L10n 

21# _ = L10n.get_translation() 

22 

23 

24from PyQt5.QtGui import QStandardItem, QStandardItemModel 

25from PyQt5.QtWidgets import ( 

26 QApplication, 

27 QPushButton, 

28 QHBoxLayout, 

29 QRadioButton, 

30 QTableView, 

31 QVBoxLayout, 

32 QWidget, 

33 QCheckBox, 

34) 

35 

36import os 

37import logging 

38from itertools import groupby 

39from functools import partial 

40import Configuration 

41 

42if __name__ == "__main__": 

43 Configuration.set_logfile("fpdb-log.txt") 

44# logging has been set up in fpdb.py or HUD_main.py, use their settings: 

45log = logging.getLogger("logview") 

46 

47MAX_LINES = 100000 # max lines to display in window 

48EST_CHARS_PER_LINE = 150 # used to guesstimate number of lines in log file 

49# label, filename, start value, path 

50LOGFILES = [ 

51 ["Fpdb Errors", "fpdb-errors.txt", False, "log"], 

52 ["Fpdb Log", "fpdb-log.txt", True, "log"], 

53 ["HUD Errors", "HUD-errors.txt", False, "log"], 

54 ["HUD Log", "HUD-log.txt", False, "log"], 

55 ["fpdb.exe log", "fpdb.exe.log", False, "pyfpdb"], 

56 ["HUD_main.exe Log", "HUD_main.exe.log ", False, "pyfpdb"], 

57] 

58 

59 

60class GuiLogView(QWidget): 

61 def __init__(self, config, mainwin, closeq): 

62 QWidget.__init__(self) 

63 self.config = config 

64 self.main_window = mainwin 

65 self.closeq = closeq 

66 

67 self.logfile = os.path.join(self.config.dir_log, LOGFILES[1][1]) 

68 

69 self.resize(700, 400) 

70 

71 self.setLayout(QVBoxLayout()) 

72 

73 self.liststore = QStandardItemModel(0, 4) 

74 self.listview = QTableView() 

75 self.listview.setModel(self.liststore) 

76 self.listview.setSelectionBehavior(QTableView.SelectRows) 

77 self.listview.setShowGrid(False) 

78 self.listview.verticalHeader().hide() 

79 self.layout().addWidget(self.listview) 

80 

81 hb1 = QHBoxLayout() 

82 for logf in LOGFILES: 

83 rb = QRadioButton(logf[0], self) 

84 rb.setChecked(logf[2]) 

85 rb.clicked.connect(partial(self.__set_logfile, filename=logf[0])) 

86 hb1.addWidget(rb) 

87 

88 hb2 = QHBoxLayout() 

89 refreshbutton = QPushButton("Refresh") 

90 refreshbutton.clicked.connect(self.refresh) 

91 hb2.addWidget(refreshbutton) 

92 

93 copybutton = QPushButton("Selection Copy to Clipboard") 

94 copybutton.clicked.connect(self.copy_to_clipboard) 

95 hb2.addWidget(copybutton) 

96 

97 # Add checkboxes for log levels 

98 self.filter_debug = QCheckBox("DEBUG", self) 

99 self.filter_info = QCheckBox("INFO", self) 

100 self.filter_warning = QCheckBox("WARNING", self) 

101 self.filter_error = QCheckBox("ERROR", self) 

102 

103 # Connect checkboxes to the filter method 

104 self.filter_debug.stateChanged.connect(self.filter_log) 

105 self.filter_info.stateChanged.connect(self.filter_log) 

106 self.filter_warning.stateChanged.connect(self.filter_log) 

107 self.filter_error.stateChanged.connect(self.filter_log) 

108 

109 # Add checkboxes to layout 

110 hb3 = QHBoxLayout() 

111 hb3.addWidget(self.filter_debug) 

112 hb3.addWidget(self.filter_info) 

113 hb3.addWidget(self.filter_warning) 

114 hb3.addWidget(self.filter_error) 

115 self.layout().addLayout(hb3) 

116 

117 self.layout().addLayout(hb1) 

118 self.layout().addLayout(hb2) 

119 

120 self.loadLog() 

121 self.show() 

122 

123 def filter_log(self): 

124 selected_levels = [] 

125 if self.filter_debug.isChecked(): 

126 selected_levels.append("DEBUG") 

127 if self.filter_info.isChecked(): 

128 selected_levels.append("INFO") 

129 if self.filter_warning.isChecked(): 

130 selected_levels.append("WARNING") 

131 if self.filter_error.isChecked(): 

132 selected_levels.append("ERROR") 

133 

134 self.loadLog(selected_levels) 

135 

136 def copy_to_clipboard(self, checkState): 

137 text = "" 

138 for row, indexes in groupby(self.listview.selectedIndexes(), lambda i: i.row()): 

139 text += " ".join([i.data() for i in indexes]) + "\n" 

140 # print(text) 

141 QApplication.clipboard().setText(text) 

142 

143 def __set_logfile(self, checkState, filename): 

144 # print "w is", w, "file is", file, "active is", w.get_active() 

145 if checkState: 

146 for logf in LOGFILES: 

147 if logf[0] == filename: 

148 if logf[3] == "pyfpdb": 

149 self.logfile = os.path.join(self.config.pyfpdb_path, logf[1]) 

150 else: 

151 self.logfile = os.path.join(self.config.dir_log, logf[1]) 

152 self.refresh(checkState) # params are not used 

153 

154 def dialog_response_cb(self, dialog, response_id): 

155 # this is called whether close button is pressed or window is closed 

156 self.closeq.put(self.__class__) 

157 dialog.destroy() 

158 

159 def get_dialog(self): 

160 return self.dia 

161 

162 def loadLog(self, selected_levels=None): 

163 self.liststore.clear() 

164 self.liststore.setHorizontalHeaderLabels( 

165 ["Date/Time", "Functionality", "Level", "Module", "Function", "Message"] 

166 ) 

167 

168 if os.path.exists(self.logfile): 

169 with open(self.logfile, "r") as log_file: 

170 for line in log_file: 

171 parts = line.strip().split(" - ") 

172 if len(parts) == 6: 

173 date_time, functionality, level, module, function, message = parts 

174 

175 # Filter log entries based on selected log levels 

176 if selected_levels is None or level in selected_levels: 

177 tablerow = [date_time, functionality, level, module, function, message] 

178 tablerow = [QStandardItem(i) for i in tablerow] 

179 for item in tablerow: 

180 item.setEditable(False) 

181 self.liststore.appendRow(tablerow) 

182 

183 self.listview.resizeColumnsToContents() 

184 

185 def refresh(self, checkState): 

186 self.loadLog() 

187 

188 

189if __name__ == "__main__": 

190 config = Configuration.Config() 

191 

192 from PyQt5.QtWidgets import QApplication, QMainWindow 

193 

194 app = QApplication([]) 

195 main_window = QMainWindow() 

196 i = GuiLogView(config, main_window, None) 

197 main_window.show() 

198 main_window.resize(1400, 800) 

199 app.exec_()