formatter.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from __future__ import absolute_import
  2. from __future__ import unicode_literals
  3. import logging
  4. import shutil
  5. import six
  6. import texttable
  7. from compose.cli import colors
  8. if hasattr(shutil, "get_terminal_size"):
  9. from shutil import get_terminal_size
  10. else:
  11. from backports.shutil_get_terminal_size import get_terminal_size
  12. def get_tty_width():
  13. try:
  14. # get_terminal_size can't determine the size if compose is piped
  15. # to another command. But in such case it doesn't make sense to
  16. # try format the output by terminal size as this output is consumed
  17. # by another command. So let's pretend we have a huge terminal so
  18. # output is single-lined
  19. width, _ = get_terminal_size(fallback=(999, 0))
  20. return int(width)
  21. except OSError:
  22. return 0
  23. class Formatter:
  24. """Format tabular data for printing."""
  25. @staticmethod
  26. def table(headers, rows):
  27. table = texttable.Texttable(max_width=get_tty_width())
  28. table.set_cols_dtype(['t' for h in headers])
  29. table.add_rows([headers] + rows)
  30. table.set_deco(table.HEADER)
  31. table.set_chars(['-', '|', '+', '-'])
  32. return table.draw()
  33. class ConsoleWarningFormatter(logging.Formatter):
  34. """A logging.Formatter which prints WARNING and ERROR messages with
  35. a prefix of the log level colored appropriate for the log level.
  36. """
  37. def get_level_message(self, record):
  38. separator = ': '
  39. if record.levelno == logging.WARNING:
  40. return colors.yellow(record.levelname) + separator
  41. if record.levelno == logging.ERROR:
  42. return colors.red(record.levelname) + separator
  43. return ''
  44. def format(self, record):
  45. if isinstance(record.msg, six.binary_type):
  46. record.msg = record.msg.decode('utf-8')
  47. message = super(ConsoleWarningFormatter, self).format(record)
  48. return '{0}{1}'.format(self.get_level_message(record), message)