1# -*- coding: utf-8 -*-
2
3"""
4clint.colored
5~~~~~~~~~~~~~
6
7This module provides a simple and elegant wrapper for colorama.
8
9"""
10
11
12from __future__ import absolute_import
13
14import os
15import re
16import sys
17
18PY3 = sys.version_info[0] >= 3
19
20from ..packages import colorama
21
22__all__ = (
23    'red', 'green', 'yellow', 'blue',
24    'black', 'magenta', 'cyan', 'white',
25    'clean', 'disable'
26)
27
28COLORS = __all__[:-2]
29
30if 'get_ipython' in dir():
31    """
32       when ipython is fired lot of variables like _oh, etc are used.
33       There are so many ways to find current python interpreter is ipython.
34       get_ipython is easiest is most appealing for readers to understand.
35    """
36    DISABLE_COLOR = True
37else:
38    DISABLE_COLOR = False
39
40
41class ColoredString(object):
42    """Enhanced string for __len__ operations on Colored output."""
43    def __init__(self, color, s, always_color=False, bold=False):
44        super(ColoredString, self).__init__()
45        self.s = s
46        self.color = color
47        self.always_color = always_color
48        self.bold = bold
49        if os.environ.get('CLINT_FORCE_COLOR'):
50            self.always_color = True
51
52    def __getattr__(self, att):
53        def func_help(*args, **kwargs):
54            result = getattr(self.s, att)(*args, **kwargs)
55            try:
56                is_result_string = isinstance(result, basestring)
57            except NameError:
58                is_result_string = isinstance(result, str)
59            if is_result_string:
60                return self._new(result)
61            elif isinstance(result, list):
62                return [self._new(x) for x in result]
63            else:
64                return result
65        return func_help
66
67    @property
68    def color_str(self):
69        style = 'BRIGHT' if self.bold else 'NORMAL'
70        c = '%s%s%s%s%s' % (getattr(colorama.Fore, self.color), getattr(colorama.Style, style), self.s, colorama.Fore.RESET, getattr(colorama.Style, 'NORMAL'))
71
72        if self.always_color:
73            return c
74        elif sys.stdout.isatty() and not DISABLE_COLOR:
75            return c
76        else:
77            return self.s
78
79
80    def __len__(self):
81        return len(self.s)
82
83    def __repr__(self):
84        return "<%s-string: '%s'>" % (self.color, self.s)
85
86    def __unicode__(self):
87        value = self.color_str
88        if isinstance(value, bytes):
89            return value.decode('utf8')
90        return value
91
92    if PY3:
93        __str__ = __unicode__
94    else:
95        def __str__(self):
96            value = self.color_str
97            if isinstance(value, bytes):
98                return value
99            return value.encode('utf8')
100
101    def __iter__(self):
102        return iter(self.color_str)
103
104    def __add__(self, other):
105        return str(self.color_str) + str(other)
106
107    def __radd__(self, other):
108        return str(other) + str(self.color_str)
109
110    def __mul__(self, other):
111        return (self.color_str * other)
112
113    def _new(self, s):
114        return ColoredString(self.color, s)
115
116
117def clean(s):
118    strip = re.compile("([^-_a-zA-Z0-9!@#%&=,/'\";:~`\$\^\*\(\)\+\[\]\.\{\}\|\?\<\>\\]+|[^\s]+)")
119    txt = strip.sub('', str(s))
120
121    strip = re.compile(r'\[\d+m')
122    txt = strip.sub('', txt)
123
124    return txt
125
126
127def black(string, always=False, bold=False):
128    return ColoredString('BLACK', string, always_color=always, bold=bold)
129
130def red(string, always=False, bold=False):
131    return ColoredString('RED', string, always_color=always, bold=bold)
132
133def green(string, always=False, bold=False):
134    return ColoredString('GREEN', string, always_color=always, bold=bold)
135
136def yellow(string, always=False, bold=False):
137    return ColoredString('YELLOW', string, always_color=always, bold=bold)
138
139def blue(string, always=False, bold=False):
140    return ColoredString('BLUE', string, always_color=always, bold=bold)
141
142def magenta(string, always=False, bold=False):
143    return ColoredString('MAGENTA', string, always_color=always, bold=bold)
144
145def cyan(string, always=False, bold=False):
146    return ColoredString('CYAN', string, always_color=always, bold=bold)
147
148def white(string, always=False, bold=False):
149    return ColoredString('WHITE', string, always_color=always, bold=bold)
150
151def disable():
152    """Disables colors."""
153    global DISABLE_COLOR
154
155    DISABLE_COLOR = True
156