import logging import os import re import sh from sys import stdout, stderr from math import log10 from collections import defaultdict from colorama import Style as Colo_Style, Fore as Colo_Fore # monkey patch to show full output sh.ErrorReturnCode.truncate_cap = 999999 class LevelDifferentiatingFormatter(logging.Formatter): def format(self, record): if record.levelno > 30: record.msg = '{}{}[ERROR]{}{}: '.format( Err_Style.BRIGHT, Err_Fore.RED, Err_Fore.RESET, Err_Style.RESET_ALL) + record.msg elif record.levelno > 20: record.msg = '{}{}[WARNING]{}{}: '.format( Err_Style.BRIGHT, Err_Fore.RED, Err_Fore.RESET, Err_Style.RESET_ALL) + record.msg elif record.levelno > 10: record.msg = '{}[INFO]{}: '.format( Err_Style.BRIGHT, Err_Style.RESET_ALL) + record.msg else: record.msg = '{}{}[DEBUG]{}{}: '.format( Err_Style.BRIGHT, Err_Fore.LIGHTBLACK_EX, Err_Fore.RESET, Err_Style.RESET_ALL) + record.msg return super().format(record) logger = logging.getLogger('p4a') # Necessary as importlib reloads this, # which would add a second handler and reset the level if not hasattr(logger, 'touched'): logger.setLevel(logging.INFO) logger.touched = True ch = logging.StreamHandler(stderr) formatter = LevelDifferentiatingFormatter('%(message)s') ch.setFormatter(formatter) logger.addHandler(ch) info = logger.info debug = logger.debug warning = logger.warning error = logger.error class colorama_shim: def __init__(self, real): self._dict = defaultdict(str) self._real = real self._enabled = False def __getattr__(self, key): return getattr(self._real, key) if self._enabled else self._dict[key] def enable(self, enable): self._enabled = enable Out_Style = colorama_shim(Colo_Style) Out_Fore = colorama_shim(Colo_Fore) Err_Style = colorama_shim(Colo_Style) Err_Fore = colorama_shim(Colo_Fore) def setup_color(color): enable_out = (False if color == 'never' else True if color == 'always' else stdout.isatty()) Out_Style.enable(enable_out) Out_Fore.enable(enable_out) enable_err = (False if color == 'never' else True if color == 'always' else stderr.isatty()) Err_Style.enable(enable_err) Err_Fo