swiftly/cli/put.py
def cli_put_object(context, path):
    """
    Performs a PUT on the object.

    See :py:mod:`swiftly.cli.put` for context usage information.

    See :py:class:`CLIPut` for more information.
    """
    if context.different and context.encrypt:
        raise ReturnCode(
            'context.different will not work properly with context.encrypt '
            'since encryption may change the object size')
    put_headers = dict(context.headers)
    if context.empty:
        body = ''
        put_headers['content-length'] = '0'
    elif not context.input_ or context.input_ == '-':
        stdin = context.io_manager.get_stdin()

        if context.stdin_segmentation:
            def reader():
                while True:
                    chunk = stdin.read(65536)
                    if chunk:
                        yield chunk
                    else:
                        return

            segment_body = FileLikeIter(reader(), context.segment_size)

            prefix = _create_container(context, path, time.time(), 0)
            new_context = context.copy()
            new_context.stdin_segmentation = False
            new_context.stdin = segment_body
            new_context.headers = dict(context.headers)
            segment_n = 0
            path2info = {}
            while not segment_body.is_empty():
                segment_path = _get_segment_path(prefix, segment_n)
                etag = cli_put_object(new_context, segment_path)
                size = segment_body.limit - segment_body.left
                path2info[segment_path] = (size, etag)

                segment_body.reset_limit()
                segment_n += 1
            body = _get_manifest_body(context, prefix, path2info, put_headers)
        else:
            if hasattr(context, 'stdin'):
                body = context.stdin
            else:
                body = stdin
    elif context.seek is not None:
        if context.encrypt:
            raise ReturnCode(
                'putting object %r: Cannot use encryption and context.seek' %
                path)
        body = open(context.input_, 'rb')
        body.seek(context.seek)
    else:
        l_mtime = os.path.getmtime(context.input_)
        l_size = os.path.getsize(context.input_)
        put_headers['content-length'] = str(l_size)
        if context.newer or context.different:
            r_mtime = None
            r_size = None
            with context.client_manager.with_client() as client:
                status, reason, headers, contents = client.head_object(
                    *path.split('/', 1), headers=context.headers,
                    query=context.query, cdn=context.cdn)
                if hasattr(contents, 'read'):
                    contents.read()
            if status // 100 == 2:
                r_mtime = headers.get('x-object-meta-mtime')
                if r_mtime:
                    try:
                        r_mtime = float(r_mtime)
                    except ValueError:
                        r_mtime = None
                r_size = headers.get('content-length')
                if r_size:
                    try:
                        r_size = int(r_size)
                    except ValueError:
                        r_size = None
            elif status != 404:
                raise ReturnCode(
                    'could not head %r for conditional check; skipping put: '
                    '%s %s' % (path, status, reason))
            if context.newer and r_mtime is not None or l_mtime <= r_mtime:
                return
            if context.different and r_mtime is not None and \
                    l_mtime == r_mtime and r_size is not None and \
                    l_size == r_size:
                return
        put_headers['x-object-meta-mtime'] = '%f' % l_mtime
        size = os.path.getsize(context.input_)
        if size > context.segment_size:
            if context.encrypt:
                raise ReturnCode(
                    'putting object %r: Cannot use encryption for objects '
                    'greater than the segment size' % path)
            prefix = _create_container(context, path, l_mtime, size)
            conc = Concurrency(context.concurrency)
            start = 0
            segment = 0
            path2info = {}
            while start < size:
                new_context = context.copy()
                new_context.headers = dict(context.headers)
                new_context.headers['content-length'] = str(min(
                    size - start, context.segment_size))
                new_context.seek = start
                new_path = _get_segment_path(prefix, segment)
                for (ident, (exc_type, exc_value, exc_tb, result)) in \
                        six.iteritems(conc.get_results()):
                    if exc_value:
                        conc.join()
                        raise exc_value
                    path2info[ident] = result
                conc.spawn(
                    new_path, cli_put_object, new_context, new_path)
                segment += 1
                start += context.segment_size
            conc.join()
            for (ident, (exc_type, exc_value, exc_tb, result)) in \
                    six.iteritems(conc.get_results()):
                if exc_value:
                    raise exc_value
                path2info[ident] = result
            body = _get_manifest_body(context, prefix, path2info, put_headers)
        else:
            body = open(context.input_, 'rb')
    with context.client_manager.with_client() as client:
        if context.encrypt:
            content_length = put_headers.get('content-length')
            if content_length:
                content_length = int(content_length)
            if hasattr(body, 'read'):
                body = FileLikeIter(aes_encrypt(
                    context.encrypt, body, preamble=AES256CBC,
                    chunk_size=getattr(client, 'chunk_size', 65536),
                    content_length=content_length))
            else:
                body = FileLikeIter(aes_encrypt(
                    context.encrypt, FileLikeIter([body]), preamble=AES256CBC,
                    chunk_size=getattr(client, 'chunk_size', 65536),
                    content_length=content_length))
            if 'content-length' in put_headers:
                del put_headers['content-length']
        container, obj = path.split('/', 1)
        status, reason, headers, contents = client.put_object(
            container, obj, body, headers=put_headers, query=context.query,
            cdn=context.cdn)
        if hasattr(contents, 'read'):
            contents = contents.read()
    if status // 100 != 2:
        raise ReturnCode(
            'putting object %r: %s %s %r' % (path, status, reason, contents))
    if context.seek is not None:
        content_length = put_headers.get('content-length')
        etag = headers.get('etag')
        if content_length and etag:
            content_length = int(content_length)
        else:
            with context.client_manager.with_client() as client:
                container, obj = path.split('/', 1)
                status, reason, headers, contents = client.head_object(
                    container, obj, cdn=context.cdn)
                if hasattr(contents, 'read'):
                    contents = contents.read()
            if status // 100 != 2:
                raise ReturnCode(
                    'heading object %r: %s %s %r' %
                    (path, status, reason, contents))
            content_length = headers.get('content-length')
            etag = headers.get('etag')
            if content_length:
                content_length = int(content_length)
        return content_length, etag
    if context.stdin is not None:
        return headers.get('etag')
