From 1bd3c0c9de01555435559b242c864fcd2a712579 Mon Sep 17 00:00:00 2001
From: emkael <emkael@tlen.pl>
Date: Fri, 26 Jul 2019 10:09:46 +0200
Subject: Logging facilities for GUI

---
 jfr_playoff/gui/__init__.py |  5 ++-
 jfr_playoff/gui/logframe.py | 84 +++++++++++++++++++++++++++++++++++++++++++++
 jfr_playoff/logger.py       |  3 +-
 3 files changed, 89 insertions(+), 3 deletions(-)
 create mode 100644 jfr_playoff/gui/logframe.py

(limited to 'jfr_playoff')

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
-- 
cgit v1.2.3