diff -r 8d941af65caf -r 77b6da96e6f1 web/lib/django/utils/termcolors.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/django/utils/termcolors.py Wed Jun 02 18:57:35 2010 +0200 @@ -0,0 +1,198 @@ +""" +termcolors.py +""" + +color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white') +foreground = dict([(color_names[x], '3%s' % x) for x in range(8)]) +background = dict([(color_names[x], '4%s' % x) for x in range(8)]) + +RESET = '0' +opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'} + +def colorize(text='', opts=(), **kwargs): + """ + Returns your text, enclosed in ANSI graphics codes. + + Depends on the keyword arguments 'fg' and 'bg', and the contents of + the opts tuple/list. + + Returns the RESET code if no parameters are given. + + Valid colors: + 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white' + + Valid options: + 'bold' + 'underscore' + 'blink' + 'reverse' + 'conceal' + 'noreset' - string will not be auto-terminated with the RESET code + + Examples: + colorize('hello', fg='red', bg='blue', opts=('blink',)) + colorize() + colorize('goodbye', opts=('underscore',)) + print colorize('first line', fg='red', opts=('noreset',)) + print 'this should be red too' + print colorize('and so should this') + print 'this should not be red' + """ + code_list = [] + if text == '' and len(opts) == 1 and opts[0] == 'reset': + return '\x1b[%sm' % RESET + for k, v in kwargs.iteritems(): + if k == 'fg': + code_list.append(foreground[v]) + elif k == 'bg': + code_list.append(background[v]) + for o in opts: + if o in opt_dict: + code_list.append(opt_dict[o]) + if 'noreset' not in opts: + text = text + '\x1b[%sm' % RESET + return ('\x1b[%sm' % ';'.join(code_list)) + text + +def make_style(opts=(), **kwargs): + """ + Returns a function with default parameters for colorize() + + Example: + bold_red = make_style(opts=('bold',), fg='red') + print bold_red('hello') + KEYWORD = make_style(fg='yellow') + COMMENT = make_style(fg='blue', opts=('bold',)) + """ + return lambda text: colorize(text, opts, **kwargs) + +NOCOLOR_PALETTE = 'nocolor' +DARK_PALETTE = 'dark' +LIGHT_PALETTE = 'light' + +PALETTES = { + NOCOLOR_PALETTE: { + 'ERROR': {}, + 'NOTICE': {}, + 'SQL_FIELD': {}, + 'SQL_COLTYPE': {}, + 'SQL_KEYWORD': {}, + 'SQL_TABLE': {}, + 'HTTP_INFO': {}, + 'HTTP_SUCCESS': {}, + 'HTTP_REDIRECT': {}, + 'HTTP_NOT_MODIFIED': {}, + 'HTTP_BAD_REQUEST': {}, + 'HTTP_NOT_FOUND': {}, + 'HTTP_SERVER_ERROR': {}, + }, + DARK_PALETTE: { + 'ERROR': { 'fg': 'red', 'opts': ('bold',) }, + 'NOTICE': { 'fg': 'red' }, + 'SQL_FIELD': { 'fg': 'green', 'opts': ('bold',) }, + 'SQL_COLTYPE': { 'fg': 'green' }, + 'SQL_KEYWORD': { 'fg': 'yellow' }, + 'SQL_TABLE': { 'opts': ('bold',) }, + 'HTTP_INFO': { 'opts': ('bold',) }, + 'HTTP_SUCCESS': { }, + 'HTTP_REDIRECT': { 'fg': 'green' }, + 'HTTP_NOT_MODIFIED': { 'fg': 'cyan' }, + 'HTTP_BAD_REQUEST': { 'fg': 'red', 'opts': ('bold',) }, + 'HTTP_NOT_FOUND': { 'fg': 'yellow' }, + 'HTTP_SERVER_ERROR': { 'fg': 'magenta', 'opts': ('bold',) }, + }, + LIGHT_PALETTE: { + 'ERROR': { 'fg': 'red', 'opts': ('bold',) }, + 'NOTICE': { 'fg': 'red' }, + 'SQL_FIELD': { 'fg': 'green', 'opts': ('bold',) }, + 'SQL_COLTYPE': { 'fg': 'green' }, + 'SQL_KEYWORD': { 'fg': 'blue' }, + 'SQL_TABLE': { 'opts': ('bold',) }, + 'HTTP_INFO': { 'opts': ('bold',) }, + 'HTTP_SUCCESS': { }, + 'HTTP_REDIRECT': { 'fg': 'green', 'opts': ('bold',) }, + 'HTTP_NOT_MODIFIED': { 'fg': 'green' }, + 'HTTP_BAD_REQUEST': { 'fg': 'red', 'opts': ('bold',) }, + 'HTTP_NOT_FOUND': { 'fg': 'red' }, + 'HTTP_SERVER_ERROR': { 'fg': 'magenta', 'opts': ('bold',) }, + } +} +DEFAULT_PALETTE = DARK_PALETTE + +def parse_color_setting(config_string): + """Parse a DJANGO_COLORS environment variable to produce the system palette + + The general form of a pallete definition is: + + "palette;role=fg;role=fg/bg;role=fg,option,option;role=fg/bg,option,option" + + where: + palette is a named palette; one of 'light', 'dark', or 'nocolor'. + role is a named style used by Django + fg is a background color. + bg is a background color. + option is a display options. + + Specifying a named palette is the same as manually specifying the individual + definitions for each role. Any individual definitions following the pallete + definition will augment the base palette definition. + + Valid roles: + 'error', 'notice', 'sql_field', 'sql_coltype', 'sql_keyword', 'sql_table', + 'http_info', 'http_success', 'http_redirect', 'http_bad_request', + 'http_not_found', 'http_server_error' + + Valid colors: + 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white' + + Valid options: + 'bold', 'underscore', 'blink', 'reverse', 'conceal' + + """ + if not config_string: + return PALETTES[DEFAULT_PALETTE] + + # Split the color configuration into parts + parts = config_string.lower().split(';') + palette = PALETTES[NOCOLOR_PALETTE].copy() + for part in parts: + if part in PALETTES: + # A default palette has been specified + palette.update(PALETTES[part]) + elif '=' in part: + # Process a palette defining string + definition = {} + + # Break the definition into the role, + # plus the list of specific instructions. + # The role must be in upper case + role, instructions = part.split('=') + role = role.upper() + + styles = instructions.split(',') + styles.reverse() + + # The first instruction can contain a slash + # to break apart fg/bg. + colors = styles.pop().split('/') + colors.reverse() + fg = colors.pop() + if fg in color_names: + definition['fg'] = fg + if colors and colors[-1] in color_names: + definition['bg'] = colors[-1] + + # All remaining instructions are options + opts = tuple(s for s in styles if s in opt_dict.keys()) + if opts: + definition['opts'] = opts + + # The nocolor palette has all available roles. + # Use that palette as the basis for determining + # if the role is valid. + if role in PALETTES[NOCOLOR_PALETTE] and definition: + palette[role] = definition + + # If there are no colors specified, return the empty palette. + if palette == PALETTES[NOCOLOR_PALETTE]: + return None + return palette