from typing import Any, List, Optional, Sequence, TypeVar, Union T = TypeVar('T') class CustomPagination: """ A custom pagination class that mimics the interface of Flask-SQLAlchemy's Pagination but doesn't rely on the _query_items method. """ def __init__(self, query: Any, page: int, per_page: int, total: int, items: List[T]): """ Initialize a new CustomPagination object. Args: query: The query object (not used, but kept for compatibility) page: The current page number (1-indexed) per_page: The number of items per page total: The total number of items items: The items on the current page """ self.query = query self.page = page self.per_page = per_page self.total = total self.items = items # For compatibility with LimitedPagination self.actual_count = total @property def has_prev(self) -> bool: """Return True if there is a previous page.""" return self.page > 1 @property def has_next(self) -> bool: """Return True if there is a next page.""" return self.page < self.pages @property def pages(self) -> int: """The total number of pages.""" if self.per_page == 0 or self.total == 0: return 0 return max(1, (self.total + self.per_page - 1) // self.per_page) @property def prev_num(self) -> Optional[int]: """The previous page number, or None if this is the first page.""" if self.has_prev: return self.page - 1 return None @property def next_num(self) -> Optional[int]: """The next page number, or None if this is the last page.""" if self.has_next: return self.page + 1 return None @property def first(self) -> int: """The number of the first item on the page, starting from 1, or 0 if there are no items.""" if not self.items: return 0 return (self.page - 1) * self.per_page + 1 @property def last(self) -> int: """The number of the last item on the page, starting from 1, inclusive, or 0 if there are no items.""" if not self.items: return 0 return min(self.total, self.page * self.per_page) def iter_pages(self, left_edge: int = 2, left_current: int = 2, right_current: int = 5, right_edge: int = 2) -> Sequence[Optional[int]]: """ Yield page numbers for a pagination widget. Skipped pages between the edges and middle are represented by a None. """ last = 0 for num in range(1, self.pages + 1): if (num <= left_edge or (num > self.page - left_current - 1 and num < self.page + right_current) or num > self.pages - right_edge): if last + 1 != num: yield None yield num last = num def __iter__(self): """Iterate over the items on the current page.""" return iter(self.items) def __len__(self): """Return the number of items on the current page.""" return len(self.items)