Exemplo n.º 1
0
    def paginate_resources(cls, request, resources, on_fail_status):
        """Truncates a list of resources based on ClientPagingControls

        Args:
            request (object): The parsed protobuf request object
            resources (list of objects): The resources to be paginated

        Returns:
            list: The paginated list of resources
            object: The ClientPagingResponse to be sent back to the client
        """
        if not resources:
            return (resources,
                    client_list_control_pb2.ClientPagingResponse(
                        total_resources=0))

        paging = request.paging
        count = min(paging.count, MAX_PAGE_SIZE) or MAX_PAGE_SIZE

        # Find the start index from the location marker sent
        try:
            if paging.start_id:
                start_index = cls.index_by_id(paging.start_id, resources)
            elif paging.end_id:
                end_index = cls.index_by_id(paging.end_id, resources)
                start_index = end_index + 1 - count
            else:
                start_index = paging.start_index

            if start_index < 0 or start_index >= len(resources):
                raise AssertionError
        except AssertionError:
            raise _ResponseFailed(on_fail_status)

        paged_resources = resources[start_index:start_index + count]

        paging_response = client_list_control_pb2.ClientPagingResponse(
            next_id=cls.id_by_index(start_index + count, resources),
            previous_id=cls.id_by_index(start_index - 1, resources),
            start_index=start_index,
            total_resources=len(resources))

        return paged_resources, paging_response
Exemplo n.º 2
0
    def paginate_resources(cls, request, resources, on_fail_status):
        """Truncates a list of resources based on ClientPagingControls

        Args:
            request (object): The parsed protobuf request object
            resources (list of objects): The resources to be paginated

        Returns:
            list: The paginated list of resources
            object: The ClientPagingResponse to be sent back to the client
        """
        if not resources:
            return (resources, client_list_control_pb2.ClientPagingResponse())

        paging = request.paging
        limit = min(paging.limit, MAX_PAGE_SIZE) or DEFAULT_PAGE_SIZE
        # Find the start index from the location marker sent
        try:
            if paging.start:
                start_index = cls.index_by_id(paging.start, resources)
            else:
                start_index = 0

            if start_index < 0 or start_index >= len(resources):
                raise AssertionError
        except AssertionError:
            raise _ResponseFailed(on_fail_status)

        paged_resources = resources[start_index: start_index + limit]
        if start_index + limit < len(resources):
            paging_response = client_list_control_pb2.ClientPagingResponse(
                next=cls.id_by_index(start_index + limit, resources),
                start=cls.id_by_index(start_index, resources),
                limit=limit)
        else:
            paging_response = client_list_control_pb2.ClientPagingResponse(
                start=cls.id_by_index(start_index, resources),
                limit=limit)

        return paged_resources, paging_response
Exemplo n.º 3
0
    def _respond(self, request):
        head_block = self._get_head_block(request)
        self._validate_ids(request.block_ids)
        blocks = None
        paging_response = None

        if request.block_ids:
            blocks = self._block_store.get_blocks(request.block_ids)
            blocks = itertools.filterfalse(
                lambda block: block.block_num > head_block.block_num, blocks)

            # realize the iterator
            blocks = list(map(lambda blkw: blkw.block, blocks))

            paging_response = client_list_control_pb2.ClientPagingResponse()
        else:
            paging = request.paging
            sort_reverse = BlockListRequest.is_reverse(
                request.sorting, self._status.INVALID_SORT)
            limit = min(paging.limit, MAX_PAGE_SIZE) or DEFAULT_PAGE_SIZE
            iterargs = {'reverse': not sort_reverse}

            if paging.start:
                iterargs['start_block_num'] = paging.start
            elif not sort_reverse:
                iterargs['start_block'] = head_block

            block_iter = None
            try:
                block_iter = self._block_store.get_block_iter(**iterargs)
                blocks = block_iter
                if sort_reverse:
                    blocks = itertools.takewhile(
                        lambda block: block.block_num <= head_block.block_num,
                        blocks)

                blocks = itertools.islice(blocks, limit)
                # realize the result list, which will evaluate the underlying
                # iterator
                blocks = list(map(lambda blkw: blkw.block, blocks))

                next_block = next(block_iter, None)
                if next_block:
                    next_block_num = block_num_to_hex(next_block.block_num)
                else:
                    next_block_num = None

                block_id = blocks[0].header_signature
                start = self._block_store[block_id].block_num
            except ValueError:
                if paging.start:
                    return self._status.INVALID_PAGING

                return self._status.NO_ROOT
            except KeyError:
                if paging.start:
                    return self._status.INVALID_PAGING

                return self._status.NO_ROOT

            paging_response = client_list_control_pb2.ClientPagingResponse(
                next=next_block_num,
                limit=limit,
                start=block_num_to_hex(start))

        if not blocks:
            return self._wrap_response(self._status.NO_RESOURCE,
                                       head_id=head_block.identifier,
                                       paging=paging_response)

        return self._wrap_response(head_id=head_block.identifier,
                                   paging=paging_response,
                                   blocks=blocks)
Exemplo n.º 4
0
    def _respond(self, request):
        head_block = self._get_head_block(request)
        blocks = None
        paging_response = None
        if request.block_ids:
            blocks = self._block_store.get_blocks(request.block_ids)
            blocks = itertools.filterfalse(
                lambda block: block.block_num > head_block.block_num, blocks)

            # realize the iterator
            blocks = list(map(lambda blkw: blkw.block, blocks))

            paging_response = client_list_control_pb2.ClientPagingResponse(
                total_resources=len(blocks))
        else:
            paging = request.paging
            sort_reverse = BlockListRequest.is_reverse(
                request.sorting, self._status.INVALID_SORT)
            count = min(paging.count, MAX_PAGE_SIZE) or MAX_PAGE_SIZE
            iterargs = {'reverse': not sort_reverse}

            if paging.start_id:
                iterargs['start_block_num'] = paging.start_id
            elif not sort_reverse:
                iterargs['start_block'] = head_block

            block_iter = None
            try:
                block_iter = self._block_store.get_block_iter(**iterargs)
                blocks = block_iter
                if sort_reverse:
                    blocks = itertools.takewhile(
                        lambda block: block.block_num <= head_block.block_num,
                        blocks)

                blocks = itertools.islice(blocks, count)

                # realize the result list, which will evaluate the underlying
                # iterator
                blocks = list(map(lambda blkw: blkw.block, blocks))

                next_block = next(block_iter, None)
                if next_block:
                    next_block_num = BlockStore.block_num_to_hex(
                        next_block.block_num)
                else:
                    next_block_num = None
            except ValueError:
                if paging.start_id:
                    return self._status.INVALID_PAGING

                return self._status.NO_ROOT

            paging_response = client_list_control_pb2.ClientPagingResponse(
                next_id=next_block_num,
                total_resources=head_block.block_num + 1)

        if not blocks:
            return self._wrap_response(self._status.NO_RESOURCE,
                                       head_id=head_block.identifier,
                                       paging=paging_response)

        return self._wrap_response(head_id=head_block.identifier,
                                   paging=paging_response,
                                   blocks=blocks)