mirror of
https://github.com/frappe/frappe_docker.git
synced 2026-06-19 22:55:10 +00:00
82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
from collections import namedtuple
|
|
import sys
|
|
|
|
from .compat import ON_WINDOWS
|
|
|
|
Message = namedtuple("Message", "type data time name colour")
|
|
|
|
|
|
class Printer(object):
|
|
"""
|
|
Printer is where Honcho's user-visible output is defined. A Printer
|
|
instance receives typed messages and prints them to its output (usually
|
|
STDOUT) in the Honcho format.
|
|
"""
|
|
|
|
def __init__(self,
|
|
output=sys.stdout,
|
|
time_format="%H:%M:%S",
|
|
width=0,
|
|
colour=True,
|
|
prefix=True):
|
|
self.output = output
|
|
self.time_format = time_format
|
|
self.width = width
|
|
self.colour = colour
|
|
self.prefix = prefix
|
|
|
|
try:
|
|
# We only want to print coloured messages if the given output supports
|
|
# ANSI escape sequences. Usually, testing if it is a TTY is safe enough.
|
|
self._colours_supported = self.output.isatty()
|
|
except AttributeError:
|
|
# If the given output does not implement isatty(), we assume that it
|
|
# is not able to handle ANSI escape sequences.
|
|
self._colours_supported = False
|
|
|
|
def write(self, message):
|
|
if message.type != 'line':
|
|
raise RuntimeError('Printer can only process messages of type "line"')
|
|
|
|
name = message.name if message.name is not None else ""
|
|
name = name.ljust(self.width)
|
|
if name:
|
|
name += " "
|
|
|
|
# When encountering data that cannot be interpreted as UTF-8 encoded
|
|
# Unicode, Printer will replace the unrecognisable bytes with the
|
|
# Unicode replacement character (U+FFFD).
|
|
if isinstance(message.data, bytes):
|
|
string = message.data.decode("utf-8", "replace")
|
|
else:
|
|
string = message.data
|
|
|
|
for line in string.splitlines():
|
|
prefix = ''
|
|
if self.prefix:
|
|
time_formatted = message.time.strftime(self.time_format)
|
|
prefix = '{time} {name}| '.format(time=time_formatted, name=name)
|
|
if self.colour and self._colours_supported and message.colour:
|
|
prefix = _colour_string(message.colour, prefix)
|
|
self.output.write(prefix + line + "\n")
|
|
|
|
|
|
def _ansi(code):
|
|
return '\033[{0}m'.format(code)
|
|
|
|
|
|
def _colour_string(colour, s):
|
|
return '{0}{1}{2}{3}'.format(_ansi(0), _ansi(colour), s, _ansi(0))
|
|
|
|
|
|
if ON_WINDOWS:
|
|
# The colorama package provides transparent support for ANSI colour codes
|
|
# on Win32 platforms. We try and import and configure that, but fall back
|
|
# to no colour if we fail.
|
|
try:
|
|
import colorama
|
|
except ImportError:
|
|
def _colour_string(colour, s): # noqa
|
|
return s
|
|
else:
|
|
colorama.init()
|