#NEWLINE# def download_with_resume( uri , dest ) : #NEWLINE# #INDENT# handler = HTTPRangeHandler ( ) #NEWLINE# opener = build_opener ( handler ) #NEWLINE# offset = 0 #NEWLINE# content_length = None #NEWLINE# accept_ranges = False #NEWLINE# while True : #NEWLINE# #INDENT# req = Request ( uri ) #NEWLINE# if offset : #NEWLINE# #INDENT# req . add_header ( 'Range' , ( 'bytes=%d-' % offset ) ) #NEWLINE# #UNINDENT# src_file = None #NEWLINE# try : #NEWLINE# #INDENT# src_file = opener . open ( req ) #NEWLINE# headers = src_file . info ( ) #NEWLINE# if ( not offset ) : #NEWLINE# #INDENT# if ( 'Content-Length' in headers ) : #NEWLINE# #INDENT# content_length = int ( headers [ 'Content-Length' ] ) #NEWLINE# #UNINDENT# if ( 'Accept-Ranges' in data ) : #NEWLINE# #INDENT# accept_ranges = ( headers [ 'Accept-Ranges' ] != 'none' ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( 'Content-Range' not in headers ) : #NEWLINE# #INDENT# raise IOError ( 'Download aborted and server does not support resuming download' ) #NEWLINE# #UNINDENT# if ( int ( headers [ 'Content-Range' ] [ len ( 'bytes ' ) : ] . split ( '-' ) [ 0 ] ) != offset ) : #NEWLINE# #INDENT# raise IOError ( 'Download aborted because server replied with different content range then requested' ) #NEWLINE# #UNINDENT# sys . stdout . write ( ( ' resume from %d...' % offset ) ) #NEWLINE# sys . stdout . flush ( ) #NEWLINE# #UNINDENT# with open ( dest , ( 'ab' if offset else 'wb' ) ) as dst_file : #NEWLINE# #INDENT# progress = False #NEWLINE# while True : #NEWLINE# #INDENT# data = src_file . read ( 8192 ) #NEWLINE# if ( not data ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# progress = True #NEWLINE# dst_file . write ( data ) #NEWLINE# offset += len ( data ) #NEWLINE# #UNINDENT# if ( not progress ) : #NEWLINE# #INDENT# raise IOError ( ( "No progress when trying to download '%s'" % uri ) ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# except : #NEWLINE# #INDENT# if src_file : #NEWLINE# #INDENT# src_file . close ( ) #NEWLINE# #UNINDENT# raise #NEWLINE# #UNINDENT# if ( content_length is None ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# if ( offset >= content_length ) : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# if ( not accept_ranges ) : #NEWLINE# #INDENT# raise IOError ( 'Server does not accept ranges to resume download' )