term.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. # -*- coding: utf-8 -*-
  2. """
  3. celery.utils.term
  4. ~~~~~~~~~~~~~~~~~
  5. Terminals and colors.
  6. """
  7. from __future__ import absolute_import, unicode_literals
  8. import platform
  9. from functools import reduce
  10. from kombu.utils.encoding import safe_str
  11. from celery.five import string
  12. __all__ = ['colored']
  13. BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
  14. OP_SEQ = '\033[%dm'
  15. RESET_SEQ = '\033[0m'
  16. COLOR_SEQ = '\033[1;%dm'
  17. IS_WINDOWS = platform.system() == 'Windows'
  18. def fg(s):
  19. return COLOR_SEQ % s
  20. class colored(object):
  21. """Terminal colored text.
  22. Example::
  23. >>> c = colored(enabled=True)
  24. >>> print(str(c.red('the quick '), c.blue('brown ', c.bold('fox ')),
  25. ... c.magenta(c.underline('jumps over')),
  26. ... c.yellow(' the lazy '),
  27. ... c.green('dog ')))
  28. """
  29. def __init__(self, *s, **kwargs):
  30. self.s = s
  31. self.enabled = not IS_WINDOWS and kwargs.get('enabled', True)
  32. self.op = kwargs.get('op', '')
  33. self.names = {'black': self.black,
  34. 'red': self.red,
  35. 'green': self.green,
  36. 'yellow': self.yellow,
  37. 'blue': self.blue,
  38. 'magenta': self.magenta,
  39. 'cyan': self.cyan,
  40. 'white': self.white}
  41. def _add(self, a, b):
  42. return string(a) + string(b)
  43. def _fold_no_color(self, a, b):
  44. try:
  45. A = a.no_color()
  46. except AttributeError:
  47. A = string(a)
  48. try:
  49. B = b.no_color()
  50. except AttributeError:
  51. B = string(b)
  52. return ''.join((string(A), string(B)))
  53. def no_color(self):
  54. if self.s:
  55. return string(reduce(self._fold_no_color, self.s))
  56. return ''
  57. def embed(self):
  58. prefix = ''
  59. if self.enabled:
  60. prefix = self.op
  61. return ''.join((string(prefix), string(reduce(self._add, self.s))))
  62. def __unicode__(self):
  63. suffix = ''
  64. if self.enabled:
  65. suffix = RESET_SEQ
  66. return string(''.join((self.embed(), string(suffix))))
  67. def __str__(self):
  68. return safe_str(self.__unicode__())
  69. def node(self, s, op):
  70. return self.__class__(enabled=self.enabled, op=op, *s)
  71. def black(self, *s):
  72. return self.node(s, fg(30 + BLACK))
  73. def red(self, *s):
  74. return self.node(s, fg(30 + RED))
  75. def green(self, *s):
  76. return self.node(s, fg(30 + GREEN))
  77. def yellow(self, *s):
  78. return self.node(s, fg(30 + YELLOW))
  79. def blue(self, *s):
  80. return self.node(s, fg(30 + BLUE))
  81. def magenta(self, *s):
  82. return self.node(s, fg(30 + MAGENTA))
  83. def cyan(self, *s):
  84. return self.node(s, fg(30 + CYAN))
  85. def white(self, *s):
  86. return self.node(s, fg(30 + WHITE))
  87. def __repr__(self):
  88. return repr(self.no_color())
  89. def bold(self, *s):
  90. return self.node(s, OP_SEQ % 1)
  91. def underline(self, *s):
  92. return self.node(s, OP_SEQ % 4)
  93. def blink(self, *s):
  94. return self.node(s, OP_SEQ % 5)
  95. def reverse(self, *s):
  96. return self.node(s, OP_SEQ % 7)
  97. def bright(self, *s):
  98. return self.node(s, OP_SEQ % 8)
  99. def ired(self, *s):
  100. return self.node(s, fg(40 + RED))
  101. def igreen(self, *s):
  102. return self.node(s, fg(40 + GREEN))
  103. def iyellow(self, *s):
  104. return self.node(s, fg(40 + YELLOW))
  105. def iblue(self, *s):
  106. return self.node(s, fg(40 + BLUE))
  107. def imagenta(self, *s):
  108. return self.node(s, fg(40 + MAGENTA))
  109. def icyan(self, *s):
  110. return self.node(s, fg(40 + CYAN))
  111. def iwhite(self, *s):
  112. return self.node(s, fg(40 + WHITE))
  113. def reset(self, *s):
  114. return self.node(s or [''], RESET_SEQ)
  115. def __add__(self, other):
  116. return string(self) + string(other)