My favorites | Sign in
Project Home Downloads Wiki Issues Source
Repository:
Checkout   Browse   Changes   Clones  
Changes to /core/misc.py
5a30a50f74f9 vs. a954a482ac43 Compare: vs.  Format:
Revision a954a482ac43
Go to: 
Project members, sign in to write a code review
/core/misc.py   5a30a50f74f9 /core/misc.py   a954a482ac43
1 # This file is part of Androguard. 1 # This file is part of Androguard.
2 # 2 #
3 # Copyright (C) 2010, Anthony Desnos <desnos at t0t0.org> 3 # Copyright (C) 2010, Anthony Desnos <desnos at t0t0.org>
4 # All rights reserved. 4 # All rights reserved.
5 # 5 #
6 # Androguard is free software: you can redistribute it and/or modify 6 # Androguard is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU Lesser General Public License as published by 7 # it under the terms of the GNU Lesser General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or 8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version. 9 # (at your option) any later version.
10 # 10 #
11 # Androguard is distributed in the hope that it will be useful, 11 # Androguard is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU Lesser General Public License for more details. 14 # GNU Lesser General Public License for more details.
15 # 15 #
16 # You should have received a copy of the GNU Lesser General Public License 16 # You should have received a copy of the GNU Lesser General Public License
17 # along with Androguard. If not, see <http://www.gnu.org/licenses/>. 17 # along with Androguard. If not, see <http://www.gnu.org/licenses/>.
18 18
19 import sys, time, types, random, string 19 import sys, time, types, random, string
20 20
21 VERSION = "BETA 0" 21 VERSION = "b0"
22 22
23 class Color: 23 class Color:
24 normal = "\033[0m" 24 normal = "\033[0m"
25 black = "\033[30m" 25 black = "\033[30m"
26 red = "\033[31m" 26 red = "\033[31m"
27 green = "\033[32m" 27 green = "\033[32m"
28 yellow = "\033[33m" 28 yellow = "\033[33m"
29 blue = "\033[34m" 29 blue = "\033[34m"
30 purple = "\033[35m" 30 purple = "\033[35m"
31 cyan = "\033[36m" 31 cyan = "\033[36m"
32 grey = "\033[37m" 32 grey = "\033[37m"
33 bold = "\033[1m" 33 bold = "\033[1m"
34 uline = "\033[4m" 34 uline = "\033[4m"
35 blink = "\033[5m" 35 blink = "\033[5m"
36 invert = "\033[7m" 36 invert = "\033[7m"
37 37
38 def long2int( l ) : 38 def long2int( l ) :
39 if l > 0x7fffffff : 39 if l > 0x7fffffff :
40 l = (0x7fffffff & l) - 0x80000000 40 l = (0x7fffffff & l) - 0x80000000
41 return l 41 return l
42 42
43 def long2str(l): 43 def long2str(l):
44 """Convert an integer to a string.""" 44 """Convert an integer to a string."""
45 if type(l) not in (types.IntType, types.LongType): 45 if type(l) not in (types.IntType, types.LongType):
46 raise ValueError, 'the input must be an integer' 46 raise ValueError, 'the input must be an integer'
47 47
48 if l < 0: 48 if l < 0:
49 raise ValueError, 'the input must be greater than 0' 49 raise ValueError, 'the input must be greater than 0'
50 s = '' 50 s = ''
51 while l: 51 while l:
52 s = s + chr(l & 255L) 52 s = s + chr(l & 255L)
53 l >>= 8 53 l >>= 8
54 54
55 return s 55 return s
56 56
57 57
58 def str2long(s): 58 def str2long(s):
59 """Convert a string to a long integer.""" 59 """Convert a string to a long integer."""
60 if type(s) not in (types.StringType, types.UnicodeType): 60 if type(s) not in (types.StringType, types.UnicodeType):
61 raise ValueError, 'the input must be a string' 61 raise ValueError, 'the input must be a string'
62 62
63 l = 0L 63 l = 0L
64 for i in s: 64 for i in s:
65 l <<= 8 65 l <<= 8
66 l |= ord(i) 66 l |= ord(i)
67 67
68 return l 68 return l
69 69
70 def levenshtein(a,b): 70 def levenshtein(a,b):
71 "Calculates the Levenshtein distance between a and b." 71 "Calculates the Levenshtein distance between a and b."
72 n, m = len(a), len(b) 72 n, m = len(a), len(b)
73 if n > m: 73 if n > m:
74 # Make sure n <= m, to use O(min(n,m)) space 74 # Make sure n <= m, to use O(min(n,m)) space
75 a,b = b,a 75 a,b = b,a
76 n,m = m,n 76 n,m = m,n
77 77
78 current = range(n+1) 78 current = range(n+1)
79 for i in range(1,m+1): 79 for i in range(1,m+1):
80 previous, current = current, [i]+[0]*n 80 previous, current = current, [i]+[0]*n
81 for j in range(1,n+1): 81 for j in range(1,n+1):
82 add, delete = previous[j]+1, current[j-1]+1 82 add, delete = previous[j]+1, current[j-1]+1
83 change = previous[j-1] 83 change = previous[j-1]
84 if a[j-1] != b[i-1]: 84 if a[j-1] != b[i-1]:
85 change = change + 1 85 change = change + 1
86 current[j] = min(add, delete, change) 86 current[j] = min(add, delete, change)
87 87
88 return current[n] 88 return current[n]
89 89
90 # progressbar - Text progressbar library for python. 90 # progressbar - Text progressbar library for python.
91 # Copyright (c) 2005 Nilton Volpato 91 # Copyright (c) 2005 Nilton Volpato
92 # 92 #
93 # This library is free software; you can redistribute it and/or 93 # This library is free software; you can redistribute it and/or
94 # modify it under the terms of the GNU Lesser General Public 94 # modify it under the terms of the GNU Lesser General Public
95 # License as published by the Free Software Foundation; either 95 # License as published by the Free Software Foundation; either
96 # version 2.1 of the License, or (at your option) any later version. 96 # version 2.1 of the License, or (at your option) any later version.
97 # 97 #
98 # This library is distributed in the hope that it will be useful, 98 # This library is distributed in the hope that it will be useful,
99 # but WITHOUT ANY WARRANTY; without even the implied warranty of 99 # but WITHOUT ANY WARRANTY; without even the implied warranty of
100 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 100 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
101 # Lesser General Public License for more details. 101 # Lesser General Public License for more details.
102 # 102 #
103 # You should have received a copy of the GNU Lesser General Public 103 # You should have received a copy of the GNU Lesser General Public
104 # License along with this library; if not, write to the Free Software 104 # License along with this library; if not, write to the Free Software
105 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 105 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
106 106
107 class ProgressBarWidget(object): 107 class ProgressBarWidget(object):
108 """This is an element of ProgressBar formatting. 108 """This is an element of ProgressBar formatting.
109 109
110 The ProgressBar object will call it's update value when an update 110 The ProgressBar object will call it's update value when an update
111 is needed. It's size may change between call, but the results will 111 is needed. It's size may change between call, but the results will
112 not be good if the size changes drastically and repeatedly. 112 not be good if the size changes drastically and repeatedly.
113 """ 113 """
114 def update(self, pbar): 114 def update(self, pbar):
115 """Returns the string representing the widget. 115 """Returns the string representing the widget.
116 116
117 The parameter pbar is a reference to the calling ProgressBar, 117 The parameter pbar is a reference to the calling ProgressBar,
118 where one can access attributes of the class for knowing how 118 where one can access attributes of the class for knowing how
119 the update must be made. 119 the update must be made.
120 120
121 At least this function must be overriden.""" 121 At least this function must be overriden."""
122 pass 122 pass
123 123
124 class ProgressBarWidgetHFill(object): 124 class ProgressBarWidgetHFill(object):
125 """This is a variable width element of ProgressBar formatting. 125 """This is a variable width element of ProgressBar formatting.
126 126
127 The ProgressBar object will call it's update value, informing the 127 The ProgressBar object will call it's update value, informing the
128 width this object must the made. This is like TeX \\hfill, it will 128 width this object must the made. This is like TeX \\hfill, it will
129 expand to fill the line. You can use more than one in the same 129 expand to fill the line. You can use more than one in the same
130 line, and they will all have the same width, and together will 130 line, and they will all have the same width, and together will
131 fill the line. 131 fill the line.
132 """ 132 """
133 def update(self, pbar, width): 133 def update(self, pbar, width):
134 """Returns the string representing the widget. 134 """Returns the string representing the widget.
135 135
136 The parameter pbar is a reference to the calling ProgressBar, 136 The parameter pbar is a reference to the calling ProgressBar,
137 where one can access attributes of the class for knowing how 137 where one can access attributes of the class for knowing how
138 the update must be made. The parameter width is the total 138 the update must be made. The parameter width is the total
139 horizontal width the widget must have. 139 horizontal width the widget must have.
140 140
141 At least this function must be overriden.""" 141 At least this function must be overriden."""
142 pass 142 pass
143 143
144 144
145 class ETA(ProgressBarWidget): 145 class ETA(ProgressBarWidget):
146 "Widget for the Estimated Time of Arrival" 146 "Widget for the Estimated Time of Arrival"
147 def format_time(self, seconds): 147 def format_time(self, seconds):
148 return time.strftime('%H:%M:%S', time.gmtime(seconds)) 148 return time.strftime('%H:%M:%S', time.gmtime(seconds))
149 def update(self, pbar): 149 def update(self, pbar):
150 if pbar.currval == 0: 150 if pbar.currval == 0:
151 return 'ETA: --:--:--' 151 return 'ETA: --:--:--'
152 elif pbar.finished: 152 elif pbar.finished:
153 return 'Time: %s' % self.format_time(pbar.seconds_elapsed) 153 return 'Time: %s' % self.format_time(pbar.seconds_elapsed)
154 else: 154 else:
155 elapsed = pbar.seconds_elapsed 155 elapsed = pbar.seconds_elapsed
156 eta = elapsed * pbar.maxval / pbar.currval - elapsed 156 eta = elapsed * pbar.maxval / pbar.currval - elapsed
157 return 'ETA: %s' % self.format_time(eta) 157 return 'ETA: %s' % self.format_time(eta)
158 158
159 class FileTransferSpeed(ProgressBarWidget): 159 class FileTransferSpeed(ProgressBarWidget):
160 "Widget for showing the transfer speed (useful for file transfers)." 160 "Widget for showing the transfer speed (useful for file transfers)."
161 def __init__(self): 161 def __init__(self):
162 self.fmt = '%6.2f %s' 162 self.fmt = '%6.2f %s'
163 self.units = ['B','K','M','G','T','P'] 163 self.units = ['B','K','M','G','T','P']
164 def update(self, pbar): 164 def update(self, pbar):
165 if pbar.seconds_elapsed < 2e-6:#== 0: 165 if pbar.seconds_elapsed < 2e-6:#== 0:
166 bps = 0.0 166 bps = 0.0
167 else: 167 else:
168 bps = float(pbar.currval) / pbar.seconds_elapsed 168 bps = float(pbar.currval) / pbar.seconds_elapsed
169 spd = bps 169 spd = bps
170 for u in self.units: 170 for u in self.units:
171 if spd < 1000: 171 if spd < 1000:
172 break 172 break
173 spd /= 1000 173 spd /= 1000
174 return self.fmt % (spd, u+'/s') 174 return self.fmt % (spd, u+'/s')
175 175
176 class RotatingMarker(ProgressBarWidget): 176 class RotatingMarker(ProgressBarWidget):
177 "A rotating marker for filling the bar of progress." 177 "A rotating marker for filling the bar of progress."
178 def __init__(self, markers='|/-\\'): 178 def __init__(self, markers='|/-\\'):
179 self.markers = markers 179 self.markers = markers
180 self.curmark = -1 180 self.curmark = -1
181 def update(self, pbar): 181 def update(self, pbar):
182 if pbar.finished: 182 if pbar.finished:
183 return self.markers[0] 183 return self.markers[0]
184 self.curmark = (self.curmark + 1)%len(self.markers) 184 self.curmark = (self.curmark + 1)%len(self.markers)
185 return self.markers[self.curmark] 185 return self.markers[self.curmark]
186 186
187 class Percentage(ProgressBarWidget): 187 class Percentage(ProgressBarWidget):
188 "Just the percentage done." 188 "Just the percentage done."
189 def update(self, pbar): 189 def update(self, pbar):
190 return '%3d%%' % pbar.percentage() 190 return '%3d%%' % pbar.percentage()
191 191
192 class Bar(ProgressBarWidgetHFill): 192 class Bar(ProgressBarWidgetHFill):
193 "The bar of progress. It will strech to fill the line." 193 "The bar of progress. It will strech to fill the line."
194 def __init__(self, marker='#', left='|', right='|'): 194 def __init__(self, marker='#', left='|', right='|'):
195 self.marker = marker 195 self.marker = marker
196 self.left = left 196 self.left = left
197 self.right = right 197 self.right = right
198 def _format_marker(self, pbar): 198 def _format_marker(self, pbar):
199 if isinstance(self.marker, (str, unicode)): 199 if isinstance(self.marker, (str, unicode)):
200 return self.marker 200 return self.marker
201 else: 201 else:
202 return self.marker.update(pbar) 202 return self.marker.update(pbar)
203 def update(self, pbar, width): 203 def update(self, pbar, width):
204 percent = pbar.percentage() 204 percent = pbar.percentage()
205 cwidth = width - len(self.left) - len(self.right) 205 cwidth = width - len(self.left) - len(self.right)
206 marked_width = int(percent * cwidth / 100) 206 marked_width = int(percent * cwidth / 100)
207 m = self._format_marker(pbar) 207 m = self._format_marker(pbar)
208 bar = (self.left + (m*marked_width).ljust(cwidth) + self.right) 208 bar = (self.left + (m*marked_width).ljust(cwidth) + self.right)
209 return bar 209 return bar
210 210
211 class ReverseBar(Bar): 211 class ReverseBar(Bar):
212 "The reverse bar of progress, or bar of regress. :)" 212 "The reverse bar of progress, or bar of regress. :)"
213 def update(self, pbar, width): 213 def update(self, pbar, width):
214 percent = pbar.percentage() 214 percent = pbar.percentage()
215 cwidth = width - len(self.left) - len(self.right) 215 cwidth = width - len(self.left) - len(self.right)
216 marked_width = int(percent * cwidth / 100) 216 marked_width = int(percent * cwidth / 100)
217 m = self._format_marker(pbar) 217 m = self._format_marker(pbar)
218 bar = (self.left + (m*marked_width).rjust(cwidth) + self.right) 218 bar = (self.left + (m*marked_width).rjust(cwidth) + self.right)
219 return bar 219 return bar
220 220
221 default_widgets = [Percentage(), ' ', Bar()] 221 default_widgets = [Percentage(), ' ', Bar()]
222 class ProgressBar(object): 222 class ProgressBar(object):
223 """This is the ProgressBar class, it updates and prints the bar. 223 """This is the ProgressBar class, it updates and prints the bar.
224 224
225 The term_width parameter may be an integer. Or None, in which case 225 The term_width parameter may be an integer. Or None, in which case
226 it will try to guess it, if it fails it will default to 80 columns. 226 it will try to guess it, if it fails it will default to 80 columns.
227 227
228 The simple use is like this: 228 The simple use is like this:
229 >>> pbar = ProgressBar().start() 229 >>> pbar = ProgressBar().start()
230 >>> for i in xrange(100): 230 >>> for i in xrange(100):
231 ... # do something 231 ... # do something
232 ... pbar.update(i+1) 232 ... pbar.update(i+1)
233 ... 233 ...
234 >>> pbar.finish() 234 >>> pbar.finish()
235 235
236 But anything you want to do is possible (well, almost anything). 236 But anything you want to do is possible (well, almost anything).
237 You can supply different widgets of any type in any order. And you 237 You can supply different widgets of any type in any order. And you
238 can even write your own widgets! There are many widgets already 238 can even write your own widgets! There are many widgets already
239 shipped and you should experiment with them. 239 shipped and you should experiment with them.
240 240
241 When implementing a widget update method you may access any 241 When implementing a widget update method you may access any
242 attribute or function of the ProgressBar object calling the 242 attribute or function of the ProgressBar object calling the
243 widget's update method. The most important attributes you would 243 widget's update method. The most important attributes you would
244 like to access are: 244 like to access are:
245 - currval: current value of the progress, 0 <= currval <= maxval 245 - currval: current value of the progress, 0 <= currval <= maxval
246 - maxval: maximum (and final) value of the progress 246 - maxval: maximum (and final) value of the progress
247 - finished: True if the bar is have finished (reached 100%), False o/w 247 - finished: True if the bar is have finished (reached 100%), False o/w
248 - start_time: first time update() method of ProgressBar was called 248 - start_time: first time update() method of ProgressBar was called
249 - seconds_elapsed: seconds elapsed since start_time 249 - seconds_elapsed: seconds elapsed since start_time
250 - percentage(): percentage of the progress (this is a method) 250 - percentage(): percentage of the progress (this is a method)
251 """ 251 """
252 def __init__(self, maxval=100, widgets=default_widgets, term_width=None, 252 def __init__(self, maxval=100, widgets=default_widgets, term_width=None,
253 fd=sys.stderr): 253 fd=sys.stderr):
254 assert maxval > 0 254 assert maxval > 0
255 self.maxval = maxval 255 self.maxval = maxval
256 self.widgets = widgets 256 self.widgets = widgets
257 self.fd = fd 257 self.fd = fd
258 self.signal_set = False 258 self.signal_set = False
259 if term_width is None: 259 if term_width is None:
260 try: 260 try:
261 self.handle_resize(None,None) 261 self.handle_resize(None,None)
262 signal.signal(signal.SIGWINCH, self.handle_resize) 262 signal.signal(signal.SIGWINCH, self.handle_resize)
263 self.signal_set = True 263 self.signal_set = True
264 except: 264 except:
265 self.term_width = 79 265 self.term_width = 79
266 else: 266 else:
267 self.term_width = term_width 267 self.term_width = term_width
268 268
269 self.currval = 0 269 self.currval = 0
270 self.finished = False 270 self.finished = False
271 self.prev_percentage = -1 271 self.prev_percentage = -1
272 self.start_time = None 272 self.start_time = None
273 self.seconds_elapsed = 0 273 self.seconds_elapsed = 0
274 274
275 def handle_resize(self, signum, frame): 275 def handle_resize(self, signum, frame):
276 h,w=array('h', ioctl(self.fd,termios.TIOCGWINSZ,'\0'*8))[:2] 276 h,w=array('h', ioctl(self.fd,termios.TIOCGWINSZ,'\0'*8))[:2]
277 self.term_width = w 277 self.term_width = w
278 278
279 def percentage(self): 279 def percentage(self):
280 "Returns the percentage of the progress." 280 "Returns the percentage of the progress."
281 return self.currval*100.0 / self.maxval 281 return self.currval*100.0 / self.maxval
282 282
283 def _format_widgets(self): 283 def _format_widgets(self):
284 r = [] 284 r = []
285 hfill_inds = [] 285 hfill_inds = []
286 num_hfill = 0 286 num_hfill = 0
287 currwidth = 0 287 currwidth = 0
288 for i, w in enumerate(self.widgets): 288 for i, w in enumerate(self.widgets):
289 if isinstance(w, ProgressBarWidgetHFill): 289 if isinstance(w, ProgressBarWidgetHFill):
290 r.append(w) 290 r.append(w)
291 hfill_inds.append(i) 291 hfill_inds.append(i)
292 num_hfill += 1 292 num_hfill += 1
293 elif isinstance(w, (str, unicode)): 293 elif isinstance(w, (str, unicode)):
294 r.append(w) 294 r.append(w)
295 currwidth += len(w) 295 currwidth += len(w)
296 else: 296 else:
297 weval = w.update(self) 297 weval = w.update(self)
298 currwidth += len(weval) 298 currwidth += len(weval)
299 r.append(weval) 299 r.append(weval)
300 for iw in hfill_inds: 300 for iw in hfill_inds:
301 r[iw] = r[iw].update(self, (self.term_width-currwidth)/num_hfill) 301 r[iw] = r[iw].update(self, (self.term_width-currwidth)/num_hfill)
302 return r 302 return r
303 303
304 def _format_line(self): 304 def _format_line(self):
305 return ''.join(self._format_widgets()).ljust(self.term_width) 305 return ''.join(self._format_widgets()).ljust(self.term_width)
306 306
307 def _need_update(self): 307 def _need_update(self):
308 return int(self.percentage()) != int(self.prev_percentage) 308 return int(self.percentage()) != int(self.prev_percentage)
309 309
310 def update(self, value): 310 def update(self, value):
311 "Updates the progress bar to a new value." 311 "Updates the progress bar to a new value."
312 assert 0 <= value <= self.maxval 312 assert 0 <= value <= self.maxval
313 self.currval = value 313 self.currval = value
314 if not self._need_update() or self.finished: 314 if not self._need_update() or self.finished:
315 return 315 return
316 if not self.start_time: 316 if not self.start_time:
317 self.start_time = time.time() 317 self.start_time = time.time()
318 self.seconds_elapsed = time.time() - self.start_time 318 self.seconds_elapsed = time.time() - self.start_time
319 self.prev_percentage = self.percentage() 319 self.prev_percentage = self.percentage()
320 if value != self.maxval: 320 if value != self.maxval:
321 self.fd.write(self._format_line() + '\r') 321 self.fd.write(self._format_line() + '\r')
322 else: 322 else:
323 self.finished = True 323 self.finished = True
324 self.fd.write(self._format_line() + '\n') 324 self.fd.write(self._format_line() + '\n')
325 325
326 def start(self): 326 def start(self):
327 """Start measuring time, and prints the bar at 0%. 327 """Start measuring time, and prints the bar at 0%.
328 328
329 It returns self so you can use it like this: 329 It returns self so you can use it like this:
330 >>> pbar = ProgressBar().start() 330 >>> pbar = ProgressBar().start()
331 >>> for i in xrange(100): 331 >>> for i in xrange(100):
332 ... # do something 332 ... # do something
333 ... pbar.update(i+1) 333 ... pbar.update(i+1)
334 ... 334 ...
335 >>> pbar.finish() 335 >>> pbar.finish()
336 """ 336 """
337 self.update(0) 337 self.update(0)
338 return self 338 return self
339 339
340 def finish(self): 340 def finish(self):
341 """Used to tell the progress is finished.""" 341 """Used to tell the progress is finished."""
342 self.update(self.maxval) 342 self.update(self.maxval)
343 if self.signal_set: 343 if self.signal_set:
344 signal.signal(signal.SIGWINCH, signal.SIG_DFL) 344 signal.signal(signal.SIGWINCH, signal.SIG_DFL)
345 345
346 def random_string() : 346 def random_string() :
347 return random.choice( string.letters ) + ''.join([ random.choice(string.letters + string.digits) for i in range(10 - 1) ] ) 347 return random.choice( string.letters ) + ''.join([ random.choice(string.letters + string.digits) for i in range(10 - 1) ] )
Powered by Google Project Hosting