1# 2# Copyright 2004, 2005, 2010 Zuza Software Foundation 3# 4# This file is part of translate. 5# 6# translate is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# translate is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, see <http://www.gnu.org/licenses/>. 18 19"""Progress bar utilities for reporting feedback on the progress of an 20application. 21""" 22 23 24class DotsProgressBar: 25 """An ultra-simple progress indicator that just writes a dot for each 26 action 27 """ 28 29 def __init__(self): 30 import sys 31 32 self.stderr = sys.stderr 33 self.amount = 0 34 35 def show(self, verbosemessage): 36 """show a dot for progress :-)""" 37 # pylint: disable=W0613 38 self.stderr.write(".") 39 self.stderr.flush() 40 41 def close(self): 42 self.stderr.write("\n") 43 self.stderr.flush() 44 45 def __del__(self): 46 self.close() 47 48 49class NoProgressBar: 50 """An invisible indicator that does nothing.""" 51 52 def __init__(self): 53 self.amount = 0 54 55 def show(self, verbosemessage): 56 """show nothing for progress :-)""" 57 pass 58 59 def close(self): 60 pass 61 62 63class ProgressBar: 64 """A plain progress bar that doesn't know very much about output.""" 65 66 def __init__(self, minValue=0, maxValue=100, totalWidth=50): 67 self.progBar = "[]" # This holds the progress bar string 68 self.min = minValue 69 self.max = maxValue 70 self.span = maxValue - minValue 71 self.width = totalWidth 72 self.amount = 0 # When amount == max, we are 100% done 73 74 def __str__(self): 75 """Produces the string representing the progress bar.""" 76 if self.amount < self.min: 77 self.amount = self.min 78 if self.amount > self.max: 79 self.amount = self.max 80 81 # Figure out the new percent done, round to an integer 82 diffFromMin = float(self.amount - self.min) 83 percentDone = (diffFromMin / float(self.span)) * 100.0 84 percentDone = round(percentDone) 85 percentDone = int(percentDone) 86 87 # Figure out how many hash bars the percentage should be 88 allFull = self.width - 7 89 numHashes = (percentDone / 100.0) * allFull 90 numHashes = int(round(numHashes)) 91 92 # build a progress bar with hashes and spaces 93 self.progBar = "[%s%s] %3d%%" % ( 94 "#" * numHashes, 95 " " * (allFull - numHashes), 96 percentDone, 97 ) 98 return str(self.progBar) 99 100 def show(self, verbosemessage): 101 """displays the progress bar""" 102 # pylint: disable=W0613 103 print(self) 104 105 106class MessageProgressBar(ProgressBar): 107 """A ProgressBar that just writes out the messages without any progress 108 display 109 """ 110 111 def __init__(self, *args, **kwargs): 112 import sys 113 114 self.sys = sys 115 super().__init__(*args, **kwargs) 116 117 def show(self, verbosemessage): 118 self.sys.stderr.write(verbosemessage + "\n") 119 self.sys.stderr.flush() 120 121 122class HashProgressBar(ProgressBar): 123 """A ProgressBar which knows how to go back to the beginning of the line.""" 124 125 def __init__(self, *args, **kwargs): 126 import sys 127 128 self.sys = sys 129 super().__init__(*args, **kwargs) 130 131 def show(self, verbosemessage): 132 self.sys.stderr.write(str(self) + "\r") 133 self.sys.stderr.flush() 134 135 def close(self): 136 self.sys.stderr.write("\n") 137 self.sys.stderr.flush() 138 139 def __del__(self): 140 self.close() 141 142 143class VerboseProgressBar(HashProgressBar): 144 def __init__(self, *args, **kwargs): 145 self.lastwidth = 0 146 super().__init__(*args, **kwargs) 147 148 def show(self, verbosemessage): 149 output = str(self) 150 self.sys.stderr.write("\r" + " " * self.lastwidth) 151 self.sys.stderr.write("\r" + verbosemessage + "\n") 152 self.lastwidth = len(output) 153 self.sys.stderr.write("\r" + output) 154 self.sys.stderr.flush() 155 156 157def test(progressbar): 158 import time 159 160 for n in range(progressbar.min, progressbar.max + 1, 5): 161 progressbar.amount = n 162 progressbar.show("Some message") 163 time.sleep(0.2) 164 165 166if __name__ == "__main__": 167 p = HashProgressBar(0, 100, 50) 168 test(p) 169