Display early log errors/warns graphically
authorJack Miller <jack@codezen.org>
Thu, 11 Jun 2015 02:03:42 +0000 (21:03 -0500)
committerJack Miller <jack@codezen.org>
Thu, 11 Jun 2015 02:03:42 +0000 (21:03 -0500)
Instantiate the GraphicalLog object much earlier, so it can defer any
WARN/ERROR level logging. This allows stuff like config errors or
migration warnings to be displayed in the client instead of just in the
log.

canto_curses/config.py
canto_curses/gui.py
canto_curses/main.py

index ba17c60..4b4ef8a 100644 (file)
@@ -594,8 +594,8 @@ class CantoCursesConfig(SubThread):
         return (False, False)
 
     def migrate_color_block(self, val, d):
-        log.info("Migrating color config to use new color system")
-        log.info("See ':help color' if this butchers your colors")
+        log.warn("Migrating color config to use new color system")
+        log.warn("See ':help color' if this butchers your colors")
 
         r = { "1" : "unread",
               "2" : "read",
index 69c97d2..8fe4ae0 100644 (file)
@@ -25,11 +25,21 @@ import logging
 log = logging.getLogger("GUI")
 
 class GraphicalLog(logging.Handler):
-    def __init__(self, callbacks, screen):
+
+    # We want to be able to catch logging output before the screen is actually
+    # initialized in curses, and callbacks etc. are setup
+
+    def __init__(self):
         logging.Handler.__init__(self)
+        self.deferred_logs = []
+        self.callbacks = None
+
+        rootlog = logging.getLogger()
+        rootlog.addHandler(self)
+
+    def init(self, callbacks, screen):
         self.callbacks = callbacks
         self.screen = screen
-        self.deferred_logs = []
 
     def _emit(self, var, window_type, record):
         if window_type not in self.screen.window_types:
@@ -43,7 +53,14 @@ class GraphicalLog(logging.Handler):
         self.callbacks["set_var"]("needs_refresh", True)
 
     def emit(self, record):
-        quiet = self.callbacks["get_var"]("quiet")
+
+        # If we have no callbacks, GUI isn't initialized, assume that we only
+        # want to have warns/errors displayed immediately on startup.
+
+        if self.callbacks:
+            quiet = self.callbacks["get_var"]("quiet")
+        else:
+            quiet = True
         if record.levelno == logging.INFO and quiet:
             return
         self.deferred_logs.append(record)
@@ -51,7 +68,7 @@ class GraphicalLog(logging.Handler):
     # Call with sync_lock
     def flush_deferred_logs(self):
         for record in self.deferred_logs:
-            if record.levelno == logging.INFO:
+            if record.levelno in [ logging.INFO, logging.WARN ]:
                 self._emit("info_msg", InfoBox, record)
             elif record.levelno == logging.ERROR:
                 self._emit("error_msg", ErrorBox, record)
@@ -61,7 +78,7 @@ class GuiPlugin(Plugin):
     pass
 
 class CantoCursesGui(CommandHandler):
-    def __init__(self, backend):
+    def __init__(self, backend, glog_handler):
         CommandHandler.__init__(self)
         self.plugin_class = GuiPlugin
         self.update_plugin_lookups()
@@ -106,15 +123,13 @@ class CantoCursesGui(CommandHandler):
         self.screen.refresh()
         self.screen.redraw()
 
-        self.glog_handler = GraphicalLog(self.callbacks, self.screen)
+        self.glog_handler = glog_handler
+        self.glog_handler.init(self.callbacks, self.screen)
 
         self.graphical_thread = Thread(target = self.run_gui)
         self.graphical_thread.daemon = True
         self.graphical_thread.start()
 
-        rootlog = logging.getLogger()
-        rootlog.addHandler(self.glog_handler)
-
         register_command(self, "refresh", self.cmd_refresh, [], "Refetch everything from the daemon", "Base")
         register_command(self, "update", self.cmd_update, [], "Sync with daemon", "Base")
         register_command(self, "quit", self.cmd_quit, [], "Quit canto-curses", "Base")
index 0796ce7..99d592b 100644 (file)
@@ -15,7 +15,7 @@ from canto_next.hooks import call_hook
 
 from .config import config, finalize_eval_settings
 from .tagcore import tag_updater, alltagcores
-from .gui import CantoCursesGui
+from .gui import CantoCursesGui, GraphicalLog
 
 from threading import Thread
 from queue import Queue
@@ -71,6 +71,8 @@ class CantoCurses(CantoClient):
         rootlog = logging.getLogger()
         rootlog.setLevel(max(rootlog.level - 10 * self.verbosity,0))
 
+        self.glog_handler = GraphicalLog()
+
         try:
             if self.port < 0:
                 # If we're running locally, ensure daemon is running
@@ -208,7 +210,7 @@ class CantoCurses(CantoClient):
         tag_updater.init(self)
 
         # Create Tags for each TagCore
-        self.gui = CantoCursesGui(self)
+        self.gui = CantoCursesGui(self, self.glog_handler)
 
         # Generate initial traffic
         tag_updater.update()