over/core/core.20-Output.pyx

153 lines
3.5 KiB
Cython

class prefix:
info = (" ", "INFO")
debug = (" §b?§/", "§bDEBG§/")
start = ("§B>>>§/", "§BEXEC§/")
exec = start
warn = (" §y#§/", "§yWARN§/")
fail = ("§r!!!§/", "§rFAIL§/")
done = (" §g*§/", "§gDONE§/")
colortags = {
"§r": "\x1b[31;01m",
"§g": "\x1b[32;01m",
"§y": "\x1b[33;01m",
"§b": "\x1b[34;01m",
"§m": "\x1b[35;01m",
"§c": "\x1b[36;01m",
"§B": "\x1b[01m",
"§/": "\x1b[39;49;00m"
}
def render(text, colors=True):
"""
Processes text with color tags and either
removes them (with colors=False) or replaces
them with terminal color codes.
"""
text = str(text)
if colors:
tags = re.findall('§[^§]', text)
for tag in tags:
try:
text = text.replace(tag, colortags[tag])
except KeyError:
pass
else:
text = re.sub('§[^§]', '', text)
# unescape actual paragraphs
text = re.sub('§§', '§', text)
return text
def char_length(string):
"""
Returns the length of a string minus all formatting tags.
"""
plain_string = render(string, colors=False)
return len(plain_string)
class Output:
"""
Text UI output renderer.
Prints messages to the stdout with optional eye candy
like colors and timestamps.
Usage:
>>> from over import Output, prefix
>>> say = Output("test", timestamp=True)
>>> say("system initialized")
[2013-02-28 16:41:28] INFO -- test, system initialized
>>> say("system is FUBAR", prefix.fail)
[2013-02-28 16:41:46] FAIL -- test, system is FUBAR
>>> say("I just realized this will not work", prefix.fail, timestamp=False)
!!! I just realized this will not work
TODO initialize with target output streams (which only need to implement .write)
"""
def __init__(self, name, default_suffix="\n", timestamp=False, colors=True, default_prefix=prefix.info, tb=False):
self.name = name
self.timestamp = timestamp
self.colors = colors
self.default_prefix = default_prefix
self.default_suffix = default_suffix
self.tb = tb
def __call__(self, text, prefix=None, suffix=None, indent=0, timestamp=None, colors=None, display_name=True, exc=None, tb=None):
if prefix is None:
prefix = self.default_prefix
if type(prefix) is str:
prefix = (prefix, prefix)
if suffix is None:
suffix = self.default_suffix
if timestamp is None:
timestamp = self.timestamp
if colors is None:
colors = self.colors
if tb is None:
tb = self.tb
output = []
# [2012-11-11 16:52:06] INFO -- ahoj
if timestamp:
output.append(time.strftime('[%Y-%m-%d %H:%M:%S] '))
output.append(prefix[1])
output.append(" -- ")
elif prefix:
output.append(prefix[0])
output.append(" ")
if display_name and self.name:
output.append("%s, " %(self.name))
#output.append(paragraph(str(text), indent=indent))
output.append(str(text))
if suffix:
output.append(suffix)
output = "".join(output)
sys.stdout.write(render(output, colors))
sys.stdout.flush()
if exc:
if exc is True:
if tb:
raise
else:
if sys.exc_info()[0]:
self.__call__("unhandled exception %s raised" %(sys.exc_info()[0].__name__), timestamp=True)
#sys.exit(1)
raise
else:
if tb:
raise exc(render(text, colors=False))
else:
self.__call__("unhandled exception %s raised" %(exc.__name__), timestamp=True)
raise exc
#sys.exit(1)
def get_terminal_size():
"""
Returns current terminal's (rows, cols).
"""
terminal = sys.stdout.fileno()
try:
return struct.unpack("HHHH", fcntl.ioctl(terminal, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))
except IOError:
return (40, 80)