deluge/deluge/ui/console/colors.py
2009-01-10 00:05:31 +00:00

109 lines
4.5 KiB
Python

#!/usr/bin/env python
#
# colors.py
#
# Copyright (C) 2008-2009 Ido Abramovich <ido.deluge@gmail.com>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
import re, sys
def color(string, fg=None, attrs=[], bg=None, keep_open=False, input=False):
if isinstance(attrs, basestring):
attrs = [attrs]
attrs = map(str.lower, attrs)
ansi_reset = "\x1b[0m"
if input:
ansi_reset = '\001'+ansi_reset+'\002'
if len(attrs) == 1 and 'reset' in attrs:
return ansi_reset
colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']
attributes = ['reset', 'bright', 'dim', None, 'underscore', 'blink', 'reverse', 'hidden']
_fg = 30 + colors.index(fg.lower()) if fg and fg.lower() in colors else None
_bg = 40 + colors.index(bg.lower()) if bg and bg.lower() in colors else None
_attrs = [ str(attributes.index(a)) for a in attrs if a in attributes]
color_vals = map(str, filter(lambda x: x is not None, [_fg, _bg]))
color_vals.extend(_attrs)
reset_cmd = ansi_reset if not keep_open else ''
color_code = '\x1b['+';'.join(color_vals)+'m'
if input:
color_code = '\001'+color_code+'\002'
return color_code+string+reset_cmd
def make_style(*args, **kwargs):
return lambda text: color(text, *args, **kwargs)
default_style = {
'black' : make_style(fg='black'),
'red' : make_style(fg='red'),
'green' : make_style(fg='green'),
'yellow' : make_style(fg='yellow'),
'blue' : make_style(fg='blue'),
'magenta' : make_style(fg='magenta'),
'cyan' : make_style(fg='cyan'),
'white' : make_style(fg='white'),
'bold_black' : make_style(fg='black', attrs='bright'),
'bold_red' : make_style(fg='red', attrs='bright'),
'bold_green' : make_style(fg='green', attrs='bright'),
'bold_yellow' : make_style(fg='yellow', attrs='bright'),
'bold_blue' : make_style(fg='blue', attrs='bright'),
'bold_magenta' : make_style(fg='magenta', attrs='bright'),
'bold_cyan' : make_style(fg='cyan', attrs='bright'),
'bold_white' : make_style(fg='white', attrs='bright'),
}
class Template(str):
regex = re.compile(r'{{\s*(?P<style>.*?)\((?P<arg>.*?)\)\s*}}')
style = default_style
def __new__(self, text):
return str.__new__(self, Template.regex.sub(lambda mo: Template.style[mo.group('style')](mo.group('arg')), text))
def __call__(self, *args, **kwargs):
if kwargs:
return str(self) % kwargs
else:
return str(self) % args
class InputTemplate(Template):
"""This class is similar to Template, but the escapes are wrapped in \001
and \002 so that readline can properly know the length of each line and
can wrap lines accordingly. Use this class for any colored text which
needs to be used in input prompts, such as in calls to raw_input()."""
input_codes = re.compile('(\x1b\[.*?m)')
def __new__(self, text):
regular_string = InputTemplate.regex.sub(lambda mo: InputTemplate.style[mo.group('style')](mo.group('arg')) , text)
return str.__new__(self, InputTemplate.input_codes.sub(r'\001\1\002', regular_string))
class struct(object):
pass
templates = struct()
templates.prompt = InputTemplate('{{bold_white(%s)}}')
templates.ERROR = Template('{{bold_red( * %s)}}')
templates.SUCCESS = Template('{{bold_green( * %s)}}')
templates.help = Template(' * {{bold_blue(%-*s)}} %s')
templates.info_general = Template('{{bold_blue(*** %s:)}} %s')
templates.info_transfers = Template('{{bold_green(*** %s:)}} %s')
templates.info_network = Template('{{bold_white(*** %s:)}} %s')
templates.info_files_header = Template('{{bold_cyan(*** %s:)}}')
templates.info_peers_header = Template('{{bold_magenta(*** %s:)}}')
templates.info_peers = Template('\t * {{bold_blue(%-22s)}} {{bold_green(%-25s)}} {{bold_cyan(Up: %-12s)}} {{bold_magenta(Down: %-12s)}}')
templates.config_display = Template(' * {{bold_blue(%s)}}: %s')