Beispiel #1
0
    def getfilelist(self, bucket, offset=0, limit=20, header=None):
        """
        获取空间中文件列表

        @param bucket: string类型,空间名称
        @param offset: integer类型,文件列表偏移位置
        @param limit: integer类型,返回文件数量
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """

        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')

        param = dict()
        param['Action'] = 'GetFileList'
        param['BucketName'] = bucket
        param['Offset'] = s(str(offset))
        param['Limit'] = s(str(limit))
        signature = self.__auth.bucket_signature(param)
        param['Signature'] = signature
        logger.info('start request the file list of bucket {0}'.format(bucket))
        return _bucket_request(UCLOUD_API_URL, param, header)
Beispiel #2
0
    def describebucket(self, bucket=None, offset=0, limit=10, header=None):
        """
        获取空间的信息,如果不提供空间名称,则获取所有空间的信息

        @param bucketname: string类型, 空间名称
        @param offset: integer类型, 起始空间编码,当提供空间名时无效
        @param limit: integer类型,获取空间数量,当提供具体空间名时无效
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """

        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')

        param = dict()
        param['Action'] = 'DescribeBucket'
        if bucket is not None:
            param['BucketName'] = bucket
        param['Offset'] = s(str(offset))
        param['Limit'] = s(str(limit))

        signature = self.__auth.bucket_signature(param)
        param['Signature'] = signature
        logger.info('start request the bucket {0} details'.format(bucket))
        return _bucket_request(UCLOUD_API_URL, param, header)
Beispiel #3
0
    def describebucket(self, bucket=None, offset=0, limit=10, header=None):
        """
        获取空间的信息,如果不提供空间名称,则获取所有空间的信息

        @param bucketname: string类型, 空间名称
        @param offset: integer类型, 起始空间编码,当提供空间名时无效
        @param limit: integer类型,获取空间数量,当提供具体空间名时无效
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """

        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')

        param = dict()
        param['Action'] = 'DescribeBucket'
        if bucket is not None:
            param['BucketName'] = bucket
        param['Offset'] = s(str(offset))
        param['Limit'] = s(str(limit))

        signature = self.__auth.bucket_signature(param)
        param['Signature'] = signature
        logger.info('start request the bucket {0} details'.format(bucket))
        return _bucket_request(UCLOUD_API_URL, param, header)
Beispiel #4
0
    def getfilelist(self, bucket, offset=0, limit=20, header=None):
        """
        获取空间中文件列表

        @param bucket: string类型,空间名称
        @param offset: integer类型,文件列表偏移位置
        @param limit: integer类型,返回文件数量
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """

        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')

        param = dict()
        param['Action'] = 'GetFileList'
        param['BucketName'] = bucket
        param['Offset'] = s(str(offset))
        param['Limit'] = s(str(limit))
        signature = self.__auth.bucket_signature(param)
        param['Signature'] = signature
        logger.info('start request the file list of bucket {0}'.format(bucket))
        return _bucket_request(UCLOUD_API_URL, param, header)
