mirror of
https://github.com/sb745/NyaaV3.git
synced 2025-03-12 22:06:55 +02:00
100 lines
3.2 KiB
Python
100 lines
3.2 KiB
Python
|
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)
|