Exemple #1
0
 def upload(self, fp, size=None, progress_callback=None):
     """
     Upload file contents.
     fp can be any file-like object, but if you don't specify it's size in advance it must support tell and seek methods.
     Progress callback is optional - if provided, it should match signature of ProgressCallbacks.upload_progress
     """
     if isinstance(fp, six.binary_type):
         fp = six.BytesIO(fp)
     if size is None:
         size = base.get_file_size(fp)
     if size < self._upload_chunk_size:
         # simple, one request upload
         retries = max(self._upload_retries, 1)
         while retries > 0:
             url = self._client.get_url(self._url_template_content,
                                        path=self.path)
             chunk = base._FileChunk(fp, 0, size)
             r = self._client.POST(url,
                                   data=chunk,
                                   headers={'Content-length': str(size)})
             exc.default.check_response(r)
             server_sha = r.headers['X-Sha512-Checksum']
             our_sha = chunk.sha.hexdigest()
             if server_sha == our_sha:
                 break
             retries -= 1
             # TODO: retry network errors too
         if retries == 0:
             raise exc.ChecksumError("Failed to upload file", {})
     else:  # chunked upload
         return self._chunked_upload(fp, size, progress_callback)
Exemple #2
0
 def _chunked_upload(self, fp, size, progress_callback):
     url = self._client.get_url(self._url_template_content_chunked,
                                path=self.path)
     chunks = list(
         base.split_file_into_chunks(
             fp, size, self._upload_chunk_size))  # need count of chunks
     chunk_count = len(chunks)
     headers = {}
     for chunk_number, chunk in enumerate(chunks, 1):  # count from 1 not 0
         headers['x-egnyte-chunk-num'] = "%d" % chunk_number
         headers['content-length'] = str(chunk.size)
         if chunk_number == chunk_count:  # last chunk
             headers['x-egnyte-last-chunk'] = "true"
         retries = max(self._upload_retries, 1)
         while retries > 0:
             r = self._client.POST(url, data=chunk, headers=headers)
             server_sha = r.headers['x-egnyte-chunk-sha512-checksum']
             our_sha = chunk.sha.hexdigest()
             if server_sha == our_sha:
                 break
             retries -= 1
             # TODO: retry network errors too
             # TODO: refactor common parts of chunked and standard upload
         if retries == 0:
             raise exc.ChecksumError("Failed to upload file chunk", {
                 "chunk_number": chunk_number,
                 "start_position": chunk.position
             })
         exc.default.check_response(r)
         if chunk_number == 1:
             headers['x-egnyte-upload-id'] = r.headers['x-egnyte-upload-id']
         if progress_callback is not None:
             progress_callback(self, size,
                               chunk_number * self._upload_chunk_size)
Exemple #3
0
 def _upload_single_chunk(self,
                          url,
                          chunk_number,
                          chunk,
                          size,
                          chunksize_mb,
                          progress_callback,
                          is_last_chunk=False,
                          upload_id=None):
     headers = {}
     headers['x-egnyte-chunk-num'] = "%d" % chunk_number
     headers['content-length'] = chunk.size
     if is_last_chunk:
         headers['x-egnyte-last-chunk'] = "true"
     if upload_id:
         headers['x-egnyte-upload-id'] = upload_id
     retries = max(self._upload_retries, 1)
     while retries > 0:
         r = self._client.POST(url, data=chunk, headers=headers)
         server_sha = r.headers['x-egnyte-chunk-sha512-checksum']
         our_sha = chunk.sha.hexdigest()
         if server_sha == our_sha:
             break
         retries -= 1
         # TODO: retry network errors too
         # TODO: refactor common parts of chunked and standard upload
     if retries == 0:
         raise exc.ChecksumError("Failed to upload file chunk", {
             "chunk_number": chunk_number,
             "start_position": chunk.position
         })
     exc.default.check_response(r)
     if progress_callback is not None:
         progress_callback(self, size,
                           chunk_number * chunksize_mb * MEGABYTES)
     return r.headers