Beispiel #5
0
    def putfile(self, bucket, key, localfile, header=None):
        """
        upload localfile to bucket as key

        @param bucket: string类型,上传空间名称
        @param key:  string 类型,上传文件在空间中的名称
        @param localfile: string类型,本地文件名称
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')
        mime_type = s(Mimetype.from_file(localfile))
        file_size = os.path.getsize(localfile)
        header['Content-Type'] = mime_type
        authorization = self.authorization('put', bucket, key, header)
        header['Authorization'] = authorization
        header['Content-Length'] = file_size
        url = ufile_put_url(bucket, key)
        logger.info('start put file {0} to bucket {1} as {2}'.format(localfile, bucket, key))
        logger.info('put UFile url: {0}'.format(url))
        logger.info('request header:\n{0}'.format(json.dumps(header, indent=4)))
        return _put_file(url, header, localfile)
Beispiel #6
0
    def resumeuploadfile(self, retrycount=3, retryinterval=5, bucket=None, key=None, uploadid=None, blocksize=None, etaglist=None, localfile=None, pausepartnumber=None, mime_type=None, header=None):
        """
        断点续传失败的本地文件分片
        可以在调用uploadfile失败后重新续传,也可以通过传递所有需要的参数续传

        @param retrycount: integer 类型,分片重传次数
        @param retryinterval: integer 类型,同个分片失败重传间隔,单位秒
        @param bucket: string类型, 空间名称
        @param key: string类型,文件或数据在空间中的名称
        @param uploadid: string类型,初始化分片获得的uploadid
        @param blocksize: integer类型,分片大小
        @param etaglist: list类型,元素为已经上传成功的分片的etag
        @param pausepartnumber: integer类型,第一个失败分片的编号(编号从0开始)
        @param localfile: string类型,本地文件名称
        @param mime_type: string类型,上传数据的MIME类型
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if localfile:
            self.__localfile = localfile
        if blocksize:
            self.blocksize = blocksize
        if pausepartnumber:
            self.pausepartnumber = pausepartnumber
        if mime_type:
            self.__mimetype = mime_type
        else:
            mime_type = s(Mimetype.from_file(self.__localfile))
        with open(self.__localfile, 'rb') as fd:
            fd.seek(self.pausepartnumber * self.blocksize, os.SEEK_SET)
            return self.resumeuploadstream(retrycount, retryinterval, bucket, key, uploadid, blocksize, etaglist, fd, pausepartnumber, mime_type, header)
Beispiel #7
0
    def private_download_url(self, bucket, key, expires=config.get_default('expires'), header=None, internal=False):
        """
        从私有空间下载文件的url

        @param bucket: string类型, 空间名称
        @param key: string类型,下载数据在空间中的名称
        @param expires:  integer类型, 下载链接有效时间,单位为秒
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return string, 从私有空间下载文件和数据的url
        """
        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')
        if expires is not None:
            expires += int(time.time())
            header['Expires'] = s(str(expires))
        signature = self.signature(bucket, key, 'get', header)
        query = { 'UCloudPublicKey': self._public_key(),
                  'Expires': str(expires),
                  'Signature': signature }
        query_str = urllib.urlencode(query)
        if internal:
            return 'http://{0}{1}/{2}?{3}'.format(bucket, config.get_default('download_suffix'), key, query_str)
        else:
            return 'http://{0}{1}/{2}?UCloudPublicKey={3}&Expires={4}&Signature={5}'.format(bucket, config.get_default('download_suffix'), key, self._public_key(), str(expires), signature)
Beispiel #8
0
    def private_download_url(self, bucket, key, expires=config.get_default('expires'), header=None, internal=False):
        """
        从私有空间下载文件的url

        @param bucket: string类型, 空间名称
        @param key: string类型,下载数据在空间中的名称
        @param expires:  integer类型, 下载链接有效时间,单位为秒
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return string, 从私有空间下载文件和数据的url
        """
        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')
        if expires is not None:
            expires += int(time.time())
            header['Expires'] = s(str(expires))
        signature = self.signature(bucket, key, 'get', header)
        query = { 'UCloudPublicKey': self._public_key(),
                  'Expires': str(expires),
                  'Signature': signature }
        query_str = urllib.urlencode(query)
        if internal:
            return 'http://{0}{1}/{2}?{3}'.format(bucket, config.get_default('download_suffix'), key, query_str)
        else:
            return 'http://{0}{1}/{2}?UCloudPublicKey={3}&Expires={4}&Signature={5}'.format(bucket, config.get_default('download_suffix'), key, self._public_key(), str(expires), signature)
