1
2
3 '''HTTPHandler that supports a callback method for progress reports.
4 '''
5
6 import urllib2
7 import httplib
8 import logging
9
10 __all__ = ['urlopen']
11
12 logging.basicConfig()
13 LOG = logging.getLogger(__name__)
14
15 progress_callback = None
16
17
19 '''Wrapper around a socket. Gives progress report through a
20 callback function.
21 '''
22
23 min_chunksize = 10240
24
27
29 '''Sends all data, calling the callback function for every
30 sent chunk.
31 '''
32
33 LOG.debug("SENDING: %s..." % bits[0:30])
34 total = len(bits)
35 sent = 0
36 chunksize = max(self.min_chunksize, total // 100)
37
38 while len(bits) > 0:
39 send = bits[0:chunksize]
40 self.socket.sendall(send)
41 sent += len(send)
42 if progress_callback:
43 progress = float(sent) / total * 100
44 progress_callback(progress, sent == total)
45
46 bits = bits[chunksize:]
47
49 '''Returns a file-like object for the socket.'''
50
51 return self.socket.makefile(mode, bufsize)
52
54 '''Closes the socket.'''
55
56 return self.socket.close()
57
58
60 '''HTTPConnection that gives regular progress reports during
61 sending of data.
62 '''
63
65 '''Connects to a HTTP server.'''
66
67 httplib.HTTPConnection.connect(self)
68 self.sock = ReportingSocket(self.sock)
69
70
72 '''HTTPHandler that gives regular progress reports during sending
73 of data.
74 '''
77
78
80 '''Sets the callback function to use for progress reports.'''
81
82 global progress_callback
83
84 if not hasattr(method, '__call__'):
85 raise ValueError('Callback method must be callable')
86
87 progress_callback = method
88
89
90 -def urlopen(url_or_request, callback, body=None):
91 '''Opens an URL using the ProgressHTTPHandler.'''
92
93 set_callback(callback)
94 opener = urllib2.build_opener(ProgressHTTPHandler)
95 return opener.open(url_or_request, body)
96
97 if __name__ == '__main__':
98 - def upload(progress, finished):
99 '''Upload progress demo'''
100
101 LOG.info("%3.0f - %s" % (progress, finished))
102
103 conn = urlopen("http://www.flickr.com/", 'x' * 10245, upload)
104 data = conn.read()
105 LOG.info("Read data")
106 print data[:100].split('\n')[0]
107