| OLD | NEW |
| 1 # Copyright (C) 2010, 2012 Google Inc. All rights reserved. | 1 # Copyright (C) 2010, 2012 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 import logging | 29 import logging |
| 30 import os | 30 import os |
| 31 import sys | 31 import sys |
| 32 import time | 32 import time |
| 33 | 33 |
| 34 LOG_HANDLER_NAME = 'MeteredStreamLogHandler' | 34 LOG_HANDLER_NAME = 'MeteredStreamLogHandler' |
| 35 | 35 |
| 36 | 36 |
| 37 class MeteredStream(object): | 37 class MeteredStream(object): |
| 38 |
| 38 """ | 39 """ |
| 39 This class implements a stream wrapper that has 'meters' as well as | 40 This class implements a stream wrapper that has 'meters' as well as |
| 40 regular output. A 'meter' is a single line of text that can be erased | 41 regular output. A 'meter' is a single line of text that can be erased |
| 41 and rewritten repeatedly, without producing multiple lines of output. It | 42 and rewritten repeatedly, without producing multiple lines of output. It |
| 42 can be used to produce effects like progress bars. | 43 can be used to produce effects like progress bars. |
| 43 """ | 44 """ |
| 44 | 45 |
| 45 @staticmethod | 46 @staticmethod |
| 46 def _erasure(txt): | 47 def _erasure(txt): |
| 47 num_chars = len(txt) | 48 num_chars = len(txt) |
| 48 return '\b' * num_chars + ' ' * num_chars + '\b' * num_chars | 49 return '\b' * num_chars + ' ' * num_chars + '\b' * num_chars |
| 49 | 50 |
| 50 @staticmethod | 51 @staticmethod |
| 51 def _ensure_newline(txt): | 52 def _ensure_newline(txt): |
| 52 return txt if txt.endswith('\n') else txt + '\n' | 53 return txt if txt.endswith('\n') else txt + '\n' |
| 53 | 54 |
| 54 def __init__(self, stream=None, verbose=False, logger=None, time_fn=None, pi
d=None, number_of_columns=None): | 55 def __init__(self, stream=None, verbose=False, logger=None, time_fn=None, pi
d=None, number_of_columns=None): |
| 55 self._stream = stream or sys.stderr | 56 self._stream = stream or sys.stderr |
| 56 self._verbose = verbose | 57 self._verbose = verbose |
| 57 self._time_fn = time_fn or time.time | 58 self._time_fn = time_fn or time.time |
| 58 self._pid = pid or os.getpid() | 59 self._pid = pid or os.getpid() |
| 59 self._isatty = self._stream.isatty() | 60 self._isatty = self._stream.isatty() |
| 60 self._erasing = self._isatty and not verbose | 61 self._erasing = self._isatty and not verbose |
| 61 self._last_partial_line = '' | 62 self._last_partial_line = '' |
| 62 self._last_write_time = 0.0 | 63 self._last_write_time = 0.0 |
| 63 self._throttle_delay_in_secs = 0.066 if self._erasing else 10.0 | 64 self._throttle_delay_in_secs = 0.066 if self._erasing else 10.0 |
| 64 self._number_of_columns = sys.maxint | 65 self._number_of_columns = sys.maxsize |
| 65 if self._isatty and number_of_columns: | 66 if self._isatty and number_of_columns: |
| 66 self._number_of_columns = number_of_columns | 67 self._number_of_columns = number_of_columns |
| 67 | 68 |
| 68 self._logger = logger | 69 self._logger = logger |
| 69 self._log_handler = None | 70 self._log_handler = None |
| 70 if self._logger: | 71 if self._logger: |
| 71 log_level = logging.DEBUG if verbose else logging.INFO | 72 log_level = logging.DEBUG if verbose else logging.INFO |
| 72 self._log_handler = _LogHandler(self) | 73 self._log_handler = _LogHandler(self) |
| 73 self._log_handler.setLevel(log_level) | 74 self._log_handler.setLevel(log_level) |
| 74 self._logger.addHandler(self._log_handler) | 75 self._logger.addHandler(self._log_handler) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 132 |
| 132 class _LogHandler(logging.Handler): | 133 class _LogHandler(logging.Handler): |
| 133 | 134 |
| 134 def __init__(self, meter): | 135 def __init__(self, meter): |
| 135 logging.Handler.__init__(self) | 136 logging.Handler.__init__(self) |
| 136 self._meter = meter | 137 self._meter = meter |
| 137 self.name = LOG_HANDLER_NAME | 138 self.name = LOG_HANDLER_NAME |
| 138 | 139 |
| 139 def emit(self, record): | 140 def emit(self, record): |
| 140 self._meter.writeln(record.getMessage(), record.created, record.process) | 141 self._meter.writeln(record.getMessage(), record.created, record.process) |
| OLD | NEW |