Beispiel #9
0
    def list(self, bucket, marker, limit, header=None):
        """

        @param bucket: string类型,上传空间名称
        @param marker: string类型,上一次查找返回的位置信息,本次列表起始查找的文件名,默认为空
        @param limit:  integer类型, 每次列表返回的最大文件个数,服务端限制为1000,最新限制值请参考官方文档
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')
        mime_type = s(Mimetype.from_file(localfile))
        file_size = os.path.getsize(localfile)
        header['Content-Type'] = mime_type
        authorization = self.authorization('put', bucket, key, header)
        header['Authorization'] = authorization
        header['Content-Length'] = str(file_size)
        url = ufile_put_url(bucket, key)
        logger.info('start put file {0} to bucket {1} as {2}'.format(localfile, bucket, key))
        logger.info('put UFile url: {0}'.format(url))
        logger.info('request header:\n{0}'.format(json.dumps(header, indent=4)))
        return _put_file(url, header, localfile)
Beispiel #10
0
    def putfile(self, bucket, key, localfile, header=None):
        """
        upload localfile to bucket as key

        @param bucket: string类型,上传空间名称
        @param key:  string 类型,上传文件在空间中的名称
        @param localfile: string类型,本地文件名称
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')
        mime_type = s(Mimetype.from_file(localfile))
        file_size = os.path.getsize(localfile)
        header['Content-Type'] = mime_type
        authorization = self.authorization('put', bucket, key, header)
        header['Authorization'] = authorization
        header['Content-Length'] = file_size
        url = ufile_put_url(bucket, key)
        logger.info('start put file {0} to bucket {1} as {2}'.format(
            localfile, bucket, key))
        logger.info('put UFile url: {0}'.format(url))
        logger.info('request header:\n{0}'.format(json.dumps(header,
                                                             indent=4)))
        return _put_file(url, header, localfile)
Beispiel #11
0
    def getfilelist(self,
                    bucket,
                    prefix=None,
                    marker=None,
                    limit=None,
                    header=None):
        """
        获取bucket下的文件列表

        @param bucket: string 类型,空间名称
        @param prefix: string 类型,文件前缀, 默认为空字符串
        @param marker: string 类型,文件列表起始位置, 默认为空字符串
        @param limit: integer 类型,文件列表数目, 默认为20
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if header is None:
            header = dict()
        else:
            _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')

        header['Content-Length'] = 0
        authorization = self.authorization('get', bucket, '', header)
        header['Authorization'] = authorization
        param = dict()
        if marker is not None and (isinstance(marker, str)
                                   or isinstance(marker, unicode)):
            param['marker'] = s(marker)
        if prefix is not None and (isinstance(prefix, str)
                                   or isinstance(prefix, unicode)):
            param['prefix'] = s(prefix)
        if limit is not None and isinstance(limit, int):
            param['limit'] = s(str(limit))
        info_message = ''.join([
            'start get file list from bucket {0}'.format(bucket),
            '' if marker is None else ', marker: {0}'.format(
                marker if isinstance(marker, str) else marker.encode('utf-8')),
            '' if limit is None else ', limit: {0}'.format(limit),
            '' if prefix is None else ', prefix: {0}'.format(prefix)
        ])
        logger.info(info_message)
        url = ufile_getfilelist_url(bucket)
        return _getfilelist(url, header, param)
Beispiel #12
0
    def uploadfile(self, bucket, key, localfile, retrycount=3, retryinterval=5, header=None):
        """
        分片上传本地文件到空间

        @param bucket: string类型,空间名称
        @param key: string类型,文件在空间中的名称
        @param localfile: string 类型,本地文件名称
        @param retrycount: integer 类型,分片重传次数
        @param retryinterval: integer 类型,同个分片失败重传间隔,单位秒
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        self.__localfile = localfile
        mime_type = s(Mimetype.from_file(self.__localfile))
        with open(localfile, 'rb') as fd:
            return self.uploadstream(bucket, key, fd, retrycount, retryinterval, mime_type, header)
