Commit | Line | Data |
---|---|---|
5e888f30 KH |
1 | # -*- coding: utf-8 -*- |
2 | ||
3 | __copyright__ = """ | |
4 | Copyright (C) 2007, Karl Hasselström <kha@treskal.com> | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License version 2 as | |
8 | published by the Free Software Foundation. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software | |
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | """ | |
19 | ||
20 | import sys | |
21 | ||
22 | class MessagePrinter(object): | |
23 | def __init__(self): | |
24 | class Output(object): | |
25 | def __init__(self, write, flush): | |
26 | self.write = write | |
27 | self.flush = flush | |
28 | self.at_start_of_line = True | |
29 | self.level = 0 | |
30 | def new_line(self): | |
31 | """Ensure that we're at the beginning of a line.""" | |
32 | if not self.at_start_of_line: | |
33 | self.write('\n') | |
34 | self.at_start_of_line = True | |
35 | def single_line(self, msg, print_newline = True, | |
36 | need_newline = True): | |
37 | """Write a single line. Newline before and after are | |
38 | separately configurable.""" | |
39 | if need_newline: | |
40 | self.new_line() | |
41 | if self.at_start_of_line: | |
42 | self.write(' '*self.level) | |
43 | self.write(msg) | |
44 | if print_newline: | |
45 | self.write('\n') | |
46 | self.at_start_of_line = True | |
47 | else: | |
48 | self.flush() | |
49 | self.at_start_of_line = False | |
50 | def tagged_lines(self, tag, lines): | |
51 | tag += ': ' | |
52 | for line in lines: | |
53 | self.single_line(tag + line) | |
54 | tag = ' '*len(tag) | |
55 | def write_line(self, line): | |
56 | """Write one line of text on a lines of its own, not | |
57 | indented.""" | |
58 | self.new_line() | |
59 | self.write('%s\n' % line) | |
60 | self.at_start_of_line = True | |
61 | def write_raw(self, string): | |
62 | """Write an arbitrary string, possibly containing | |
63 | newlines.""" | |
64 | self.new_line() | |
65 | self.write(string) | |
66 | self.at_start_of_line = string.endswith('\n') | |
8ea5a4e2 | 67 | self.__stderr = Output(sys.stderr.write, sys.stderr.flush) |
5e888f30 KH |
68 | self.__stdout = Output(sys.stdout.write, sys.stdout.flush) |
69 | if sys.stdout.isatty(): | |
70 | self.__out = self.__stdout | |
8ea5a4e2 | 71 | self.__err = self.__stdout |
5e888f30 KH |
72 | else: |
73 | self.__out = Output(lambda msg: None, lambda: None) | |
8ea5a4e2 | 74 | self.__err = self.__stderr |
5e888f30 KH |
75 | def stdout(self, line): |
76 | """Write a line to stdout.""" | |
77 | self.__stdout.write_line(line) | |
78 | def stdout_raw(self, string): | |
79 | """Write a string possibly containing newlines to stdout.""" | |
80 | self.__stdout.write_raw(string) | |
8ea5a4e2 KH |
81 | def err_raw(self, string): |
82 | """Write a string possibly containing newlines to the error | |
83 | output.""" | |
84 | self.__err.write_raw(string) | |
5e888f30 KH |
85 | def info(self, *msgs): |
86 | for msg in msgs: | |
87 | self.__out.single_line(msg) | |
20d80b85 KH |
88 | def note(self, *msgs, **kw): |
89 | self.__out.tagged_lines(kw.get('title', 'Notice'), msgs) | |
90 | def warn(self, *msgs, **kw): | |
91 | self.__err.tagged_lines(kw.get('title', 'Warning'), msgs) | |
92 | def error(self, *msgs, **kw): | |
93 | self.__err.tagged_lines(kw.get('title', 'Error'), msgs) | |
5e888f30 KH |
94 | def start(self, msg): |
95 | """Start a long-running operation.""" | |
96 | self.__out.single_line('%s ... ' % msg, print_newline = False) | |
97 | self.__out.level += 1 | |
98 | def done(self, extramsg = None): | |
99 | """Finish long-running operation.""" | |
100 | self.__out.level -= 1 | |
101 | if extramsg: | |
102 | msg = 'done (%s)' % extramsg | |
103 | else: | |
104 | msg = 'done' | |
105 | self.__out.single_line(msg, need_newline = False) | |
106 | ||
107 | out = MessagePrinter() |