Coverage for GuiLogView.py: 0%
117 statements
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-15 19:33 +0000
« 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 -*-
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.
18from __future__ import division
20# import L10n
21# _ = L10n.get_translation()
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)
36import os
37import logging
38from itertools import groupby
39from functools import partial
40import Configuration
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")
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]
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
67 self.logfile = os.path.join(self.config.dir_log, LOGFILES[1][1])
69 self.resize(700, 400)
71 self.setLayout(QVBoxLayout())
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)
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)
88 hb2 = QHBoxLayout()
89 refreshbutton = QPushButton("Refresh")
90 refreshbutton.clicked.connect(self.refresh)
91 hb2.addWidget(refreshbutton)
93 copybutton = QPushButton("Selection Copy to Clipboard")
94 copybutton.clicked.connect(self.copy_to_clipboard)
95 hb2.addWidget(copybutton)
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)
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)
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)
117 self.layout().addLayout(hb1)
118 self.layout().addLayout(hb2)
120 self.loadLog()
121 self.show()
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")
134 self.loadLog(selected_levels)
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)
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
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()
159 def get_dialog(self):
160 return self.dia
162 def loadLog(self, selected_levels=None):
163 self.liststore.clear()
164 self.liststore.setHorizontalHeaderLabels(
165 ["Date/Time", "Functionality", "Level", "Module", "Function", "Message"]
166 )
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
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)
183 self.listview.resizeColumnsToContents()
185 def refresh(self, checkState):
186 self.loadLog()
189if __name__ == "__main__":
190 config = Configuration.Config()
192 from PyQt5.QtWidgets import QApplication, QMainWindow
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_()