Beispiel #13
0
    def resumeuploadfile(self,
                         retrycount=3,
                         retryinterval=5,
                         bucket=None,
                         key=None,
                         uploadid=None,
                         blocksize=None,
                         etaglist=None,
                         localfile=None,
                         pausepartnumber=None,
                         mime_type=None,
                         header=None):
        """
        断点续传失败的本地文件分片
        可以在调用uploadfile失败后重新续传,也可以通过传递所有需要的参数续传

        @param retrycount: integer 类型,分片重传次数
        @param retryinterval: integer 类型,同个分片失败重传间隔,单位秒
        @param bucket: string类型, 空间名称
        @param key: string类型,文件或数据在空间中的名称
        @param uploadid: string类型,初始化分片获得的uploadid
        @param blocksize: integer类型,分片大小
        @param etaglist: list类型,元素为已经上传成功的分片的etag
        @param pausepartnumber: integer类型,第一个失败分片的编号(编号从0开始)
        @param localfile: string类型,本地文件名称
        @param mime_type: string类型,上传数据的MIME类型
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if localfile:
            self.__localfile = localfile
        if blocksize:
            self.blocksize = blocksize
        if pausepartnumber:
            self.pausepartnumber = pausepartnumber
        if mime_type:
            self.__mimetype = mime_type
        else:
            mime_type = s(Mimetype.from_file(self.__localfile))
        with open(self.__localfile, 'rb') as fd:
            fd.seek(self.pausepartnumber * self.blocksize, os.SEEK_SET)
            return self.resumeuploadstream(retrycount, retryinterval, bucket,
                                           key, uploadid, blocksize, etaglist,
                                           fd, pausepartnumber, mime_type,
                                           header)
Beispiel #14
0
    def postfile(self, bucket, key, localfile, header=None):
        """
        表单上传文件到UFile空间

        @param bucket: string类型,上传空间名称
        @param key:  string 类型,上传文件在空间中的名称
        @param localfile: string类型,本地文件名称
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if header is None:
            header = dict()
        _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')
        mime_type = s(Mimetype.from_file(localfile))

        # update the request header content-type
        boundary = self.__make_boundary()
        header['Content-Type'] = 'multipart/form-data; boundary={0}'.format(
            boundary)

        # form fields
        authorization = self.authorization('post', bucket, key, header,
                                           mime_type)
        fields = dict()
        fields['FileName'] = key
        fields['Authorization'] = authorization
        with open(localfile, 'rb') as stream:
            postdata = self.__make_postbody(boundary, fields, stream,
                                            mime_type, localfile)

        # update the request header content-length
        header['Content-Length'] = str(len(postdata))

        # post url
        url = ufile_post_url(bucket)

        # start post file
        logger.info('start post file {0} to bucket {1} as {2}'.format(
            localfile, bucket, key))
        logger.info('post url is {0}'.format(url))

        return _post_file(url, header, postdata)
Beispiel #15
0
    def postfile(self, bucket, key, localfile, header=None):
        """
        表单上传文件到UFile空间

        @param bucket: string类型,上传空间名称
        @param key:  string 类型,上传文件在空间中的名称
        @param localfile: string类型,本地文件名称
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        if header is None:
            header = dict()
        _check_dict(header)
        if "User-Agent" not in header:
            header["User-Agent"] = config.get_default("user_agent")
        mime_type = s(Mimetype.from_file(localfile))

        # update the request header content-type
        boundary = self.__make_boundary()
        header["Content-Type"] = "multipart/form-data; boundary={0}".format(boundary)

        # form fields
        authorization = self.authorization("post", bucket, key, header, mime_type)
        fields = dict()
        fields["FileName"] = key
        fields["Authorization"] = authorization
        with open(localfile, "rb") as stream:
            postdata = self.__make_postbody(boundary, fields, stream, mime_type, localfile)

        # update the request header content-length
        header["Content-Length"] = len(postdata)

        # post url
        url = ufile_post_url(bucket)

        # start post file
        logger.info("start post file {0} to bucket {1} as {2}".format(localfile, bucket, key))
        logger.info("post url is {0}".format(url))

        return _post_file(url, header, postdata)
Beispiel #16
0
    def uploadhit(self, bucket, key, localfile, header=None):
        """
        尝试秒传文件到UFile空间

        @param bucket: string类型,上传空间名称
        @param key:  string 类型,上传文件在空间中的名称
        @param localfile: string类型,本地文件名称
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """

        if header is None:
            header = dict()
        _check_dict(header)
        if 'User-Agent' not in header:
            header['User-Agent'] = config.get_default('user_agent')

        filesize = os.path.getsize(localfile)
        fileetags = file_etag(localfile, BLOCKSIZE)
        mimetype = s(Mimetype.from_file(localfile))

        # update request header
        header['Content-Type'] = mimetype
        header['Content-Length'] = 0
        authorization = self.authorization('post', bucket, key, header)
        header['Authorization'] = authorization

        # parameter

        params = {'Hash': fileetags,
                  'FileName': key,
                  'FileSize': filesize}

        url = ufile_uploadhit_url(bucket)

        logger.info('start upload hit localfile {0} as {1} in bucket {2}'.format(localfile, key, bucket))
        logger.info('request url: {0}'.format(url))

        return _uploadhit_file(url, header, params)
Beispiel #17
0
    def uploadfile(self,
                   bucket,
                   key,
                   localfile,
                   retrycount=3,
                   retryinterval=5,
                   header=None):
        """
        分片上传本地文件到空间

        @param bucket: string类型,空间名称
        @param key: string类型,文件在空间中的名称
        @param localfile: string 类型,本地文件名称
        @param retrycount: integer 类型,分片重传次数
        @param retryinterval: integer 类型,同个分片失败重传间隔,单位秒
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        self.__localfile = localfile
        mime_type = s(Mimetype.from_file(self.__localfile))
        with open(localfile, 'rb') as fd:
            return self.uploadstream(bucket, key, fd, retrycount,
                                     retryinterval, mime_type, header)
