# (c) 2012-2014, Michael DeHaan # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . from __future__ import (absolute_import, division, print_function) __metaclass__ = type import re import sys from ansible import constants as C ANSIBLE_COLOR = True if C.ANSIBLE_NOCOLOR: ANSIBLE_COLOR = False elif not hasattr(sys.stdout, 'isatty') or not sys.stdout.isatty(): ANSIBLE_COLOR = False else: try: import curses curses.setupterm() if curses.tigetnum('colors') < 0: ANSIBLE_COLOR = False except ImportError: # curses library was not found pass except curses.error: # curses returns an error (e.g. could not find terminal) ANSIBLE_COLOR = False if C.ANSIBLE_FORCE_COLOR: ANSIBLE_COLOR = True # --- begin "pretty" # # pretty - A miniature library that provides a Python print and stdout # wrapper that makes colored terminal text easier to use (e.g. without # having to mess around with ANSI escape sequences). This code is public # domain - there is no license except that you must leave this header. # # Copyright (C) 2008 Brian Nez def parsecolor(color): """SGR parameter string for the specified color name.""" matches = re.match(r"color(?P[0-9]+)" r"|(?Prgb(?P[0-5])(?P[0-5])(?P[0-5]))" r"|gray(?P[0-9]+)", color) if not matches: return C.COLOR_CODES[color] if matches.group('color'): return u'38;5;%d' % int(matches.group('color')) if matches.group('rgb'): return u'38;5;%d' % (16 + 36 * int(matches.group('red')) + 6 * int(matches.group('green')) + int(matches.group('blue'))) if matches.group('gray'): return u'38;5;%d' % (232 + int(matches.group('gray'))) def stringc(text, color, wrap_nonvisible_chars=False): """String in color.""" if ANSIBLE_COLOR: color_code = parsecolor(color) fmt = u"\033[%sm%s\033[0m" if wrap_nonvisible_chars: # This option is provided for use in cases when the # formatting of a command line prompt is needed, such as # `ansible-console`. As said in `readline` sources: # readline/display.c:321 # /* Current implementation: # \001 (^A) start non-visible characters # \002 (^B) end non-visible characters # all characters except \001 and \002 (following a \001) are copied to # the returned string; all characters except those between \001 and # \002 are assumed to be `visible'. */ fmt = u"\001\033[%sm\002%s\001\033[0m\002" return u"\n".join([fmt % (color_code, t) for t in text.split(u'\n')]) else: return text def colorize(lead, num, color): """ Print 'lead' = 'num' in 'color' """ s = u"%s=%-4s" % (lead, str(num)) if num != 0 and ANSIBLE_COLOR and color is not None: s = stringc(s, color) return s def hostcolor(host, stats, color=True): if ANSIBLE_COLOR and color: if stats['failures'] != 0 or stats['unreachable'] != 0: return u"%-37s" % stringc(host, C.COLOR_ERROR) elif stats['changed'] != 0: return u"%-37s" % stringc(host, C.COLOR_CHANGED) else: return u"%-37s" % stringc(host, C.COLOR_OK) return u"%-26s" % host