diff --git a/display.py b/display.py index f0563b6a75120e5c66ae8cece954640a8addb652..14820797de908ddfbdf541a30f942123bfbe8fcc 100644 --- a/display.py +++ b/display.py @@ -24,29 +24,63 @@ import fcntl import time import textwrap import subprocess +import logging from struct import unpack, pack from termios import TIOCGWINSZ from ammsml.utils.color import stringc -from ammsml.utils.parsing import to_text +from ammsml.utils.parsing import to_text, boolean from ammsml.utils.errors import AMMSMLError from ammsml.utils.singleton import Singleton, with_metaclass from ammsml.config import constants as C from ammsml.utils.wrap import wrap_var +class FilterBlackList(logging.Filter): + def __init__(self, blacklist): + self.blacklist = [logging.Filter(name) for name in blacklist] + + def filter(self, record): + return not any(f.filter(record) for f in self.blacklist) + + +logger = None +# TODO: make this a callback event instead +# if getattr(C, 'DEFAULT_LOG_PATH'): +# path = C.DEFAULT_LOG_PATH +# if path and (os.path.exists(path) and os.access(path, os.W_OK)) or os.access(os.path.dirname(path), os.W_OK): +# logging.basicConfig(filename=path, level=logging.INFO, format='%(asctime)s p=%(user)s u=%(process)d | %(message)s') +# logger = logging.LoggerAdapter(logging.getLogger('ammsml'), {'user': getpass.getuser()}) +# for handler in logging.root.handlers: +# handler.addFilter(FilterBlackList(getattr(C, 'DEFAULT_LOG_FILTER', []))) +# else: +# print("[WARNING]: log file at %s is not writeable and we cannot create it, aborting\n" % path, file=sys.stderr) + + +# map color to log levels +# TODO may be better in utils.color? +color_to_log_level = {C.COLOR_ERROR: logging.ERROR, + C.COLOR_WARN: logging.WARNING, + C.COLOR_OK: logging.INFO, + C.COLOR_SKIP: logging.WARNING, + # C.COLOR_UNREACHABLE: logging.ERROR, + C.COLOR_DEBUG: logging.DEBUG, + # C.COLOR_CHANGED: logging.INFO, + C.COLOR_DEPRECATE: logging.WARNING, + C.COLOR_VERBOSE: logging.INFO} + b_COW_PATHS = ( - b"/usr/bin/cowsay", - b"/usr/games/cowsay", - b"/usr/local/bin/cowsay", # BSD path for cowsay - b"/opt/local/bin/cowsay", # MacPorts path for cowsay + b'/usr/bin/cowsay', + b'/usr/games/cowsay', + b'/usr/local/bin/cowsay', # BSD path for cowsay + b'/opt/local/bin/cowsay', # MacPorts path for cowsay ) class Display(with_metaclass(Singleton, object)): - def __init__(self, verbosity: int=0): + def __init__(self, verbosity: int = 0): self.columns = None self.verbosity = verbosity @@ -100,8 +134,7 @@ class Display(with_metaclass(Singleton, object)): else: msg2 = msg - msg2 = to_text(msg2) - + msg2 = to_text(msg2, self._output_encoding(stderr=stderr)) if not stderr: fileobj = sys.stdout else: @@ -136,8 +169,8 @@ class Display(with_metaclass(Singleton, object)): return self.verbose(msg, host=host, caplevel=5) def debug(self, msg, host=None): - # TODO TODO - if C.DEFAULT_DEBUG: + # TODO boolean() neccesary? + if boolean(C.DEFAULT_DEBUG): if host is None: self.display("%6d %0.5f: %s" % (os.getpid(), time.time(), msg), color=C.COLOR_DEBUG) else: @@ -263,7 +296,7 @@ class Display(with_metaclass(Singleton, object)): result = default # handle utf-8 chars - result = to_text(result, errors='surrogate_or_strict') + result = to_text(result) if unsafe: result = wrap_var(result) @@ -272,11 +305,6 @@ class Display(with_metaclass(Singleton, object)): @staticmethod def _output_encoding(stderr=False): encoding = locale.getpreferredencoding() - # https://bugs.python.org/issue6202 - # Python2 hardcodes an obsolete value on Mac. Use MacOSX defaults - # instead. - if encoding in ('mac-roman',): - encoding = 'utf-8' return encoding def _set_column_width(self):