Mercurial > nagslang
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 |