swiftly/cli/get.py
def cli_get(context, path=None):
    """
    Performs a GET on the item (account, container, or object).

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

    See :py:class:`CLIGet` for more information.
    """
    path = path.lstrip('/') if path else None
    if not path:
        return cli_get_account_listing(context)
    elif '/' not in path.rstrip('/'):
        return cli_get_container_listing(context, path)
    status, reason, headers, contents = 0, 'Unknown', {}, ''
    with context.client_manager.with_client() as client:
        status, reason, headers, contents = client.get_object(
            *path.split('/', 1), headers=context.headers, query=context.query,
            cdn=context.cdn)
        if status // 100 != 2:
            if status == 404 and context.ignore_404:
                return
            if hasattr(contents, 'read'):
                contents.read()
            raise ReturnCode(
                'getting object %r: %s %s' % (path, status, reason))
        if context.decrypt:
            crypt_type = contents.read(1)
            if crypt_type == AES256CBC:
                contents = FileLikeIter(aes_decrypt(
                    context.decrypt, contents,
                    chunk_size=getattr(client, 'chunk_size', 65536)))
            else:
                raise ReturnCode(
                    'getting object %r: contents encrypted with unsupported '
                    'type %r' % (path, crypt_type))

        def disk_closed_callback(disk_path):
            if context.remove_empty_files and not os.path.getsize(disk_path):
                os.unlink(disk_path)
                if context.io_manager.stdout_root:
                    dirname = os.path.dirname(disk_path)
                    while dirname and dirname.startswith(
                            context.io_manager.stdout_root):
                        try:
                            os.rmdir(dirname)
                        except OSError:
                            pass
                        dirname = os.path.dirname(dirname)
                return
            if (headers.get('content-type') in
                    ['text/directory', 'application/directory'] and
                    headers.get('content-length') == '0'):
                os.unlink(disk_path)
                os.makedirs(disk_path)
            mtime = 0
            if 'x-object-meta-mtime' in headers:
                mtime = float(headers['x-object-meta-mtime'])
            elif 'last-modified' in headers:
                mtime = time.mktime(time.strptime(
                    headers['last-modified'], '%a, %d %b %Y %H:%M:%S %Z'))
            if mtime:
                os.utime(disk_path, (mtime, mtime))

        out_path = path
        if context.suppress_container_name:
            out_path = out_path.split('/', 1)[1]
        out_path = context.io_manager.client_path_to_os_path(out_path)
        with context.io_manager.with_stdout(
                out_path, disk_closed_callback=disk_closed_callback) as fp:
            if context.output_headers:
                context.write_headers(
                    fp, headers, context.muted_object_headers)
                fp.write('\n')
            chunk = contents.read(65536)
            while chunk:
                fp.write(chunk)
                chunk = contents.read(65536)
            fp.flush()
def cli_get(context, path=None):
    """
    Performs a GET on the item (account, container, or object).

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

    See :py:class:`CLIGet` for more information.
    """
    path = path.lstrip('/') if path else None
    if not path:
        return cli_get_account_listing(context)
    elif '/' not in path.rstrip('/'):
        return cli_get_container_listing(context, path)
    status, reason, headers, contents = 0, 'Unknown', {}, ''
    with context.client_manager.with_client() as client:
        status, reason, headers, contents = client.get_object(
            *path.split('/', 1), headers=context.headers, query=context.query,
            cdn=context.cdn)
        if status // 100 != 2:
            if status == 404 and context.ignore_404:
                return
            if hasattr(contents, 'read'):
                contents.read()
            raise ReturnCode(
                'getting object %r: %s %s' % (path, status, reason))
        if context.decrypt:
            crypt_type = contents.read(1)
            if crypt_type == AES256CBC:
                contents = FileLikeIter(aes_decrypt(
                    context.decrypt, contents,
                    chunk_size=getattr(client, 'chunk_size', 65536)))
            else:
                raise ReturnCode(
                    'getting object %r: contents encrypted with unsupported '
                    'type %r' % (path, crypt_type))

        def disk_closed_callback(disk_path):
            if context.remove_empty_files and not os.path.getsize(disk_path):
                os.unlink(disk_path)
                if context.io_manager.stdout_root:
                    dirname = os.path.dirname(disk_path)
                    while dirname and dirname.startswith(
                            context.io_manager.stdout_root):
                        try:
                            os.rmdir(dirname)
                        except OSError:
                            pass
                        dirname = os.path.dirname(dirname)
                return
            if (headers.get('content-type') in
                    ['text/directory', 'application/directory'] and
                    headers.get('content-length') == '0'):
                os.unlink(disk_path)
                os.makedirs(disk_path)
            mtime = 0
            if 'x-object-meta-mtime' in headers:
                mtime = float(headers['x-object-meta-mtime'])
            elif 'last-modified' in headers:
                mtime = time.mktime(time.strptime(
                    headers['last-modified'], '%a, %d %b %Y %H:%M:%S %Z'))
            if mtime:
                os.utime(disk_path, (mtime, mtime))

        out_path = path
        if context.suppress_container_name:
            out_path = out_path.split('/', 1)[1]
        out_path = context.io_manager.client_path_to_os_path(out_path)
        with context.io_manager.with_stdout(
                out_path, disk_closed_callback=disk_closed_callback) as fp:
            if context.output_headers:
                context.write_headers(
                    fp, headers, context.muted_object_headers)
                fp.write('\n')
            chunk = contents.read(65536)
            while chunk:
                fp.write(chunk)
                chunk = contents.read(65536)
            fp.flush()
Performs a GET on the item (account, container, or object).

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

    See :py:class:`CLIGet` for more information.