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 | ||
a4b511ff | 20 | import sys, textwrap |
5e888f30 KH |
21 | |
22 | class MessagePrinter(object): | |
cf8be1c8 | 23 | def __init__(self, file = None): |
5e888f30 KH |
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 += ': ' | |
a4b511ff KH |
52 | width = 79 - 2*self.level - len(tag) |
53 | lines = [wl for line in lines | |
54 | for wl in textwrap.wrap(line, width, | |
55 | break_long_words = False)] | |
5e888f30 KH |
56 | for line in lines: |
57 | self.single_line(tag + line) | |
58 | tag = ' '*len(tag) | |
59 | def write_line(self, line): | |
60 | """Write one line of text on a lines of its own, not | |
61 | indented.""" | |
62 | self.new_line() | |
63 | self.write('%s\n' % line) | |
64 | self.at_start_of_line = True | |
65 | def write_raw(self, string): | |
66 | """Write an arbitrary string, possibly containing | |
67 | newlines.""" | |
68 | self.new_line() | |
69 | self.write(string) | |
70 | self.at_start_of_line = string.endswith('\n') | |
cf8be1c8 KH |
71 | if file: |
72 | self.__stdout = self.__stderr = Output(file.write, file.flush) | |
73 | else: | |
74 | self.__stdout = Output(sys.stdout.write, sys.stdout.flush) | |
75 | self.__stderr = Output(sys.stdout.write, sys.stdout.flush) | |
76 | if file or sys.stdout.isatty(): | |
5e888f30 | 77 | self.__out = self.__stdout |
8ea5a4e2 | 78 | self.__err = self.__stdout |
5e888f30 KH |
79 | else: |
80 | self.__out = Output(lambda msg: None, lambda: None) | |
8ea5a4e2 | 81 | self.__err = self.__stderr |
5e888f30 KH |
82 | def stdout(self, line): |
83 | """Write a line to stdout.""" | |
84 | self.__stdout.write_line(line) | |
85 | def stdout_raw(self, string): | |
86 | """Write a string possibly containing newlines to stdout.""" | |
87 | self.__stdout.write_raw(string) | |
8ea5a4e2 KH |
88 | def err_raw(self, string): |
89 | """Write a string possibly containing newlines to the error | |
90 | output.""" | |
91 | self.__err.write_raw(string) | |
5e888f30 KH |
92 | def info(self, *msgs): |
93 | for msg in msgs: | |
94 | self.__out.single_line(msg) | |
20d80b85 KH |
95 | def note(self, *msgs, **kw): |
96 | self.__out.tagged_lines(kw.get('title', 'Notice'), msgs) | |
97 | def warn(self, *msgs, **kw): | |
98 | self.__err.tagged_lines(kw.get('title', 'Warning'), msgs) | |
99 | def error(self, *msgs, **kw): | |
100 | self.__err.tagged_lines(kw.get('title', 'Error'), msgs) | |
5e888f30 KH |
101 | def start(self, msg): |
102 | """Start a long-running operation.""" | |
103 | self.__out.single_line('%s ... ' % msg, print_newline = False) | |
104 | self.__out.level += 1 | |
105 | def done(self, extramsg = None): | |
106 | """Finish long-running operation.""" | |
107 | self.__out.level -= 1 | |
108 | if extramsg: | |
109 | msg = 'done (%s)' % extramsg | |
110 | else: | |
111 | msg = 'done' | |
112 | self.__out.single_line(msg, need_newline = False) | |
113 | ||
114 | out = MessagePrinter() |