diff --git a/bumblebee-status b/bumblebee-status index 248ff52..a349466 100755 --- a/bumblebee-status +++ b/bumblebee-status @@ -1,6 +1,8 @@ #!/usr/bin/env python +import os import sys +import logging import bumblebee.theme import bumblebee.engine import bumblebee.config @@ -8,17 +10,42 @@ import bumblebee.output import bumblebee.input def main(): + logging.basicConfig( + level=logging.DEBUG, + format="[%(asctime)s] %(levelname)-8s %(message)s", + filename="{}/debug.log".format(os.path.dirname(os.path.realpath(__file__))) + ) config = bumblebee.config.Config(sys.argv[1:]) theme = bumblebee.theme.Theme(config.theme()) output = bumblebee.output.I3BarOutput(theme=theme) inp = bumblebee.input.I3BarInput() - engine = bumblebee.engine.Engine( - config=config, - output=output, - inp=inp, - ) + engine = None - engine.run() + try: + engine = bumblebee.engine.Engine( + config=config, + output=output, + inp=inp, + ) + engine.run() + except BaseException as e: + logging.exception(e) + if output.started(): + output.flush() + output.end() + else: + output.start() + import time + while True: + output.begin() + error = bumblebee.modules.error.Module(engine, config) + error.set("exception occurred: {}".format(e)) + widget = error.widgets()[0] + widget.link_module(error) + output.draw(widget, error) + output.flush() + output.end() + time.sleep(1) # try: # except KeyboardInterrupt as error: # inp.stop() diff --git a/bumblebee/config.py b/bumblebee/config.py index 3086cff..53d3d1d 100644 --- a/bumblebee/config.py +++ b/bumblebee/config.py @@ -4,7 +4,9 @@ This module provides configuration information (loaded modules, module parameters, etc.) to all other components """ +import os import sys +import logging import argparse import textwrap import importlib @@ -14,6 +16,7 @@ MODULE_HELP = "Specify a space-separated list of modules to load. The order of t THEME_HELP = "Specify the theme to use for drawing modules" PARAMETER_HELP = "Provide configuration parameters in the form of .=" LIST_HELP = "Display a list of either available themes or available modules along with their parameters." +DEBUG_HELP = "Enable debug log ('debug.log' located in the same directory as the bumblebee-status executable)" class print_usage(argparse.Action): def __init__(self, option_strings, dest, nargs=None, **kwargs): @@ -51,6 +54,8 @@ def create_parser(): help=PARAMETER_HELP) parser.add_argument("-l", "--list", choices=["modules", "themes"], action=print_usage, help=LIST_HELP) + parser.add_argument("-d", "--debug", action="store_true", + help=DEBUG_HELP) return parser class Config(bumblebee.store.Store): @@ -64,6 +69,9 @@ class Config(bumblebee.store.Store): parser = create_parser() self._args = parser.parse_args(args if args else []) + if not self._args.debug: + logger = logging.getLogger().disabled = True + for param in self._args.parameters: key, value = param.split("=") self.set(key, value) diff --git a/bumblebee/modules/error.py b/bumblebee/modules/error.py new file mode 100644 index 0000000..16d3834 --- /dev/null +++ b/bumblebee/modules/error.py @@ -0,0 +1,26 @@ +# pylint: disable=C0111,R0903 + +"""Draws an error widget. +""" + +import bumblebee.input +import bumblebee.output +import bumblebee.engine + +class Module(bumblebee.engine.Module): + def __init__(self, engine, config): + super(Module, self).__init__(engine, config, + bumblebee.output.Widget(full_text=self.text) + ) + self._text = "" + + def set(self, text): + self._text = text + + def text(self, widget): + return self._text + + def state(self, widget): + return ["critical"] + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/bumblebee/output.py b/bumblebee/output.py index 974e651..578fb30 100644 --- a/bumblebee/output.py +++ b/bumblebee/output.py @@ -50,9 +50,14 @@ class I3BarOutput(object): def __init__(self, theme): self._theme = theme self._widgets = [] + self._started = False + + def started(self): + return self._started def start(self): """Print start preamble for i3bar protocol""" + self._started = True sys.stdout.write(json.dumps({"version": 1, "click_events": True}) + "[\n") def stop(self): diff --git a/bumblebee/util.py b/bumblebee/util.py index 07f8091..0e85184 100644 --- a/bumblebee/util.py +++ b/bumblebee/util.py @@ -1,4 +1,5 @@ import shlex +import logging import subprocess try: @@ -8,17 +9,21 @@ except ImportError: pass def execute(cmd, wait=True): + logging.info("executing command '{}'".format(cmd)) args = shlex.split(cmd) proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + rv = None if wait: out, _ = proc.communicate() if proc.returncode != 0: raise RuntimeError("{} exited with {}".format(cmd, proc.returncode)) if type(out) == str: - return out - return out.decode("utf-8") - return None + rv = out + else: + rv = out.decode("utf-8") + logging.info("command returned '{}'".format("" if not rv else rv)) + return rv def bytefmt(num): for unit in [ "", "Ki", "Mi", "Gi" ]: