comparison pyweek_upload.py @ 2:e30d192e9031

Fix PEP8 errors.
author Simon Cross <hodgestar@gmail.com>
date Sun, 01 Sep 2013 10:12:43 +0200
parents 1ea8fa09b70f
children
comparison
equal deleted inserted replaced
1:47410c09ec35 2:e30d192e9031
1 ''' 1 '''
2 Upload script specifically engineered for the PyWeek challenge. 2 Upload script specifically engineered for the PyWeek challenge.
3 3
4 Handles authentication and gives upload progress feedback. 4 Handles authentication and gives upload progress feedback.
5 ''' 5 '''
6 import sys, os, httplib, cStringIO, socket, time, getopt 6 import sys
7 7 import os
8 class Upload: 8 import httplib
9 import cStringIO
10 import socket
11 import time
12 import getopt
13
14
15 class Upload(object):
9 def __init__(self, filename): 16 def __init__(self, filename):
10 self.filename = filename 17 self.filename = filename
11 18
12 boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' 19 boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
13 sep_boundary = '\n--' + boundary 20 sep_boundary = '\n--' + boundary
14 end_boundary = sep_boundary + '--' 21 end_boundary = sep_boundary + '--'
22
15 23
16 def mimeEncode(data, sep_boundary=sep_boundary, end_boundary=end_boundary): 24 def mimeEncode(data, sep_boundary=sep_boundary, end_boundary=end_boundary):
17 '''Take the mapping of data and construct the body of a 25 '''Take the mapping of data and construct the body of a
18 multipart/form-data message with it using the indicated boundaries. 26 multipart/form-data message with it using the indicated boundaries.
19 ''' 27 '''
20 ret = cStringIO.StringIO() 28 ret = cStringIO.StringIO()
21 for key, value in data.items(): 29 for key, value in data.items():
22 # handle multiple entries for the same name 30 # handle multiple entries for the same name
23 if type(value) != type([]): value = [value] 31 if not isinstance(value, list):
32 value = [value]
24 for value in value: 33 for value in value:
25 ret.write(sep_boundary) 34 ret.write(sep_boundary)
26 if isinstance(value, Upload): 35 if isinstance(value, Upload):
27 ret.write('\nContent-Disposition: form-data; name="%s"'%key) 36 ret.write('\nContent-Disposition: form-data; name="%s"' % key)
28 filename = os.path.basename(value.filename) 37 filename = os.path.basename(value.filename)
29 ret.write('; filename="%s"\n\n'%filename) 38 ret.write('; filename="%s"\n\n' % filename)
30 value = open(os.path.join(value.filename), "rb").read() 39 value = open(os.path.join(value.filename), "rb").read()
31 else: 40 else:
32 ret.write('\nContent-Disposition: form-data; name="%s"'%key) 41 ret.write('\nContent-Disposition: form-data; name="%s"' % key)
33 ret.write("\n\n") 42 ret.write("\n\n")
34 value = str(value) 43 value = str(value)
35 ret.write(str(value)) 44 ret.write(str(value))
36 if value and value[-1] == '\r': 45 if value and value[-1] == '\r':
37 ret.write('\n') # write an extra newline 46 ret.write('\n') # write an extra newline
38 ret.write(end_boundary) 47 ret.write(end_boundary)
39 return ret.getvalue() 48 return ret.getvalue()
40 49
41 class Progress: 50
51 class Progress(object):
42 def __init__(self, info, data): 52 def __init__(self, info, data):
43 self.info = info 53 self.info = info
44 self.tosend = len(data) 54 self.tosend = len(data)
45 self.total = self.tosend/1024 55 self.total = self.tosend / 1024
46 self.data = cStringIO.StringIO(data) 56 self.data = cStringIO.StringIO(data)
47 self.start = self.now = time.time() 57 self.start = self.now = time.time()
48 self.sent = 0 58 self.sent = 0
49 self.num = 0 59 self.num = 0
50 self.stepsize = self.total / 100 or 1 60 self.stepsize = self.total / 100 or 1
51 self.steptimes = [] 61 self.steptimes = []
52 self.display() 62 self.display()
53 63
54 def __iter__(self): return self 64 def __iter__(self):
65 return self
55 66
56 def next(self): 67 def next(self):
57 self.num += 1 68 self.num += 1
58 if self.sent >= self.tosend: 69 if self.sent >= self.tosend:
59 print self.info, 'done', ' '*(75-len(self.info)-6) 70 print self.info, 'done', ' ' * (75 - len(self.info) - 6)
60 sys.stdout.flush() 71 sys.stdout.flush()
61 raise StopIteration 72 raise StopIteration
62 73
63 chunk = self.data.read(1024) 74 chunk = self.data.read(1024)
64 self.sent += len(chunk) 75 self.sent += len(chunk)
76 self.steptimes.insert(0, steptime) 87 self.steptimes.insert(0, steptime)
77 if len(self.steptimes) > 5: 88 if len(self.steptimes) > 5:
78 self.steptimes.pop() 89 self.steptimes.pop()
79 steptime = sum(self.steptimes) / len(self.steptimes) 90 steptime = sum(self.steptimes) / len(self.steptimes)
80 self.now = now 91 self.now = now
81 eta = steptime * ((self.total - self.num)/self.stepsize) 92 eta = steptime * ((self.total - self.num) / self.stepsize)
82 93
83 # tell it like it is (or might be) 94 # tell it like it is (or might be)
84 if now - self.start > 3: 95 if now - self.start > 3:
85 M = eta / 60 96 M = eta / 60
86 H = M / 60 97 H = M / 60
87 M = M % 60 98 M = M % 60
88 S = eta % 60 99 S = eta % 60
89 if self.total: 100 if self.total:
90 s = '%s %2d%% (ETA %02d:%02d:%02d)'%(self.info, 101 s = '%s %2d%% (ETA %02d:%02d:%02d)' % (self.info,
91 self.num * 100. / self.total, H, M, S) 102 self.num * 100. / self.total, H, M, S)
92 else: 103 else:
93 s = '%s 0%% (ETA %02d:%02d:%02d)'%(self.info, H, M, S) 104 s = '%s 0%% (ETA %02d:%02d:%02d)' % (self.info, H, M, S)
94 elif self.total: 105 elif self.total:
95 s = '%s %2d%%'%(self.info, self.num * 100. / self.total) 106 s = '%s %2d%%' % (self.info, self.num * 100. / self.total)
96 else: 107 else:
97 s = '%s %d done'%(self.info, self.num) 108 s = '%s %d done' % (self.info, self.num)
98 sys.stdout.write(s + ' '*(75-len(s)) + '\r') 109 sys.stdout.write(s + ' ' * (75 - len(s)) + '\r')
99 sys.stdout.flush() 110 sys.stdout.flush()
111
100 112
101 class progressHTTPConnection(httplib.HTTPConnection): 113 class progressHTTPConnection(httplib.HTTPConnection):
102 def progress_send(self, str): 114 def progress_send(self, str):
103 """Send `str' to the server.""" 115 """Send `str' to the server."""
104 if self.sock is None: 116 if self.sock is None:
114 if v[0] == 32: # Broken pipe 126 if v[0] == 32: # Broken pipe
115 self.close() 127 self.close()
116 raise 128 raise
117 p.display() 129 p.display()
118 130
131
119 class progressHTTP(httplib.HTTP): 132 class progressHTTP(httplib.HTTP):
120 _connection_class = progressHTTPConnection 133 _connection_class = progressHTTPConnection
134
121 def _setup(self, conn): 135 def _setup(self, conn):
122 httplib.HTTP._setup(self, conn) 136 httplib.HTTP._setup(self, conn)
123 self.progress_send = self._conn.progress_send 137 self.progress_send = self._conn.progress_send
124 138
139
125 def http_request(data, server, port, url): 140 def http_request(data, server, port, url):
126 h = progressHTTP(server, port) 141 h = progressHTTP(server, port)
127 142
128 data = mimeEncode(data) 143 data = mimeEncode(data)
129 h.putrequest('POST', url) 144 h.putrequest('POST', url)
130 h.putheader('Content-type', 'multipart/form-data; boundary=%s'%boundary) 145 h.putheader('Content-type', 'multipart/form-data; boundary=%s' % boundary)
131 h.putheader('Content-length', str(len(data))) 146 h.putheader('Content-length', str(len(data)))
132 h.putheader('Host', server) 147 h.putheader('Host', server)
133 h.endheaders() 148 h.endheaders()
134 149
135 h.progress_send(data) 150 h.progress_send(data)
138 153
139 f = h.getfile() 154 f = h.getfile()
140 response = f.read().strip() 155 response = f.read().strip()
141 f.close() 156 f.close()
142 157
143 print '%s %s'%(errcode, errmsg) 158 print '%s %s' % (errcode, errmsg)
144 if response: print response 159 if response:
160 print response
161
145 162
146 def usage(): 163 def usage():
147 print '''This program is to be used to upload files to the PyWeek system. 164 print '''This program is to be used to upload files to the PyWeek system.
148 You may use it to upload screenshots or code submissions. 165 You may use it to upload screenshots or code submissions.
149 166
176 port = 80 193 port = 80
177 data = dict(version=2) 194 data = dict(version=2)
178 optional = {} 195 optional = {}
179 url = None 196 url = None
180 for opt, arg in optlist: 197 for opt, arg in optlist:
181 if opt == '-u': data['user'] = arg 198 if opt == '-u':
182 elif opt == '-p': data['password'] = arg 199 data['user'] = arg
183 elif opt == '-s': optional['is_screenshot'] = 'yes' 200 elif opt == '-p':
184 elif opt == '-f': optional['is_final'] = 'yes' 201 data['password'] = arg
185 elif opt == '-d': data['description'] = arg 202 elif opt == '-s':
186 elif opt == '-c': data['content_file'] = Upload(arg) 203 optional['is_screenshot'] = 'yes'
187 elif opt == '-e': url = '/e/%s/oup/'%arg 204 elif opt == '-f':
188 elif opt == '-h': host = arg 205 optional['is_final'] = 'yes'
189 elif opt == '-P': port = int(arg) 206 elif opt == '-d':
207 data['description'] = arg
208 elif opt == '-c':
209 data['content_file'] = Upload(arg)
210 elif opt == '-e':
211 url = '/e/%s/oup/' % arg
212 elif opt == '-h':
213 host = arg
214 elif opt == '-P':
215 port = int(arg)
190 216
191 if len(data) < 4 or url is None: 217 if len(data) < 4 or url is None:
192 print 'Required argument missing' 218 print 'Required argument missing'
193 usage() 219 usage()
194 sys.exit(1) 220 sys.exit(1)
195 221
196 data.update(optional) 222 data.update(optional)
197 http_request(data, host, port, url) 223 http_request(data, host, port, url)
198