# -*- coding: utf-8 -*- """ $Id$ Copyright 2010 Lars Kruse This file is part of PyCAM. PyCAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PyCAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PyCAM. If not, see . """ __all__ = ["ConsoleProgressBar"] import os class ConsoleProgressBar(object): STYLE_NONE = 0 STYLE_TEXT = 1 STYLE_BAR = 2 STYLE_DOT = 3 PROGRESS_BAR_LENGTH = 70 def __init__(self, output, style=None): if style is None: style = ConsoleProgressBar.STYLE_TEXT self.output = output self.style = style self.last_length = 0 self.text = "" self.percent = 0 def _output_current_state(self, progress_happened=True): if self.style == ConsoleProgressBar.STYLE_TEXT: text = "%d%% %s" % (self.percent, self.text) self.last_length = len(text) elif self.style == ConsoleProgressBar.STYLE_BAR: bar_length = ConsoleProgressBar.PROGRESS_BAR_LENGTH hashes = int(bar_length * self.percent / 100.0) empty = bar_length - hashes text = "[%s%s]" % ("#" * hashes, "." * empty) # include a text like " 10% " in the middle percent_text = " %d%% " % self.percent start_text = text[:(len(text) - len(percent_text)) / 2] end_text = text[-(len(text) - len(start_text) - len(percent_text)):] text = start_text + percent_text + end_text self.last_length = len(text) elif self.style == ConsoleProgressBar.STYLE_DOT: if progress_happened: text = "." else: text = "" # don't remove any previous characters self.last_length = 0 else: raise ValueError("ConsoleProgressBar: invalid style (%d)" \ % self.style) self.output.write(text) self.output.flush() def update(self, text=None, percent=None, **kwargs): if self.style == ConsoleProgressBar.STYLE_NONE: return if not text is None: self.text = text if not percent is None: self.percent = int(percent) if self.last_length > 0: # delete the previous line self.output.write("\x08" * self.last_length) self._output_current_state(progress_happened = (not percent is None)) def finish(self): if self.style == ConsoleProgressBar.STYLE_NONE: return # show that we are finished self.update(percent=100) # finish the line self.output.write(os.linesep)