forked from IPKM/nmreval
run scripts Co-authored-by: Dominik Demuth <dominik.demuth@physik.tu-darmstadt.de> Reviewed-on: IPKM/nmreval#291
144 lines
4.6 KiB
Python
144 lines
4.6 KiB
Python
import logging
|
|
from pathlib import Path
|
|
|
|
from PyQt5 import QtWidgets
|
|
|
|
from ..editors.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])
|
|
|
|
|
|
class ConsoleDock(QtWidgets.QDockWidget):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent=parent)
|
|
|
|
self.code = QtWidgets.QPlainTextEdit(parent)
|
|
self.code.highlight = LogHighlighter(self.code.document())
|
|
self.code.setReadOnly(True)
|
|
self.code.setMaximumBlockCount(50)
|
|
self.setWidget(self.code)
|
|
|
|
|
|
class QTextHandler(logging.Handler):
|
|
def __init__(self, parent):
|
|
super().__init__()
|
|
|
|
self.console = ConsoleDock(parent)
|
|
self.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
|
|
self.setLevel(logging.WARNING)
|
|
|
|
def emit(self, record):
|
|
msg = self.format(record)
|
|
self.console.code.appendPlainText(msg)
|
|
self.console.show()
|