nmreval/src/gui_qt/lib/logger.py
2023-01-10 19:46:19 +01:00

115 lines
3.8 KiB
Python

import sys
from pathlib import Path
from .codeeditor import _make_textformats
from ..Qt import QtWidgets, QtCore, QtGui
from nmreval.configs import config_paths
STYLES = {'INFO': _make_textformats('black'),
'WARNING': _make_textformats('blue'),
'ERROR': _make_textformats('red', 'bold'),
'DEBUG': _make_textformats('black', 'italic'),
'file': _make_textformats('red', 'italic'),
'PyError': _make_textformats('red', 'bold-italic')}
class LogHighlighter(QtGui.QSyntaxHighlighter):
msg = ['INFO', 'DEBUG', 'ERROR', 'WARNING']
def __init__(self, parent):
super(LogHighlighter, self).__init__(parent)
rules = list()
rules += [(r'\b\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} - %s - .*' % m, 0, STYLES[m]) for m in LogHighlighter.msg]
rules += [(r'\b[A-Z]\w*Error: .*\b', 0, STYLES['PyError'])]
rules += [(r'\bFile .*', 0, STYLES['file'])]
self.rules = [(QtCore.QRegExp(pat), index, fmt) for (pat, index, fmt) in rules]
def highlightBlock(self, text):
"""Apply syntax highlighting to the given block of text.
"""
# Do other syntax formatting
for expression, nth, format in self.rules:
index = expression.indexIn(text, 0)
while index >= 0:
# We actually want the index of the nth match
index = expression.pos(nth)
try:
length = expression.cap(nth).length()
except AttributeError:
length = len(expression.cap(nth))
self.setFormat(index, length, format)
index = expression.indexIn(text, index + length)
self.setCurrentBlockState(0)
def match_multiline(self, text, delimiter, in_state, style):
if self.previousBlockState() == in_state:
start = 0
add = 0
else:
start = delimiter.indexIn(text)
add = delimiter.matchedLength()
while start >= 0:
end = delimiter.indexIn(text, start + add)
if end >= add:
length = end - start + add + delimiter.matchedLength()
self.setCurrentBlockState(0)
else:
self.setCurrentBlockState(in_state)
try:
length = text.length() - start + add
except AttributeError:
length = len(text) - start + add
# Apply formatting
self.setFormat(start, length, style)
# Look for the next match
start = delimiter.indexIn(text, start + length)
# Return True if still inside a multi-line string, False otherwise
if self.currentBlockState() == in_state:
return True
else:
return False
class QLog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(QLog, self).__init__(parent=parent)
self._initUi()
self.logfile = config_paths() / 'errors.log'
self.read_log()
def _initUi(self):
self.resize(960, 640)
layout = QtWidgets.QVBoxLayout()
self.plainTextEdit = QtWidgets.QPlainTextEdit()
self.plainTextEdit.highlight = LogHighlighter(self.plainTextEdit.document())
self.plainTextEdit.setReadOnly(True)
self.plainTextEdit.setMaximumBlockCount(50)
layout.addWidget(self.plainTextEdit)
self.buttonBox = QtWidgets.QDialogButtonBox()
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
layout.addWidget(self.buttonBox)
self.setLayout(layout)
def read_log(self):
with Path(self.logfile).open('r') as f:
text = f.readlines()
for lines in text[-100:]:
self.plainTextEdit.appendPlainText(lines[:-1])