##// END OF EJS Templates
enable posting GitHub downloads
MinRK -
Show More
@@ -6,6 +6,8 b' try:'
6 6 except NameError:
7 7 pass
8 8
9 import os
10
9 11 import requests
10 12 import getpass
11 13 import json
@@ -102,3 +104,101 b' def get_pulls_list(project, github_api=3):'
102 104 if github_api == 2 :
103 105 return json.loads(response.text)['pulls']
104 106 return json.loads(response.text)
107
108 # encode_multipart_formdata is from urllib3.filepost
109 # The only change is to iter_fields, to enforce S3's required key ordering
110
111 def iter_fields(fields):
112 fields = fields.copy()
113 for key in ('key', 'acl', 'Filename', 'success_action_status', 'AWSAccessKeyId',
114 'Policy', 'Signature', 'Content-Type', 'file'):
115 yield (key, fields.pop(key))
116 for (k,v) in fields.items():
117 yield k,v
118
119 def encode_multipart_formdata(fields, boundary=None):
120 """
121 Encode a dictionary of ``fields`` using the multipart/form-data mime format.
122
123 :param fields:
124 Dictionary of fields or list of (key, value) field tuples. The key is
125 treated as the field name, and the value as the body of the form-data
126 bytes. If the value is a tuple of two elements, then the first element
127 is treated as the filename of the form-data section.
128
129 Field names and filenames must be unicode.
130
131 :param boundary:
132 If not specified, then a random boundary will be generated using
133 :func:`mimetools.choose_boundary`.
134 """
135 # copy requests imports in here:
136 from io import BytesIO
137 from requests.packages.urllib3.filepost import (
138 choose_boundary, six, writer, b, get_content_type
139 )
140 body = BytesIO()
141 if boundary is None:
142 boundary = choose_boundary()
143
144 for fieldname, value in iter_fields(fields):
145 body.write(b('--%s\r\n' % (boundary)))
146
147 if isinstance(value, tuple):
148 filename, data = value
149 writer(body).write('Content-Disposition: form-data; name="%s"; '
150 'filename="%s"\r\n' % (fieldname, filename))
151 body.write(b('Content-Type: %s\r\n\r\n' %
152 (get_content_type(filename))))
153 else:
154 data = value
155 writer(body).write('Content-Disposition: form-data; name="%s"\r\n'
156 % (fieldname))
157 body.write(b'Content-Type: text/plain\r\n\r\n')
158
159 if isinstance(data, int):
160 data = str(data) # Backwards compatibility
161 if isinstance(data, six.text_type):
162 writer(body).write(data)
163 else:
164 body.write(data)
165
166 body.write(b'\r\n')
167
168 body.write(b('--%s--\r\n' % (boundary)))
169
170 content_type = b('multipart/form-data; boundary=%s' % boundary)
171
172 return body.getvalue(), content_type
173
174
175 def post_download(project, filename, name=None, description=""):
176 """Upload a file to the GitHub downloads area"""
177 if name is None:
178 name = os.path.basename(filename)
179 with open(filename, 'rb') as f:
180 filedata = f.read()
181
182 url = "https://api.github.com/repos/{project}/downloads".format(project=project)
183
184 payload = json.dumps(dict(name=name, size=len(filedata),
185 description=description))
186 response = requests.post(url, data=payload, headers=make_auth_header())
187 response.raise_for_status()
188 reply = json.loads(response.content)
189 s3_url = reply['s3_url']
190
191 fields = dict(
192 key=reply['path'],
193 acl=reply['acl'],
194 success_action_status=201,
195 Filename=reply['name'],
196 AWSAccessKeyId=reply['accesskeyid'],
197 Policy=reply['policy'],
198 Signature=reply['signature'],
199 file=(reply['name'], filedata),
200 )
201 fields['Content-Type'] = reply['mime_type']
202 data, content_type = encode_multipart_formdata(fields)
203 s3r = requests.post(s3_url, data=data, headers={'Content-Type': content_type})
204 return s3r
General Comments 0
You need to be logged in to leave comments. Login now