Package commons :: Module progress
[hide private]
[frames] | no frames]

Source Code for Module commons.progress

  1  # -*- mode: python; tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4; -*- 
  2  # vim:ft=python:et:sw=4:ts=4 
  3   
  4  """ 
  5  Long-running processes and facilities to let them report their progress. 
  6  """ 
  7   
  8  from commons.log import * 
  9  from commons.seqs import * 
 10  import urllib2, sys 
 11   
12 -def urlopen_progress( url, output_stream = None, fields = 'OoRrtcl', chunk_size = 4096 ):
13 """ 14 Progress reporter for urlopen(). This is a generator which, upon 15 receipt of each chunk of data, yields a tuple of values. This 16 tuple reports data about the progress of the download; the exact 17 values yielded can be configured. 18 19 Based on 20 U{http://mail.python.org/pipermail/python-list/2006-January/320635.html}. 21 22 @param url: The URL to fetch. 23 @type url: str 24 25 @param output_stream: The file-like stream object to write to. 26 @type output_stream: stream 27 28 @param fields: A set of characters indicating what data to 29 report. The following characters have meaning: 30 - O: offset where the first byte of the latest chunk is to be 31 written 32 - o: offset percentage 33 - R: received number of bytes (offset + length of latest 34 chunk) 35 - r: received percentage 36 - t: total number of bytes 37 - c: the latest chunk 38 - l: the length of the latest chunk 39 @type fields: str 40 41 @param chunk_size: The requested chunk size. 42 @type chunk_size: int 43 """ 44 chunk_size = 4096 45 result = urllib2.urlopen( url ) 46 headers = result.info() 47 total = int( headers[ 'Content-Length' ] ) 48 for offset, chunk in chunkify( result, chunk_size ): 49 if output_stream is not None: 50 output_stream.write( chunk ) 51 values = [] 52 offset_ratio = float(offset)/float(total) 53 received = offset + len( chunk ) 54 received_ratio = float(received)/float(total) 55 if 'O' in fields: 56 values.append( offset ) 57 if 'o' in fields: 58 values.append( offset_ratio ) 59 if 'R' in fields: 60 values.append( received ) 61 if 'r' in fields: 62 values.append( received_ratio ) 63 if 't' in fields: 64 values.append( total ) 65 if 'c' in fields: 66 values.append( chunk ) 67 if 'l' in fields: 68 values.append( len( chunk ) ) 69 # TODO allow caller to customize the yields 70 yield tuple( values ) 71 debug( 'urlopen_progress', 'R', received, 'r', received_ratio, 't', total ) 72 result.close()
73 74 # TODO enable printing to a different stream 75 # TODO enable index/total/block interface
76 -def render_progress( caption, ratio, width ): # index = None, total = None, block = None ):
77 """ 78 Draws a progress bar on the console. First prints a carriage 79 return, so this function can be called repeatedly to create an 80 "animated" progress bar. 81 82 @param caption: The label printed to the left of the bar. 83 @type caption: str 84 85 @param ratio: The percentage progress. 86 @type ratio: float 87 88 @param width: The width of the progress bar, in characters. 89 @type width: int 90 """ 91 sys.stdout.write( interp( '\r$caption: [' ) ) 92 thresh = ratio * width 93 for cursor in range( width ): 94 if cursor < thresh: 95 sys.stdout.write( '=' ) 96 else: 97 sys.stdout.write( ' ' ) 98 sys.stdout.write( interp( '] $ratio' ) ) 99 if ratio == 1.0: 100 sys.stdout.write( '\n' ) 101 #if index % block == 0: 102 # print interp( '\r$caption: |' ) 103 # for counter in range( total / block ): 104 # if counter < index / block: 105 # print '.' 106 # else: 107 # print ' ' 108 # print "| " 109