Revision: | 1.2 |
Committed: | Wed Jan 17 18:17:59 2007 UTC (18 years, 3 months ago) by slacapra |
Content type: | text/x-python |
Branch: | MAIN |
CVS Tags: | CRAB_2_9_1, CRAB_2_9_1_pre2, CRAB_2_9_1_pre1, CRAB_2_9_0, CRAB_2_9_0_pre2, CRAB_2_9_0_pre1, CRAB_2_8_8, CRAB_2_8_8_pre1, CRAB_2_8_7_patch3, CRAB_2_8_7_patch2, CRAB_2_8_7_patch1, CRAB_2_8_7, CRAB_2_8_7_pre2, CRAB_2_8_7_pre1, CRAB_2_8_6, CRAB_2_8_6_pre1, CRAB_2_8_5_patch3, CRAB_2_8_5_patch2, CRAB_2_8_5_patch1, CRAB_2_8_5, CRAB_2_8_5_pre5, CRAB_2_8_5_pre4, CRAB_2_8_5_pre3, CRAB_2_8_4_patch3, CRAB_2_8_5_pre2, CRAB_2_8_4_patch2, CRAB_2_8_5_pre1, CRAB_2_8_4_patch1, CRAB_2_8_4, CRAB_2_8_4_pre5, CRAB_2_8_4_pre4, CRAB_2_8_4_pre3, CRAB_2_8_4_pre2, CRAB_2_8_4_pre1, CRAB_2_8_3, CRAB_2_8_3_pre4, CRAB_2_8_3_pre3, CRAB_2_8_3_pre2, CRAB_2_8_3_pre1, CRAB_2_8_2_patch1, CRAB_2_8_2, CRAB_2_8_2_pre5, CRAB_2_8_2_pre4, CRAB_2_8_2_pre3, CRAB_2_8_2_pre2, CRAB_2_8_2_pre1, CRAB_2_8_1, CRAB_2_8_0, CRAB_2_8_0_pre1, CRAB_2_7_10_pre3, CRAB_2_7_9_patch2_pre1, CRAB_2_7_10_pre2, CRAB_2_7_10_pre1, CRAB_2_7_9_patch1, CRAB_2_7_9, CRAB_2_7_9_pre5, CRAB_2_7_9_pre4, CRAB_2_7_9_pre3, CRAB_2_7_9_pre2, CRAB_2_7_8_patch2, CRAB_2_7_9_pre1, CRAB_2_7_8_patch2_pre1, CRAB_2_7_8_patch1, CRAB_2_7_8_patch1_pre1, CRAB_2_7_8, CRAB_2_7_8_pre3, CRAB_2_7_8_pre2, CRAB_2_7_8_dash3, CRAB_2_7_8_dash2, CRAB_2_7_8_dash, CRAB_2_7_7_patch1, CRAB_2_7_7_patch1_pre1, CRAB_2_7_8_pre1, CRAB_2_7_7, CRAB_2_7_7_pre2, CRAB_2_7_7_pre1, CRAB_2_7_6_patch1, CRAB_2_7_6, CRAB_2_7_6_pre1, CRAB_2_7_5_patch1, CRAB_2_7_5, CRAB_2_7_5_pre3, CRAB_2_7_5_pre2, CRAB_2_7_5_pre1, CRAB_2_7_4_patch1, CRAB_2_7_4, CRAB_2_7_4_pre6, CRAB_2_7_4_pre5, CRAB_2_7_4_pre4, CRAB_2_7_4_pre3, CRAB_2_7_4_pre2, CRAB_2_7_4_pre1, CRAB_2_7_3, CRAB_2_7_3_pre3, CRAB_2_7_3_pre3_beta, CRAB_2_7_3_pre2, CRAB_2_7_3_pre2_beta, CRAB_2_7_3_pre1, CRAB_2_7_3_beta3, CRAB_2_7_3_beta2, CRAB_2_7_3_beta1, CRAB_2_7_3_beta, CRAB_2_7_2_p1, CRAB_2_7_1_branch_firstMERGE, CRAB_2_7_2, CRAB_2_7_2_pre4, CRAB_2_7_2_pre3, CRAB_2_7_2_pre2, CRAB_2_7_2_pre1, CRAB_2_7_1, fede_170310, CRAB_2_7_1_pre12, CRAB_2_7_1_pre11, CRAB_2_7_1_pre10, CRAB_2_7_1_pre9, CRAB_LumiMask, CRAB_2_7_lumi, from_LimiMask, CRAB_2_7_1_pre8, CRAB_2_7_1_pre6, CRAB_2_7_1_pre5, CRAB_2_7_1_wmbs_pre4, CRAB_2_7_1_pre4, CRAB_2_7_1_pre3, CRAB_2_6_6_pre6, CRAB_2_7_1_pre2, CRAB_2_6_6_pre5, CRAB_2_7_1_pre1, CRAB_2_6_6_pre4, CRAB_2_6_6_pre3, CRAB_2_6_6_pre2, CRAB_2_6_6_check, CRAB_2_6_6, CRAB_2_6_6_pre1, CRAB_2_7_0, CRAB_2_6_5, CRAB_2_7_0_pre8, CRAB_2_6_5_pre1, CRAB_2_7_0_pre7, CRAB_2_6_4, CRAB_2_7_0_pre6, CRAB_2_6_4_pre1, CRAB_2_7_0_pre5, CRAB_2_6_3_patch_2, CRAB_2_6_3_patch_2_pre2, CRAB_2_6_3_patch_2_pre1, CRAB_2_6_3_patch_1, CRAB_2_7_0_pre4, CRAB_2_7_0_pre3, CRAB_2_6_3, CRAB_2_6_3_pre5, CRAB_2_6_3_pre4, CRAB_2_6_3_pre3, CRAB_2_6_3_pre2, CRAB_2_7_0_pre2, CRAB_2_6_3_pre1, test_1, CRAB_2_7_0_pre1, CRAB_2_6_2, CRAB_2_6_2_pre2, CRAB_2_6_2_pre1, CRAB_2_6_1_pre4, CRAB_2_6_1_pre3, CRAB_2_6_1_pre2, CRAB_2_6_1_pre1, CRAB_2_6_1, CRAB_2_6_0, CRAB_2_6_0_pre14, CRAB_2_6_0_pre13, CRAB_2_6_0_pre12, CRAB_2_6_0_pre11, CRAB_2_6_0_pre10, CRAB_2_6_0_pre9, CRAB_2_6_0_pre8, CRAB_2_6_0_pre7, CRAB_2_6_0_pre6, CRAB_2_6_0_pre5, CRAB_2_6_0_pre4, CRAB_2_6_0_pre3, CRAB_2_6_0_pre2, CRAB_2_6_0_pre1, CRAB_2_5_1, CRAB_2_5_1_pre4, CRAB_2_5_1_pre3, CRAB_2_5_1_pre2, CRAB_2_5_1_pre1, CRAB_2_5_0, CRAB_2_5_0_pre7, CRAB_2_5_0_pre6, CRAB_2_5_0_pre5, CRAB_2_5_0_pre4, CRAB_2_5_0_pre3, CRAB_2_5_0_pre2, CRAB_2_5_0_pre1, CRAB_2_4_4, CRAB_2_4_4_pre6, CRAB_2_4_4_pre5, CRAB_2_4_4_pre4, CRAB_2_4_4_pre3, CRAB_2_4_4_pre2, CRAB_2_4_4_pre1, CRAB_2_4_3, CRAB_2_4_3_pre8, CRAB_2_4_3_pre7, CRAB_2_4_3_pre6, CRAB_2_4_3_pre5, CRAB_2_4_3_pre3, CRAB_2_4_3_pre2, CRAB_2_4_3_pre1, CRAB_2_4_2, CRAB_2_4_2_pre3, CRAB_2_4_2_pre2, CRAB_2_4_2_pre1, CRAB_2_4_1, CRAB_2_4_1_pre4, CRAB_2_4_1_pre3, CRAB_2_4_1_pre2, CRAB_2_4_1_pre1, CRAB_2_4_0_Tutorial, CRAB_2_4_0_Tutorial_pre1, CRAB_2_4_0, CRAB_2_4_0_pre9, CRAB_2_4_0_pre8, CRAB_2_4_0_pre7, CRAB_2_4_0_pre6, CRAB_2_4_0_pre5, CRAB_2_4_0_pre4, CRAB_2_4_0_pre3, CRAB_2_4_0_pre2, CRAB_2_4_0_pre1, CRAB_DLS_PHED1, CRAB_DLS_PHED, CRAB_2_3_2_Fnal, CRAB_2_3_2, CRAB_2_3_2_pre7, CRAB_2_3_2_pre5, CRAB_2_3_2_pre4, CRAB_2_3_2_pre3, CRAB_2_3_2_pre2, CRAB_2_3_2_pre1, CRAB_2_4_0_test, CRAB_2_3_1, CRAB_2_3_1_pre6, CRAB_2_3_1_pre5, CRAB_2_3_1_pre4, CRAB_2_3_1_pre3, CRAB_2_3_1_pre2, CRAB_2_3_1_pre1, CRAB_2_3_0, CRAB_2_3_0_pre6, CRAB_2_3_0_pre1, CRAB_2_2_2_pre5, CRAB_2_2_2_pre4, CRAB_2_2_2_pre3, CRAB_2_2_2_pre2, CRAB_2_2_2_pre1, CRAB_2_2_1, CRAB_2_2_1_pre6, CRAB_2_2_1_pre5, CRAB_2_2_1_pre4, PRODCOMMON_0_10_7_testCS2, CRAB_2_2_1_pre3, CRAB_2_2_1_pre2, CRAB_2_2_1_pre1, CRAB_2_2_0, CRAB_2_2_0_pre21, CRAB_2_2_0_pre19, CRAB_2_2_0_pre18, CRAB_2_2_0_pre17, CRAB_2_2_0_pre16, CRAB_2_2_0_pre15, CRAB_2_2_0_pre13, CRAB_2_2_0_pre12, CRAB_2_2_0_pre11, CRAB_2_2_0_pre10, bp_osg_bdii, CRAB_2_2_0_pre9, CRAB_2_2_0_pre8, CRAB_2_2_0_pre7, CRAB_2_1_2, CRAB_2_2_0_pre5, CRAB_2_1_2_pre2, CRAB_2_1_2_pre1, CRAB_2_2_0_pre4, CRAB_2_2_0_pre2, CRAB_2_1_1, CRAB_2_1_1_pre3, CRAB_2_2_0_pre1, CRAB_2_1_1_pre1, CRAB_2_1_0, CRAB_2_1_0_pre6, CRAB_2_1_0_pre5, CRAB_2_1_0_pre4, CRAB_2_1_0_pre3, CRAB_2_1_0_pre2, CRAB_2_1_0_pre1, CRAB_2_0_4, CRAB_2_0_4_pre2, CRAB_2_0_4_pre1, CRAB_2_0_3, CRAB_2_0_3_pre1, CRAB_2_0_2, CRAB_2_0_2_pre6, CRAB_2_0_2_pre5, CRAB_2_0_2_pre4, CRAB_2_0_2_pre3, CRAB_1_5_4_SLC3, CRAB_1_5_4_SLC3_pre4, CRAB_2_0_2_pre2, CRAB_2_0_2_pre1, CRAB_1_5_4_SLC3_pre3, CRAB_2_0_1, CRAB_1_5_4_SLC3_pre2, CRAB_2_0_1_pre1, CRAB_1_5_4_SLC3_pre1, CRAB_2_0_0, CRAB_2_0_0_pre10, CRAB_2_0_0_pre9, CRAB_1_5_4, CRAB_1_5_4_pre2, CRAB_1_5_4_pre1, CRAB_2_0_0_pre7, CRAB_2_0_0_pre6, CRAB_1_5_3, CRAB_1_5_3_pre5, CRAB_1_5_3_pre4, CRAB_2_0_0_pre5, CRAB_1_5_3_pre3, configure, CRAB_2_0_0_pre4, CRAB_1_5_3_pre2, CRAB_1_5_3_pre1, CRAB_2_0_0_pre3, CRAB_1_5_2, CRAB_2_0_0_pre2, CRAB_2_0_0_pre1, CRAB_1_5_1, CRAB_1_5_1_pre4, CRAB_1_5_1_pre3, CRAB_1_5_1_pre2, CRAB_1_5_1_pre1, CRAB_1_5_0, CRAB_1_5_0_pre9, CRAB_1_5_0_pre8, CRAB_1_5_0_pre7, CRAB_1_5_0_pre6, CRAB_1_5_0_pre5, CRAB_1_5_0_pre4, HEAD |
Branch point for: | CRAB_multiout, CRAB_2_7_1_branch, Lumi2_8, CRAB_2_6_X_br, AnaDataSet, CRAB_2_3_0_br, osg_bdii, CRAB_2_1_2_br, CRAB_2_1_1_pre2, CRAB_1_5_4_SLC3_pre4_br, CRAB_1_5_4_SLC3_start |
Changes since 1.1: | +1 -1 lines |
Log Message: | many minor fixes reported by pychecker, mostly unsude import and unused variables |
# | User | Rev | Content |
---|---|---|---|
1 | slacapra | 1.1 | #!/usr/bin/env python |
2 | |||
3 | slacapra | 1.2 | import sys, re |
4 | slacapra | 1.1 | |
5 | class TerminalController: | ||
6 | """ | ||
7 | A class that can be used to portably generate formatted output to | ||
8 | a terminal. | ||
9 | |||
10 | `TerminalController` defines a set of instance variables whose | ||
11 | values are initialized to the control sequence necessary to | ||
12 | perform a given action. These can be simply included in normal | ||
13 | output to the terminal: | ||
14 | |||
15 | >>> term = TerminalController() | ||
16 | >>> print 'This is '+term.GREEN+'green'+term.NORMAL | ||
17 | |||
18 | Alternatively, the `render()` method can used, which replaces | ||
19 | '${action}' with the string required to perform 'action': | ||
20 | |||
21 | >>> term = TerminalController() | ||
22 | >>> print term.render('This is ${GREEN}green${NORMAL}') | ||
23 | |||
24 | If the terminal doesn't support a given action, then the value of | ||
25 | the corresponding instance variable will be set to ''. As a | ||
26 | result, the above code will still work on terminals that do not | ||
27 | support color, except that their output will not be colored. | ||
28 | Also, this means that you can test whether the terminal supports a | ||
29 | given action by simply testing the truth value of the | ||
30 | corresponding instance variable: | ||
31 | |||
32 | >>> term = TerminalController() | ||
33 | >>> if term.CLEAR_SCREEN: | ||
34 | ... print 'This terminal supports clearning the screen.' | ||
35 | |||
36 | Finally, if the width and height of the terminal are known, then | ||
37 | they will be stored in the `COLS` and `LINES` attributes. | ||
38 | """ | ||
39 | # Cursor movement: | ||
40 | BOL = '' #: Move the cursor to the beginning of the line | ||
41 | UP = '' #: Move the cursor up one line | ||
42 | DOWN = '' #: Move the cursor down one line | ||
43 | LEFT = '' #: Move the cursor left one char | ||
44 | RIGHT = '' #: Move the cursor right one char | ||
45 | |||
46 | # Deletion: | ||
47 | CLEAR_SCREEN = '' #: Clear the screen and move to home position | ||
48 | CLEAR_EOL = '' #: Clear to the end of the line. | ||
49 | CLEAR_BOL = '' #: Clear to the beginning of the line. | ||
50 | CLEAR_EOS = '' #: Clear to the end of the screen | ||
51 | |||
52 | # Output modes: | ||
53 | BOLD = '' #: Turn on bold mode | ||
54 | BLINK = '' #: Turn on blink mode | ||
55 | DIM = '' #: Turn on half-bright mode | ||
56 | REVERSE = '' #: Turn on reverse-video mode | ||
57 | NORMAL = '' #: Turn off all modes | ||
58 | |||
59 | # Cursor display: | ||
60 | HIDE_CURSOR = '' #: Make the cursor invisible | ||
61 | SHOW_CURSOR = '' #: Make the cursor visible | ||
62 | |||
63 | # Terminal size: | ||
64 | COLS = None #: Width of the terminal (None for unknown) | ||
65 | LINES = None #: Height of the terminal (None for unknown) | ||
66 | |||
67 | # Foreground colors: | ||
68 | BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' | ||
69 | |||
70 | # Background colors: | ||
71 | BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = '' | ||
72 | BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = '' | ||
73 | |||
74 | _STRING_CAPABILITIES = """ | ||
75 | BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 | ||
76 | CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold | ||
77 | BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0 | ||
78 | HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split() | ||
79 | _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split() | ||
80 | _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() | ||
81 | |||
82 | def __init__(self, term_stream=sys.stdout): | ||
83 | """ | ||
84 | Create a `TerminalController` and initialize its attributes | ||
85 | with appropriate values for the current terminal. | ||
86 | `term_stream` is the stream that will be used for terminal | ||
87 | output; if this stream is not a tty, then the terminal is | ||
88 | assumed to be a dumb terminal (i.e., have no capabilities). | ||
89 | """ | ||
90 | # Curses isn't available on all platforms | ||
91 | try: import curses | ||
92 | except: return | ||
93 | |||
94 | # If the stream isn't a tty, then assume it has no capabilities. | ||
95 | if not term_stream.isatty(): return | ||
96 | |||
97 | # Check the terminal type. If we fail, then assume that the | ||
98 | # terminal has no capabilities. | ||
99 | try: curses.setupterm() | ||
100 | except: return | ||
101 | |||
102 | # Look up numeric capabilities. | ||
103 | self.COLS = curses.tigetnum('cols') | ||
104 | self.LINES = curses.tigetnum('lines') | ||
105 | |||
106 | # Look up string capabilities. | ||
107 | for capability in self._STRING_CAPABILITIES: | ||
108 | (attrib, cap_name) = capability.split('=') | ||
109 | setattr(self, attrib, self._tigetstr(cap_name) or '') | ||
110 | |||
111 | # Colors | ||
112 | set_fg = self._tigetstr('setf') | ||
113 | if set_fg: | ||
114 | for i,color in zip(range(len(self._COLORS)), self._COLORS): | ||
115 | setattr(self, color, curses.tparm(set_fg, i) or '') | ||
116 | set_fg_ansi = self._tigetstr('setaf') | ||
117 | if set_fg_ansi: | ||
118 | for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): | ||
119 | setattr(self, color, curses.tparm(set_fg_ansi, i) or '') | ||
120 | set_bg = self._tigetstr('setb') | ||
121 | if set_bg: | ||
122 | for i,color in zip(range(len(self._COLORS)), self._COLORS): | ||
123 | setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '') | ||
124 | set_bg_ansi = self._tigetstr('setab') | ||
125 | if set_bg_ansi: | ||
126 | for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): | ||
127 | setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '') | ||
128 | |||
129 | def _tigetstr(self, cap_name): | ||
130 | # String capabilities can include "delays" of the form "$<2>". | ||
131 | # For any modern terminal, we should be able to just ignore | ||
132 | # these, so strip them out. | ||
133 | import curses | ||
134 | cap = curses.tigetstr(cap_name) or '' | ||
135 | return re.sub(r'\$<\d+>[/*]?', '', cap) | ||
136 | |||
137 | def render(self, template): | ||
138 | """ | ||
139 | Replace each $-substitutions in the given template string with | ||
140 | the corresponding terminal control string (if it's defined) or | ||
141 | '' (if it's not). | ||
142 | """ | ||
143 | return re.sub(r'\$\$|\${\w+}', self._render_sub, template) | ||
144 | |||
145 | def _render_sub(self, match): | ||
146 | s = match.group() | ||
147 | if s == '$$': return s | ||
148 | else: return getattr(self, s[2:-1]) | ||
149 | |||
150 | |||
151 | if __name__ == '__main__': | ||
152 | term = TerminalController() | ||
153 | print 'This is '+term.GREEN+term.BG_WHITE+'green'+term.NORMAL |