term.py 3.9 KB

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