1# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 2# 3# Copyright (C) 2006 Red Hat 4# see file 'COPYING' for use and warranty information 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation; version 2 only 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# 19import locale 20import sys 21 22 23PY3 = sys.version_info[0] == 3 24 25if PY3: 26 bytes_type=bytes 27 string_type=str 28else: 29 bytes_type=str 30 string_type=unicode 31 32 33class ConsoleProgressBar: 34 def __init__(self, out, steps=100, indicator='#'): 35 self.blocks = 0 36 self.current = 0 37 self.steps = steps 38 self.indicator = indicator 39 self.out = out 40 self.done = False 41 42 def start(self, message=None): 43 self.done = False 44 if message: 45 self.out.write('\n%s:\n' % message) 46 self.out.write('%--10---20---30---40---50---60---70---80---90--100\n') 47 48 def step(self, n=1): 49 self.current += n 50 51 old = self.blocks 52 self.blocks = int(round(self.current / float(self.steps) * 100) / 2) 53 54 if self.blocks > 50: 55 self.blocks = 50 56 57 new = self.blocks - old 58 59 self.out.write(self.indicator * new) 60 self.out.flush() 61 62 if self.blocks == 50 and not self.done: 63 self.done = True 64 self.out.write("\n") 65 66def set_to_list(s): 67 l = [] 68 l.extend(s) 69 return l 70 71def first(s, sorted=False): 72 """ 73 Return the first element of a set. 74 75 It sometimes useful to return the first element from a set but, 76 because sets are not indexable, this is rather hard. This function 77 will return the first element from a set. If sorted is True, then 78 the set will first be sorted (making this an expensive operation). 79 Otherwise a random element will be returned (as sets are not ordered). 80 """ 81 if not len(s): 82 raise IndexError("empty containter") 83 84 if sorted: 85 l = set_to_list(s) 86 l.sort() 87 return l[0] 88 else: 89 for x in s: 90 return x 91 92def encode_input(text): 93 """Encode given text via preferred system encoding""" 94 # locale will often find out the correct encoding 95 encoding = locale.getpreferredencoding() 96 try: 97 encoded_text = text.encode(encoding) 98 except UnicodeError: 99 # if it fails to find correct encoding then ascii is used 100 # which may lead to UnicodeError if `text` contains non ascii signs 101 # utf-8 is our guess to fix the situation 102 encoded_text = text.encode('utf-8') 103 return encoded_text 104 105def decode_input(text): 106 """Decode given text via preferred system encoding""" 107 # locale will often find out the correct encoding 108 encoding = locale.getpreferredencoding() 109 try: 110 decoded_text = text.decode(encoding) 111 except UnicodeError: 112 # if it fails to find correct encoding then ascii is used 113 # which may lead to UnicodeError if `text` contains non ascii signs 114 # utf-8 is our guess to fix the situation 115 decoded_text = text.decode('utf-8') 116 return decoded_text 117 118class Comparison(): 119 """Class used when implementing rich comparison. 120 121 Inherit from this class if you want to have a rich 122 comparison withing the class, afterwards implement 123 _compare function within your class.""" 124 125 def _compare(self, other, method): 126 return NotImplemented 127 128 def __eq__(self, other): 129 return self._compare(other, lambda a, b: a == b) 130 131 def __lt__(self, other): 132 return self._compare(other, lambda a, b: a < b) 133 134 def __le__(self, other): 135 return self._compare(other, lambda a, b: a <= b) 136 137 def __ge__(self, other): 138 return self._compare(other, lambda a, b: a >= b) 139 140 def __gt__(self, other): 141 return self._compare(other, lambda a, b: a > b) 142 143 def __ne__(self, other): 144 return self._compare(other, lambda a, b: a != b) 145 146if sys.version_info < (2,7): 147 # cmp_to_key function is missing in python2.6 148 def cmp_to_key(mycmp): 149 'Convert a cmp= function into a key= function' 150 class K: 151 def __init__(self, obj, *args): 152 self.obj = obj 153 def __lt__(self, other): 154 return mycmp(self.obj, other.obj) < 0 155 def __gt__(self, other): 156 return mycmp(self.obj, other.obj) > 0 157 def __eq__(self, other): 158 return mycmp(self.obj, other.obj) == 0 159 def __le__(self, other): 160 return mycmp(self.obj, other.obj) <= 0 161 def __ge__(self, other): 162 return mycmp(self.obj, other.obj) >= 0 163 def __ne__(self, other): 164 return mycmp(self.obj, other.obj) != 0 165 return K 166else: 167 from functools import cmp_to_key 168 169def cmp(first, second): 170 return (first > second) - (second > first) 171 172if __name__ == "__main__": 173 import time 174 p = ConsoleProgressBar(sys.stdout, steps=999) 175 p.start("computing pi") 176 for i in range(999): 177 p.step() 178 time.sleep(0.001) 179