diff options
author | emkael <emkael@tlen.pl> | 2019-07-26 10:09:46 +0200 |
---|---|---|
committer | emkael <emkael@tlen.pl> | 2019-07-26 10:09:46 +0200 |
commit | 1bd3c0c9de01555435559b242c864fcd2a712579 (patch) | |
tree | 6758cdc54f386d52c3947141b75d23931ef6134f | |
parent | 7879c847b3b1aa2a9b6775e38dbad22de5b37e96 (diff) |
Logging facilities for GUI
-rw-r--r-- | jfr_playoff/gui/__init__.py | 5 | ||||
-rw-r--r-- | jfr_playoff/gui/logframe.py | 84 | ||||
-rw-r--r-- | jfr_playoff/logger.py | 3 | ||||
-rw-r--r-- | playoff.py | 9 |
4 files changed, 94 insertions, 7 deletions
diff --git a/jfr_playoff/gui/__init__.py b/jfr_playoff/gui/__init__.py index a0dedc9..5981fc0 100644 --- a/jfr_playoff/gui/__init__.py +++ b/jfr_playoff/gui/__init__.py @@ -12,6 +12,7 @@ from .tabs import * from .icons import GuiImage from .frames import LabelButton, NumericSpinbox from .variables import NumericVar +from .logframe import LogWindow class PlayoffGUI(tk.Tk): def __init__(self): @@ -20,6 +21,7 @@ class PlayoffGUI(tk.Tk): ttk.Style().configure('TLabelframe', padding=5) self.geometry('920x640') self.tabs = {} + self.logWindow = LogWindow(self) self._buildMenu() self.newFileIndex = 0 self._title = tk.StringVar() @@ -144,7 +146,8 @@ class PlayoffGUI(tk.Tk): pass def onLogWindowOpen(self): - pass + self.logWindow.update() + self.logWindow.deiconify() def newFile(self): self._filepath = None diff --git a/jfr_playoff/gui/logframe.py b/jfr_playoff/gui/logframe.py new file mode 100644 index 0000000..28e3487 --- /dev/null +++ b/jfr_playoff/gui/logframe.py @@ -0,0 +1,84 @@ +#coding=utf-8 + +import datetime +import logging as log +from collections import OrderedDict + +import tkinter as tk +from tkinter import ttk +import tkFileDialog as tkfd + +class LogWindow(tk.Toplevel): + def __init__(self, *args, **kwargs): + tk.Toplevel.__init__(self, *args, **kwargs) + self.withdraw() + self.protocol('WM_DELETE_WINDOW', self.withdraw) + self.renderContents() + self._registerLogging() + self._records = [] + self._counter = -1 + + def renderContents(self): + columns = OrderedDict([ + ('level', 'Poziom komunikatu'), + ('category', 'Moduł'), + ('message', 'Komunikat')]) + self.logList = ttk.Treeview( + self, show='headings', + columns=columns.keys(), + selectmode='browse') + for column, heading in columns.iteritems(): + self.logList.heading(column, text=heading) + self.logList.pack(side=tk.TOP, fill=tk.BOTH, expand=True) + btnFrame = tk.Frame(self) + btnFrame.pack(side=tk.BOTTOM) + (ttk.Button( + btnFrame, text='Zapisz dziennik...', + command=self.onRecordsSave)).pack(side=tk.LEFT) + (ttk.Button( + btnFrame, text='Wyczyść dziennik', + command=self.resetRecords)).pack(side=tk.LEFT) + + def _registerLogging(self): + logHandler = LogHandler(log.INFO, window=self) + logger = log.getLogger() + logger.setLevel(log.INFO) + logger.addHandler(logHandler) + + def addRecord(self, record): + self._counter += 1 + self._records.append((record, datetime.datetime.now())) + self.logList.insert( + '', tk.END, tag=self._counter, values=[ + record.levelname, record.name, record.message + ]) + + def resetRecords(self): + self._records = [] + self.logList.delete(*self.logList.get_children()) + + def onRecordsSave(self, *args): + filename = tkfd.asksaveasfilename( + title='Wybierz plik dziennika', + filetypes=(('Log files', '*.log'),)) + if filename: + if not filename.lower().endswith('.log'): + filename = filename + '.log' + self._saveRecords(filename) + + def _saveRecords(self, filename): + with open(filename, 'w') as fileObj: + for record, timestamp in self._records: + fileObj.write('%s\t%s\t%s\t%s' % ( + timestamp, record.levelname, record.name, record.message)) + + +class LogHandler(log.Handler): + def __init__(self, *args, **kwargs): + self._window = kwargs['window'] + del kwargs['window'] + log.Handler.__init__(self, *args, **kwargs) + + def handle(self, record): + self.format(record) + self._window.addRecord(record) diff --git a/jfr_playoff/logger.py b/jfr_playoff/logger.py index 8944e5b..1218022 100644 --- a/jfr_playoff/logger.py +++ b/jfr_playoff/logger.py @@ -6,8 +6,7 @@ class PlayoffLogger: @classmethod def setup(cls, level): log.basicConfig( - level=getattr(log, level), - streamhandler=log.StreamHandler(), + level=level, format='%(levelname)-8s %(name)-8s %(message)s') @classmethod @@ -1,4 +1,4 @@ -import traceback +import logging, traceback from jfr_playoff.filemanager import PlayoffFileManager from jfr_playoff.generator import PlayoffGenerator @@ -26,9 +26,10 @@ def main(): type=str, nargs='?', default=None) arguments = arg_parser.parse_args() - PlayoffLogger.setup('ERROR' if arguments.quiet else ( - 'INFO' if arguments.verbose else ( - 'DEBUG' if arguments.debug else 'WARNING'))) + PlayoffLogger.setup( + level=logging.ERROR if arguments.quiet else ( + logging.INFO if arguments.verbose else ( + logging.DEBUG if arguments.debug else logging.WARNING))) PlayoffLogger.get().info('started with arguments: %s', arguments) |