Copy a remote file chunk http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadUploadPart.html http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html
(self, seq, offset, chunk_size, labels, remote_status=None)
| 244 | return response |
| 245 | |
| 246 | def copy_part(self, seq, offset, chunk_size, labels, remote_status=None): |
| 247 | """ |
| 248 | Copy a remote file chunk |
| 249 | http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadUploadPart.html |
| 250 | http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html |
| 251 | """ |
| 252 | debug("Copying part %i of %r (%s bytes)" % (seq, self.upload_id, |
| 253 | chunk_size)) |
| 254 | |
| 255 | # set up headers with copy-params. |
| 256 | # Examples: |
| 257 | # x-amz-copy-source: /source_bucket/sourceObject |
| 258 | # x-amz-copy-source-range:bytes=first-last |
| 259 | # x-amz-copy-source-if-match: etag |
| 260 | # x-amz-copy-source-if-none-match: etag |
| 261 | # x-amz-copy-source-if-unmodified-since: time_stamp |
| 262 | # x-amz-copy-source-if-modified-since: time_stamp |
| 263 | headers = { |
| 264 | "x-amz-copy-source": s3_quote("/%s/%s" % (self.src_uri.bucket(), |
| 265 | self.src_uri.object()), |
| 266 | quote_backslashes=False, |
| 267 | unicode_output=True) |
| 268 | } |
| 269 | |
| 270 | # byte range, with end byte included. A 10 byte file has bytes=0-9 |
| 271 | headers["x-amz-copy-source-range"] = \ |
| 272 | "bytes=%d-%d" % (offset, (offset + chunk_size - 1)) |
| 273 | |
| 274 | query_string_params = {'partNumber': '%s' % seq, |
| 275 | 'uploadId': self.upload_id} |
| 276 | request = self.s3.create_request("OBJECT_PUT", uri=self.dst_uri, |
| 277 | headers=headers, |
| 278 | uri_params=query_string_params) |
| 279 | |
| 280 | labels[u'action'] = u'remote copy' |
| 281 | response = self.s3.send_request_with_progress(request, labels, |
| 282 | chunk_size) |
| 283 | |
| 284 | # NOTE: Amazon sends whitespace while upload progresses, which |
| 285 | # accumulates in response body and seems to confuse XML parser. |
| 286 | # Strip newlines to find ETag in XML response data |
| 287 | #data = response["data"].replace("\n", '') |
| 288 | self.parts[seq] = getTextFromXml(response['data'], "ETag") or '' |
| 289 | |
| 290 | return response |
| 291 | |
| 292 | def complete_multipart_upload(self): |
| 293 | """ |
no test coverage detected