OLD | NEW |
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ | 1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ |
2 # Copyright (c) 2010, Eucalyptus Systems, Inc. | 2 # Copyright (c) 2010, Eucalyptus Systems, Inc. |
3 # | 3 # |
4 # Permission is hereby granted, free of charge, to any person obtaining a | 4 # Permission is hereby granted, free of charge, to any person obtaining a |
5 # copy of this software and associated documentation files (the | 5 # copy of this software and associated documentation files (the |
6 # "Software"), to deal in the Software without restriction, including | 6 # "Software"), to deal in the Software without restriction, including |
7 # without limitation the rights to use, copy, modify, merge, publish, dis- | 7 # without limitation the rights to use, copy, modify, merge, publish, dis- |
8 # tribute, sublicense, and/or sell copies of the Software, and to permit | 8 # tribute, sublicense, and/or sell copies of the Software, and to permit |
9 # persons to whom the Software is furnished to do so, subject to the fol- | 9 # persons to whom the Software is furnished to do so, subject to the fol- |
10 # lowing conditions: | 10 # lowing conditions: |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 self.part_number = int(value) | 95 self.part_number = int(value) |
96 elif name == 'LastModified': | 96 elif name == 'LastModified': |
97 self.last_modified = value | 97 self.last_modified = value |
98 elif name == 'ETag': | 98 elif name == 'ETag': |
99 self.etag = value | 99 self.etag = value |
100 elif name == 'Size': | 100 elif name == 'Size': |
101 self.size = int(value) | 101 self.size = int(value) |
102 else: | 102 else: |
103 setattr(self, name, value) | 103 setattr(self, name, value) |
104 | 104 |
105 def part_lister(mpupload, part_number_marker=''): | 105 def part_lister(mpupload, part_number_marker=None): |
106 """ | 106 """ |
107 A generator function for listing parts of a multipart upload. | 107 A generator function for listing parts of a multipart upload. |
108 """ | 108 """ |
109 more_results = True | 109 more_results = True |
110 part = None | 110 part = None |
111 while more_results: | 111 while more_results: |
112 parts = mpupload.get_all_parts(None, part_number_marker) | 112 parts = mpupload.get_all_parts(None, part_number_marker) |
113 for part in parts: | 113 for part in parts: |
114 yield part | 114 yield part |
115 part_number_marker = mpupload.next_part_number_marker | 115 part_number_marker = mpupload.next_part_number_marker |
(...skipping 16 matching lines...) Expand all Loading... |
132 self.part_number_marker = None | 132 self.part_number_marker = None |
133 self.next_part_number_marker = None | 133 self.next_part_number_marker = None |
134 self.max_parts = None | 134 self.max_parts = None |
135 self.is_truncated = False | 135 self.is_truncated = False |
136 self._parts = None | 136 self._parts = None |
137 | 137 |
138 def __repr__(self): | 138 def __repr__(self): |
139 return '<MultiPartUpload %s>' % self.key_name | 139 return '<MultiPartUpload %s>' % self.key_name |
140 | 140 |
141 def __iter__(self): | 141 def __iter__(self): |
142 return part_lister(self, part_number_marker=self.part_number_marker) | 142 return part_lister(self) |
143 | 143 |
144 def to_xml(self): | 144 def to_xml(self): |
145 self.get_all_parts() | 145 self.get_all_parts() |
146 s = '<CompleteMultipartUpload>\n' | 146 s = '<CompleteMultipartUpload>\n' |
147 for part in self: | 147 for part in self: |
148 s += ' <Part>\n' | 148 s += ' <Part>\n' |
149 s += ' <PartNumber>%d</PartNumber>\n' % part.part_number | 149 s += ' <PartNumber>%d</PartNumber>\n' % part.part_number |
150 s += ' <ETag>%s</ETag>\n' % part.etag | 150 s += ' <ETag>%s</ETag>\n' % part.etag |
151 s += ' </Part>\n' | 151 s += ' </Part>\n' |
152 s += '</CompleteMultipartUpload>' | 152 s += '</CompleteMultipartUpload>' |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 response = self.bucket.connection.make_request('GET', self.bucket.name, | 205 response = self.bucket.connection.make_request('GET', self.bucket.name, |
206 self.key_name, | 206 self.key_name, |
207 query_args=query_args) | 207 query_args=query_args) |
208 body = response.read() | 208 body = response.read() |
209 if response.status == 200: | 209 if response.status == 200: |
210 h = handler.XmlHandler(self, self) | 210 h = handler.XmlHandler(self, self) |
211 xml.sax.parseString(body, h) | 211 xml.sax.parseString(body, h) |
212 return self._parts | 212 return self._parts |
213 | 213 |
214 def upload_part_from_file(self, fp, part_num, headers=None, replace=True, | 214 def upload_part_from_file(self, fp, part_num, headers=None, replace=True, |
215 cb=None, num_cb=10, policy=None, md5=None, | 215 cb=None, num_cb=10, policy=None, md5=None): |
216 reduced_redundancy=False): | |
217 """ | 216 """ |
218 Upload another part of this MultiPart Upload. | 217 Upload another part of this MultiPart Upload. |
219 | 218 |
220 :type fp: file | 219 :type fp: file |
221 :param fp: The file object you want to upload. | 220 :param fp: The file object you want to upload. |
222 | 221 |
223 :type part_num: int | 222 :type part_num: int |
224 :param part_num: The number of this part. | 223 :param part_num: The number of this part. |
225 | 224 |
226 The other parameters are exactly as defined for the | 225 The other parameters are exactly as defined for the |
227 :class:`boto.s3.key.Key` set_contents_from_file method. | 226 :class:`boto.s3.key.Key` set_contents_from_file method. |
228 """ | 227 """ |
229 if part_num < 1: | 228 if part_num < 1: |
230 raise ValueError('Part numbers must be greater than zero') | 229 raise ValueError('Part numbers must be greater than zero') |
231 query_args = 'uploadId=%s&partNumber=%d' % (self.id, part_num) | 230 query_args = 'uploadId=%s&partNumber=%d' % (self.id, part_num) |
232 key = self.bucket.new_key(self.key_name) | 231 key = self.bucket.new_key(self.key_name) |
233 key.set_contents_from_file(fp, headers, replace, cb, num_cb, policy, | 232 key.set_contents_from_file(fp, headers, replace, cb, num_cb, policy, |
234 md5, reduced_redundancy, query_args) | 233 md5, reduced_redundancy=False, |
| 234 query_args=query_args) |
235 | 235 |
236 def complete_upload(self): | 236 def complete_upload(self): |
237 """ | 237 """ |
238 Complete the MultiPart Upload operation. This method should | 238 Complete the MultiPart Upload operation. This method should |
239 be called when all parts of the file have been successfully | 239 be called when all parts of the file have been successfully |
240 uploaded to S3. | 240 uploaded to S3. |
241 | 241 |
242 :rtype: :class:`boto.s3.multipart.CompletedMultiPartUpload` | 242 :rtype: :class:`boto.s3.multipart.CompletedMultiPartUpload` |
243 :returns: An object representing the completed upload. | 243 :returns: An object representing the completed upload. |
244 """ | 244 """ |
245 xml = self.to_xml() | 245 xml = self.to_xml() |
246 self.bucket.complete_multipart_upload(self.key_name, | 246 return self.bucket.complete_multipart_upload(self.key_name, |
247 self.id, xml) | 247 self.id, xml) |
248 | 248 |
249 def cancel_upload(self): | 249 def cancel_upload(self): |
250 """ | 250 """ |
251 Cancels a MultiPart Upload operation. The storage consumed by | 251 Cancels a MultiPart Upload operation. The storage consumed by |
252 any previously uploaded parts will be freed. However, if any | 252 any previously uploaded parts will be freed. However, if any |
253 part uploads are currently in progress, those part uploads | 253 part uploads are currently in progress, those part uploads |
254 might or might not succeed. As a result, it might be necessary | 254 might or might not succeed. As a result, it might be necessary |
255 to abort a given multipart upload multiple times in order to | 255 to abort a given multipart upload multiple times in order to |
256 completely free all storage consumed by all parts. | 256 completely free all storage consumed by all parts. |
257 """ | 257 """ |
258 self.bucket.cancel_multipart_upload(self.key_name, self.id) | 258 self.bucket.cancel_multipart_upload(self.key_name, self.id) |
259 | 259 |
260 | 260 |
OLD | NEW |