# Initialise the HTTP client
self.http = http.Client(baseurl=huburl)
+ @property
+ def _request_args(self):
+ """
+ Arguments sent with each request
+ """
+ return {
+ "auth" : (self.username, self.password),
+ }
+
def _request(self, *args, **kwargs):
"""
Wrapper function around the HTTP Client request()
function that adds authentication, etc.
"""
- kwargs.update({
- "auth" : (self.username, self.password),
- })
+ kwargs.update(self._request_args)
return self.http.request(*args, **kwargs)
+ def _upload(self, *args, **kwargs):
+ kwargs.update(self._request_args)
+
+ return self.http.upload(*args, **kwargs)
+
# Test functions
def test(self):
# File uploads
def upload_file(self, path):
- uploader = FileUploader(self, path)
-
- return uploader.upload()
-
-
-class FileUploader(object):
- """
- Handles file uploads to the Pakfire Hub
- """
- def __init__(self, hub, path):
- self.hub = hub
- self.path = path
-
- @property
- def filename(self):
- """
- Returns the basename of the uploaded file
- """
- return os.path.basename(self.path)
-
- @property
- def filesize(self):
- """
- The filesize of the uploaded file
- """
- return os.path.getsize(self.path)
-
- @staticmethod
- def _make_checksum(algo, path):
- h = hashlib.new(algo)
-
- with open(path, "rb") as f:
- while True:
- buf = f.read(CHUNK_SIZE)
- if not buf:
- break
-
- h.update(buf)
-
- return h.hexdigest()
-
- def _get_upload_id(self):
- """
- Sends some basic information to the hub
- and requests an upload id.
- """
+ # Send some basic information to the hub
+ # and request an upload ID
data = {
- "filename" : self.filename,
- "filesize" : self.filesize,
- "hash" : self._make_checksum("sha1", self.path),
+ "filename" : os.path.basename(path),
+ "filesize" : os.path.getsize(path),
}
+ upload_id = self._request("/uploads/create", method="GET",
+ decode="ascii", data=data)
- return self.hub._request("/uploads/create", method="GET", decode="ascii", data=data)
-
- def _send_chunk(self, upload_id, chunk):
- """
- Sends a chunk at a time
- """
- # Compute the SHA512 checksum of this chunk
- h = hashlib.new("sha512")
- h.update(chunk)
-
- # Encode data in base64
- data = base64.b64encode(chunk)
-
- # Send chunk to the server
- self.hub._request("/uploads/%s/sendchunk" % upload_id, method="POST",
- data={ "chksum" : h.hexdigest(), "data" : data })
-
- return len(chunk)
-
- def upload(self):
- """
- Main function which runs the upload
- """
- # Borrow progressbar from downloader
- p = self.hub.http._make_progressbar(message=self.filename, value_max=self.filesize)
-
- with p:
- # Request an upload ID
- upload_id = self._get_upload_id()
- assert upload_id
-
- log.debug("Starting upload with id %s" % upload_id)
-
- # Initial chunk size
- chunk_size = CHUNK_SIZE
-
- try:
- with open(self.path, "rb") as f:
- while True:
- chunk = f.read(chunk_size)
- if not chunk:
- break
-
- # Save the time when we started to send this bit
- time_started = time.time()
-
- # Send the chunk to the server
- self._send_chunk(upload_id, chunk)
-
- # Determine the size of the next chunk
- duration = time_started - time.time()
- chunk_size = math.ceil(chunk_size / duration)
-
- # Never let chunk_size drop under CHUNK_SIZE
- if chunk_size < CHUNK_SIZE:
- chunk_size = CHUNK_SIZE
-
- # Update progressbar
- p.increment(len(chunk))
-
- # Catch any unhandled exception here, tell the hub to delete the
- # file and raise the original exception
- except Exception as e:
- self.hub._request("/uploads/%s/destroy" % upload_id)
-
- raise
+ log.debug("Upload ID: %s" % upload_id)
- # If all went well, we finish the upload
- else:
- self.hub._request("/uploads/%s/finished" % upload_id)
+ # Upload the data
+ self._upload("/uploads/stream?id=%s" % upload_id, path)
- # Return the upload ID if the upload was successful
- return upload_id
+ return upload_id
\ No newline at end of file