def cli_put_object(context, path):
    """
    Performs a PUT on the object.

    See :py:mod:`swiftly.cli.put` for context usage information.

    See :py:class:`CLIPut` for more information.
    """
    if context.different and context.encrypt:
        raise ReturnCode(
            'context.different will not work properly with context.encrypt '
            'since encryption may change the object size')
    put_headers = dict(context.headers)
    if context.empty:
        body = ''
        put_headers['content-length'] = '0'
    elif not context.input_ or context.input_ == '-':
        stdin = context.io_manager.get_stdin()

        if context.stdin_segmentation:
            def reader():
                while True:
                    chunk = stdin.read(65536)
                    if chunk:
                        yield chunk
                    else:
                        return

            segment_body = FileLikeIter(reader(), context.segment_size)

            prefix = _create_container(context, path, time.time(), 0)
            new_context = context.copy()
            new_context.stdin_segmentation = False
            new_context.stdin = segment_body
            new_context.headers = dict(context.headers)
            segment_n = 0
            path2info = {}
            while not segment_body.is_empty():
                segment_path = _get_segment_path(prefix, segment_n)
                etag = cli_put_object(new_context, segment_path)
                size = segment_body.limit - segment_body.left
                path2info[segment_path] = (size, etag)

                segment_body.reset_limit()
                segment_n += 1
            body = _get_manifest_body(context, prefix, path2info, put_headers)
        else:
            if hasattr(context, 'stdin'):
                body = context.stdin
            else:
                body = stdin
    elif context.seek is not None:
        if context.encrypt:
            raise ReturnCode(
                'putting object %r: Cannot use encryption and context.seek' %
                path)
        body = open(context.input_, 'rb')
        body.seek(context.seek)
    else:
        l_mtime = os.path.getmtime(context.input_)
        l_size = os.path.getsize(context.input_)
        put_headers['content-length'] = str(l_size)
        if context.newer or context.different:
            r_mtime = None
            r_size = None
            with context.client_manager.with_client() as client:
                status, reason, headers, contents = client.head_object(
                    *path.split('/', 1), headers=context.headers,
                    query=context.query, cdn=context.cdn)
                if hasattr(contents, 'read'):
                    contents.read()
            if status // 100 == 2:
                r_mtime = headers.get('x-object-meta-mtime')
                if r_mtime:
                    try:
                        r_mtime = float(r_mtime)
                    except ValueError:
                        r_mtime = None
                r_size = headers.get('content-length')
                if r_size:
                    try:
                        r_size = int(r_size)
                    except ValueError:
                        r_size = None
            elif status != 404:
                raise ReturnCode(
                    'could not head %r for conditional check; skipping put: '
                    '%s %s' % (path, status, reason))
            if context.newer and r_mtime is not None or l_mtime <= r_mtime:
                return
            if context.different and r_mtime is not None and \
                    l_mtime == r_mtime and r_size is not None and \
                    l_size == r_size:
                return
        put_headers['x-object-meta-mtime'] = '%f' % l_mtime
        size = os.path.getsize(context.input_)
        if size > context.segment_size:
            if context.encrypt:
                raise ReturnCode(
                    'putting object %r: Cannot use encryption for objects '
                    'greater than the segment size' % path)
            prefix = _create_container(context, path, l_mtime, size)
            conc = Concurrency(context.concurrency)
            start = 0
            segment = 0
            path2info = {}
            while start < size:
                new_context = context.copy()
                new_context.headers = dict(context.headers)
                new_context.headers['content-length'] = str(min(
                    size - start, context.segment_size))
                new_context.seek = start
                new_path = _get_segment_path(prefix, segment)
                for (ident, (exc_type, exc_value, exc_tb, result)) in \
                        six.iteritems(conc.get_results()):
                    if exc_value:
                        conc.join()
                        raise exc_value
                    path2info[ident] = result
                conc.spawn(
                    new_path, cli_put_object, new_context, new_path)
                segment += 1
                start += context.segment_size
            conc.join()
            for (ident, (exc_type, exc_value, exc_tb, result)) in \
                    six.iteritems(conc.get_results()):
                if exc_value:
                    raise exc_value
                path2info[ident] = result
            body = _get_manifest_body(context, prefix, path2info, put_headers)
        else:
            body = open(context.input_, 'rb')
    with context.client_manager.with_client() as client:
        if context.encrypt:
            content_length = put_headers.get('content-length')
            if content_length:
                content_length = int(content_length)
            if hasattr(body, 'read'):
                body = FileLikeIter(aes_encrypt(
                    context.encrypt, body, preamble=AES256CBC,
                    chunk_size=getattr(client, 'chunk_size', 65536),
                    content_length=content_length))
            else:
                body = FileLikeIter(aes_encrypt(
                    context.encrypt, FileLikeIter([body]), preamble=AES256CBC,
                    chunk_size=getattr(client, 'chunk_size', 65536),
                    content_length=content_length))
            if 'content-length' in put_headers:
                del put_headers['content-length']
        container, obj = path.split('/', 1)
        status, reason, headers, contents = client.put_object(
            container, obj, body, headers=put_headers, query=context.query,
            cdn=context.cdn)
        if hasattr(contents, 'read'):
            contents = contents.read()
    if status // 100 != 2:
        raise ReturnCode(
            'putting object %r: %s %s %r' % (path, status, reason, contents))
    if context.seek is not None:
        content_length = put_headers.get('content-length')
        etag = headers.get('etag')
        if content_length and etag:
            content_length = int(content_length)
        else:
            with context.client_manager.with_client() as client:
                container, obj = path.split('/', 1)
                status, reason, headers, contents = client.head_object(
                    container, obj, cdn=context.cdn)
                if hasattr(contents, 'read'):
                    contents = contents.read()
            if status // 100 != 2:
                raise ReturnCode(
                    'heading object %r: %s %s %r' %
                    (path, status, reason, contents))
            content_length = headers.get('content-length')
            etag = headers.get('etag')
            if content_length:
                content_length = int(content_length)
        return content_length, etag
    if context.stdin is not None:
        return headers.get('etag')
