formatter.py 1.8 KB

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