Beispiel #18
0
    def uploadstream(self, bucket, key, stream, retrycount=3, retryinterval=5, mime_type=None, header=None):
        """
        分片上传二进制数据流到UFile空间

        @param bucket: 空间名称
        @param key: 上传数据在空间中的名称
        @param stream: file-like 对象或者二进制数据流
        @param mime_type: 上传数据的MIME类型
        @param retrycount: integer 类型,分片重传次数
        @param retryinterval: integer 类型,同个分片失败重传间隔,单位秒
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        self.__bucket = bucket
        self.__key = key
        self.etaglist = []
        self.uploadid = None
        self.blocksize = None
        self.__header = header
        self.__stream = stream
        self.pausepartnumber = 0
        if self.__header is None:
            self.__header = dict()
        else:
            _check_dict(self.__header)
        if 'User-Agent' not in self.__header:
            self.__header['User-Agent'] = config.get_default('user_agent')

        # initial sharding request
        ret, resp = self.__initialsharding()
        if resp.ok():
            self.uploadid = ret.get('UploadId')
            self.blocksize = ret.get('BlkSize')
            logger.info('multipart upload id: {0}'.format(self.uploadid))
        else:
            logger.error('multipar upload init failed. error message: {0}'.format(resp.error))
            return ret, resp

        # mulitple sharding upload
        if mime_type is None:
            if hasattr(self.__stream, 'seek') and hasattr(self.__stream, 'read'):
                self.__mimetype = s(Mimetype.from_buffer(self.__stream.read(1024)))
                self.__stream.seek(0, os.SEEK_SET)
            else:
                self.__mimetype = 'application/octec-stream'
        else:
            self.__mimetype = mime_type

        self.__header['Content-Type'] = self.__mimetype
        authorization = self.authorization('put', self.__bucket, self.__key, self.__header)
        self.__header['Authorization'] = authorization

        for data in _file_iter(self.__stream, self.blocksize):
            url = shardingupload_url(self.__bucket, self.__key, self.uploadid, self.pausepartnumber)
            ret = None
            resp = None
            for index in range(retrycount):
                logger.info('try {0} time sharding upload sharding {1}'.format(index + 1, self.pausepartnumber))
                logger.info('sharding url:{0}'.format(url))
                ret, resp = _shardingupload(url, data, self.__header)
                if not resp.ok():
                    logger.error('failed {0} time when upload sharding {1}.error message: {2}, uploadid: {3}'.format(index + 1, self.pausepartnumber, resp.error, self.uploadid))
                    if index < retrycount - 1:
                        time.sleep(retryinterval)
                else:
                    break
            if not resp.ok():
                logger.error('upload sharding {0} failed. uploadid: {1}'.format(self.pausepartnumber, self.uploadid))
                return ret, resp
            logger.info('upload sharding {0} succeed.etag:{1}, uploadid: {2}'.format(self.pausepartnumber, resp.etag, self.uploadid))
            self.pausepartnumber += 1
            self.etaglist.append(resp.etag)
        logger.info('start finish sharding request.')
        ret, resp = self.__finishupload()
        if not resp.ok():
            logger.error('multipart upload failed. uploadid:{0}, pausepartnumber: {1}, key: {2} FAIL!!!'.format(self.uploadid, self.pausepartnumber, self.__key))
        else:
            logger.info('mulitpart upload succeed. uploadid: {0}, key: {1} SUCCEED!!!'.format(self.uploadid, self.__key))
        return ret, resp
Beispiel #19
0
    def uploadstream(self,
                     bucket,
                     key,
                     stream,
                     retrycount=3,
                     retryinterval=5,
                     mime_type=None,
                     header=None):
        """
        分片上传二进制数据流到UFile空间

        @param bucket: 空间名称
        @param key: 上传数据在空间中的名称
        @param stream: file-like 对象或者二进制数据流
        @param mime_type: 上传数据的MIME类型
        @param retrycount: integer 类型,分片重传次数
        @param retryinterval: integer 类型,同个分片失败重传间隔,单位秒
        @param header: dict类型,http 请求header,键值对类型分别为string,比如{'User-Agent': 'Google Chrome'}
        @return ret: 如果http状态码为[200, 204, 206]之一则返回None,否则如果服务器返回json信息则返回dict类型,键值对类型分别为string, unicode string类型,否则返回空的dict
        @return  ResponseInfo: 响应的具体信息,UCloud UFile 服务器返回信息或者网络链接异常
        """
        self.__bucket = bucket
        self.__key = key
        self.etaglist = []
        self.uploadid = None
        self.blocksize = None
        self.__header = header
        self.__stream = stream
        self.pausepartnumber = 0
        if self.__header is None:
            self.__header = dict()
        else:
            _check_dict(self.__header)
        if 'User-Agent' not in self.__header:
            self.__header['User-Agent'] = config.get_default('user_agent')

        # initial sharding request
        ret, resp = self.__initialsharding()
        if resp.ok():
            self.uploadid = ret.get('UploadId')
            self.blocksize = ret.get('BlkSize')
            logger.info('multipart upload id: {0}'.format(self.uploadid))
        else:
            logger.error(
                'multipar upload init failed. error message: {0}'.format(
                    resp.error))
            return ret, resp

        # mulitple sharding upload
        if mime_type is None:
            if hasattr(self.__stream, 'seek') and hasattr(
                    self.__stream, 'read'):
                self.__mimetype = s(
                    Mimetype.from_buffer(self.__stream.read(1024)))
                self.__stream.seek(0, os.SEEK_SET)
            else:
                self.__mimetype = 'application/octec-stream'
        else:
            self.__mimetype = mime_type

        self.__header['Content-Type'] = self.__mimetype
        authorization = self.authorization('put', self.__bucket, self.__key,
                                           self.__header)
        self.__header['Authorization'] = authorization

        for data in _file_iter(self.__stream, self.blocksize):
            url = shardingupload_url(self.__bucket, self.__key, self.uploadid,
                                     self.pausepartnumber)
            ret = None
            resp = None
            for index in range(retrycount):
                logger.info('try {0} time sharding upload sharding {1}'.format(
                    index + 1, self.pausepartnumber))
                logger.info('sharding url:{0}'.format(url))
                ret, resp = _shardingupload(url, data, self.__header)
                if not resp.ok():
                    logger.error(
                        'failed {0} time when upload sharding {1}.error message: {2}, uploadid: {3}'
                        .format(index + 1, self.pausepartnumber, resp.error,
                                self.uploadid))
                    if index < retrycount - 1:
                        time.sleep(retryinterval)
                else:
                    break
            if not resp.ok():
                logger.error(
                    'upload sharding {0} failed. uploadid: {1}'.format(
                        self.pausepartnumber, self.uploadid))
                return ret, resp
            logger.info(
                'upload sharding {0} succeed.etag:{1}, uploadid: {2}'.format(
                    self.pausepartnumber, resp.etag, self.uploadid))
            self.pausepartnumber += 1
            self.etaglist.append(resp.etag)
        logger.info('start finish sharding request.')
        ret, resp = self.__finishupload()
        if not resp.ok():
            logger.error(
                'multipart upload failed. uploadid:{0}, pausepartnumber: {1}, key: {2} FAIL!!!'
                .format(self.uploadid, self.pausepartnumber, self.__key))
        else:
            logger.info(
                'mulitpart upload succeed. uploadid: {0}, key: {1} SUCCEED!!!'.
                format(self.uploadid, self.__key))
        return ret, resp