147
148
            return NullProgressView()
 
 
150
    def _make_output_stream_explicit(self, encoding, encoding_type):
 
 
151
        if encoding_type == 'exact':
 
 
152
            # force sys.stdout to be binary stream on win32; 
 
 
153
            # NB: this leaves the file set in that mode; may cause problems if
 
 
154
            # one process tries to do binary and then text output
 
 
155
            if sys.platform == 'win32':
 
 
156
                fileno = getattr(self.stdout, 'fileno', None)
 
 
159
                    msvcrt.setmode(fileno(), os.O_BINARY)
 
 
160
            return TextUIOutputStream(self, self.stdout)
 
 
162
            encoded_stdout = codecs.getwriter(encoding)(self.stdout,
 
 
163
                errors=encoding_type)
 
 
164
            # For whatever reason codecs.getwriter() does not advertise its encoding
 
 
165
            # it just returns the encoding of the wrapped file, which is completely
 
 
166
            # bogus. So set the attribute, so we can find the correct encoding later.
 
 
167
            encoded_stdout.encoding = encoding
 
 
168
            return TextUIOutputStream(self, encoded_stdout)
 
149
170
    def note(self, msg):
 
150
171
        """Write an already-formatted message, clearing the progress bar if necessary."""
 
151
172
        self.clear_term()
 
 
235
256
    def _show_line(self, s):
 
236
257
        # sys.stderr.write("progress %r\n" % s)
 
238
 
        self._term_file.write('\r%-*.*s\r' % (n, n, s))
 
 
258
        if self._width is not None:
 
 
260
            s = '%-*.*s' % (n, n, s)
 
 
261
        self._term_file.write('\r' + s + '\r')
 
241
264
        if self._have_output:
 
 
365
388
            self._bytes_since_update = 0
 
366
389
            self._last_transport_msg = msg
 
 
393
class TextUIOutputStream(object):
 
 
394
    """Decorates an output stream so that the terminal is cleared before writing.
 
 
396
    This is supposed to ensure that the progress bar does not conflict with bulk
 
 
399
    # XXX: this does not handle the case of writing part of a line, then doing
 
 
400
    # progress bar output: the progress bar will probably write over it.
 
 
401
    # one option is just to buffer that text until we have a full line;
 
 
402
    # another is to save and restore it
 
 
404
    # XXX: might need to wrap more methods
 
 
406
    def __init__(self, ui_factory, wrapped_stream):
 
 
407
        self.ui_factory = ui_factory
 
 
408
        self.wrapped_stream = wrapped_stream
 
 
409
        # this does no transcoding, but it must expose the underlying encoding
 
 
410
        # because some callers need to know what can be written - see for
 
 
411
        # example unescape_for_display.
 
 
412
        self.encoding = getattr(wrapped_stream, 'encoding', None)
 
 
415
        self.ui_factory.clear_term()
 
 
416
        self.wrapped_stream.flush()
 
 
418
    def write(self, to_write):
 
 
419
        self.ui_factory.clear_term()
 
 
420
        self.wrapped_stream.write(to_write)
 
 
422
    def writelines(self, lines):
 
 
423
        self.ui_factory.clear_term()
 
 
424
        self.wrapped_stream.writelines(lines)