def cli_put_object ( context , path ) : if context . different and context . encrypt : raise ReturnCode ( 'context.different will not work properly with context.encrypt ' 'since encryption may change the object size' ) put_headers = dict ( context . headers ) if context . empty : body = '' put_headers [ 'content-length' ] = '0' elif not context . input_ or context . input_ == '-' : stdin = context . io_manager . get_stdin ( ) if context . stdin_segmentation : def reader ( ) : while True : chunk = stdin . read ( 65536 ) if chunk : yield chunk else : return segment_body = FileLikeIter ( reader ( ) , context . segment_size ) prefix = _create_container ( context , path , time . time ( ) , 0 ) new_context = context . copy ( ) new_context . stdin_segmentation = False new_context . stdin = segment_body new_context . headers = dict ( context . headers ) segment_n = 0 path2info = { } while not segment_body . is_empty ( ) : segment_path = _get_segment_path ( prefix , segment_n ) etag = cli_put_object ( new_context , segment_path ) size = segment_body . limit - segment_body . left path2info [ segment_path ] = ( size , etag ) segment_body . reset_limit ( ) segment_n += 1 body = _get_manifest_body ( context , prefix , path2info , put_headers ) else : if hasattr ( context , 'stdin' ) : body = context . stdin else : body = stdin elif context . seek is not None : if context . encrypt : raise ReturnCode ( 'putting object %r: Cannot use encryption and context.seek' % path ) body = open ( context . input_ , 'rb' ) body . seek ( context . seek ) else : l_mtime = os . path . getmtime ( context . input_ ) l_size = os . path . getsize ( context . input_ ) put_headers [ 'content-length' ] = str ( l_size ) if context . newer or context . different : r_mtime = None r_size = None with context . client_manager . with_client ( ) as client : status , reason , headers , contents = client . head_object ( * path . split ( '/' , 1 ) , headers = context . headers , query = context . query , cdn = context . cdn ) if hasattr ( contents , 'read' ) : contents . read ( ) if status // 100 == 2 : r_mtime = headers . get ( 'x-object-meta-mtime' ) if r_mtime : try : r_mtime = float ( r_mtime ) except ValueError : r_mtime = None r_size = headers . get ( 'content-length' ) if r_size : try : r_size = int ( r_size ) except ValueError : r_size = None elif status != 404 : raise ReturnCode ( 'could not head %r for conditional check; skipping put: ' '%s %s' % ( path , status , reason ) ) if context . newer and r_mtime is not None or l_mtime <= r_mtime : return if context . different and r_mtime is not None and l_mtime == r_mtime and r_size is not None and l_size == r_size : return put_headers [ 'x-object-meta-mtime' ] = '%f' % l_mtime size = os . path . getsize ( context . input_ ) if size > context . segment_size : if context . encrypt : raise ReturnCode ( 'putting object %r: Cannot use encryption for objects ' 'greater than the segment size' % path ) prefix = _create_container ( context , path , l_mtime , size ) conc = Concurrency ( context . concurrency ) start = 0 segment = 0 path2info = { } while start < size : new_context = context . copy ( ) new_context . headers = dict ( context . headers ) new_context . headers [ 'content-length' ] = str ( min ( size - start , context . segment_size ) ) new_context . seek = start new_path = _get_segment_path ( prefix , segment ) for ( ident , ( exc_type , exc_value , exc_tb , result ) ) in six . iteritems ( conc . get_results ( ) ) : if exc_value : conc . join ( ) raise exc_value path2info [ ident ] = result conc . spawn ( new_path , cli_put_object , new_context , new_path ) segment += 1 start += context . segment_size conc . join ( ) for ( ident , ( exc_type , exc_value , exc_tb , result ) ) in six . iteritems ( conc . get_results ( ) ) : if exc_value : raise exc_value path2info [ ident ] = result body = _get_manifest_body ( context , prefix , path2info , put_headers ) else : body = open ( context . input_ , 'rb' ) with context . client_manager . with_client ( ) as client : if context . encrypt : content_length = put_headers . get ( 'content-length' ) if content_length : content_length = int ( content_length ) if hasattr ( body , 'read' ) : body = FileLikeIter ( aes_encrypt ( context . encrypt , body , preamble = AES256CBC , chunk_size = getattr ( client , 'chunk_size' , 65536 ) , content_length = content_length ) ) else : body = FileLikeIter ( aes_encrypt ( context . encrypt , FileLikeIter ( [ body ] ) , preamble = AES256CBC , chunk_size = getattr ( client , 'chunk_size' , 65536 ) , content_length = content_length ) ) if 'content-length' in put_headers : del put_headers [ 'content-length' ] container , obj = path . split ( '/' , 1 ) status , reason , headers , contents = client . put_object ( container , obj , body , headers = put_headers , query = context . query , cdn = context . cdn ) if hasattr ( contents , 'read' ) : contents = contents . read ( ) if status // 100 != 2 : raise ReturnCode ( 'putting object %r: %s %s %r' % ( path , status , reason , contents ) ) if context . seek is not None : content_length = put_headers . get ( 'content-length' ) etag = headers . get ( 'etag' ) if content_length and etag : content_length = int ( content_length ) else : with context . client_manager . with_client ( ) as client : container , obj = path . split ( '/' , 1 ) status , reason , headers , contents = client . head_object ( container , obj , cdn = context . cdn ) if hasattr ( contents , 'read' ) : contents = contents . read ( ) if status // 100 != 2 : raise ReturnCode ( 'heading object %r: %s %s %r' % ( path , status , reason , contents ) ) content_length = headers . get ( 'content-length' ) etag = headers . get ( 'etag' ) if content_length : content_length = int ( content_length ) return content_length , etag if context . stdin is not None : return headers . get ( 'etag' )
Performs a PUT on the object.

    See :py:mod:`swiftly.cli.put` for context usage information.

    See :py:class:`CLIPut` for more information.
Performs a PUT on the object .