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
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
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)
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)