Coverage for GuiLogView.py: 0%

120 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-28 16:41 +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 

20from past.utils import old_div 

21#import L10n 

22#_ = L10n.get_translation() 

23 

24import queue 

25 

26from PyQt5.QtGui import (QStandardItem, QStandardItemModel) 

27from PyQt5.QtWidgets import (QApplication, QDialog, QPushButton, QHBoxLayout, QRadioButton, 

28 QTableView, QVBoxLayout, QWidget, QCheckBox) 

29 

30import os 

31import traceback 

32import logging 

33from itertools import groupby 

34from functools import partial 

35import Configuration 

36if __name__ == "__main__": 

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

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

39log = logging.getLogger("logview") 

40 

41MAX_LINES = 100000 # max lines to display in window 

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

43# label, filename, start value, path 

44LOGFILES = [['Fpdb Errors', 'fpdb-errors.txt', False, 'log'], 

45 ['Fpdb Log', 'fpdb-log.txt', True, 'log'], 

46 ['HUD Errors', 'HUD-errors.txt', False, 'log'], 

47 ['HUD Log', 'HUD-log.txt', False, 'log'], 

48 ['fpdb.exe log', 'fpdb.exe.log', False, 'pyfpdb'], 

49 ['HUD_main.exe Log', 'HUD_main.exe.log ', False, 'pyfpdb'] 

50 ] 

51 

52class GuiLogView(QWidget): 

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

54 QWidget.__init__(self) 

55 self.config = config 

56 self.main_window = mainwin 

57 self.closeq = closeq 

58 

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

60 

61 self.resize(700, 400) 

62 

63 self.setLayout(QVBoxLayout()) 

64 

65 self.liststore = QStandardItemModel(0, 4) 

66 self.listview = QTableView() 

67 self.listview.setModel(self.liststore) 

68 self.listview.setSelectionBehavior(QTableView.SelectRows) 

69 self.listview.setShowGrid(False) 

70 self.listview.verticalHeader().hide() 

71 self.layout().addWidget(self.listview) 

72 

73 hb1 = QHBoxLayout() 

74 for logf in LOGFILES: 

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

76 rb.setChecked(logf[2]) 

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

78 hb1.addWidget(rb) 

79 

80 hb2 = QHBoxLayout() 

81 refreshbutton = QPushButton("Refresh") 

82 refreshbutton.clicked.connect(self.refresh) 

83 hb2.addWidget(refreshbutton) 

84 

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

86 copybutton.clicked.connect(self.copy_to_clipboard) 

87 hb2.addWidget(copybutton) 

88 

89 # Add checkboxes for log levels 

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

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

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

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

94 

95 # Connect checkboxes to the filter method 

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

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

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

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

100 

101 # Add checkboxes to layout 

102 hb3 = QHBoxLayout() 

103 hb3.addWidget(self.filter_debug) 

104 hb3.addWidget(self.filter_info) 

105 hb3.addWidget(self.filter_warning) 

106 hb3.addWidget(self.filter_error) 

107 self.layout().addLayout(hb3) 

108 

109 self.layout().addLayout(hb1) 

110 self.layout().addLayout(hb2) 

111 

112 self.loadLog() 

113 self.show() 

114 

115 def filter_log(self): 

116 selected_levels = [] 

117 if self.filter_debug.isChecked(): 

118 selected_levels.append("DEBUG") 

119 if self.filter_info.isChecked(): 

120 selected_levels.append("INFO") 

121 if self.filter_warning.isChecked(): 

122 selected_levels.append("WARNING") 

123 if self.filter_error.isChecked(): 

124 selected_levels.append("ERROR") 

125 

126 self.loadLog(selected_levels) 

127 

128 def copy_to_clipboard(self, checkState): 

129 text = "" 

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

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

132 # print(text) 

133 QApplication.clipboard().setText(text) 

134 

135 def __set_logfile(self, checkState, filename): 

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

137 if checkState: 

138 for logf in LOGFILES: 

139 if logf[0] == filename: 

140 if logf[3] == 'pyfpdb': 

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

142 else: 

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

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

145 

146 def dialog_response_cb(self, dialog, response_id): 

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

148 self.closeq.put(self.__class__) 

149 dialog.destroy() 

150 

151 def get_dialog(self): 

152 return self.dia 

153 

154 def loadLog(self, selected_levels=None): 

155 self.liststore.clear() 

156 self.liststore.setHorizontalHeaderLabels( 

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

158 

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

160 with open(self.logfile, 'r') as log_file: 

161 for line in log_file: 

162 parts = line.strip().split(' - ') 

163 if len(parts) == 6: 

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

165 

166 # Filter log entries based on selected log levels 

167 if selected_levels is None or level in selected_levels: 

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

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

170 for item in tablerow: 

171 item.setEditable(False) 

172 self.liststore.appendRow(tablerow) 

173 

174 self.listview.resizeColumnsToContents() 

175 

176 def refresh(self, checkState): 

177 self.loadLog() 

178 

179 

180 

181if __name__=="__main__": 

182 config = Configuration.Config() 

183 

184 from PyQt5.QtWidgets import QApplication, QMainWindow 

185 app = QApplication([]) 

186 main_window = QMainWindow() 

187 i = GuiLogView(config, main_window, None) 

188 main_window.show() 

189 main_window.resize(1400, 800) 

190 app.exec_()