Skip to content
Snippets Groups Projects
pod_client.py 3.05 KiB
Newer Older
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import hashlib
import logging
import math
import os
import requests
import time

from .resource import API_URLS, Resource
logger = logging.getLogger('pod_client.resource')

    api_key = ''
    def __init__(self, host_url, api_key, site_id=1):
        self.host_url = host_url
        if not self.host_url:
            raise Exception('Pod host url required')
        self.api_key = api_key
        if not self.api_key:
            raise Exception('Pod api key required')
        for resource_name in API_URLS.keys():
            self.__dict__[resource_name] = Resource(self.host_url, self.api_key, resource_name, site_id)

    def chunked_upload(self, file_path, slug=None, progress_callback=None,
                       progress_data=None, check_md5=True, timeout=3600):
        url_prefix = '%s/api/' % self.host_url
        chunk_size = 1000000
        total_size = os.path.getsize(file_path)
        chunks_count = math.ceil(total_size / chunk_size)
        chunk_index = 0
        start_offset = 0
        end_offset = min(chunk_size, total_size) - 1
        data = dict()
        if check_md5:
            md5sum = hashlib.md5()
        begin = time.time()
        with open(file_path, 'rb') as file_object:
            while True:
                chunk = file_object.read(chunk_size)
                if not chunk:
                    break
                chunk_index += 1
                logger.debug('Uploading chunk %s/%s.', chunk_index, chunks_count)
                if check_md5:
                    md5sum.update(chunk)
                files = {'file': (os.path.basename(file_path), chunk)}
                headers = {'Content-Range': 'bytes %s-%s/%s' % (start_offset, end_offset, total_size)}
                response = requests.request('post', url_prefix + 'chunked_upload/', data=data, files=files, headers=headers, timeout=timeout)
                if response.status_code != 200:
                    raise Exception('Error {status_code}: "{text}"'.format(status_code=response.status_code, text=response.text))
                response = response.json()
                if progress_callback:
                    pdata = progress_data or dict()
                    progress_callback(0.9 * end_offset / total_size, **pdata)
                if 'upload_id' not in data:
                    data['upload_id'] = response['upload_id']
                start_offset += chunk_size
                end_offset = min(end_offset + chunk_size, total_size - 1)
        bandwidth = total_size * 8 / ((time.time() - begin) * 1000000)
        logger.debug('Upload finished, average bandwidth: %.2f Mbits/s', bandwidth)
        if check_md5:
            data['md5'] = md5sum.hexdigest()
        else:
            data['no_md5'] = 'yes'
        if slug:
            data['slug'] = slug
        requests.request('post', url_prefix + 'chunked_upload/complete/', data=data, timeout=timeout)
        if progress_callback:
            pdata = progress_data or dict()
            progress_callback(1., **pdata)
        return data['upload_id']