From 5b76d4536b71b305e89c83047158c68e10085ecf Mon Sep 17 00:00:00 2001 From: yupix Date: Wed, 24 May 2023 08:19:25 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20pagination=E3=82=92=E3=82=84=E3=82=8B?= =?UTF-8?q?=E3=81=9F=E3=82=81=E3=81=AE=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mipac/utils/pagination.py | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 mipac/utils/pagination.py diff --git a/mipac/utils/pagination.py b/mipac/utils/pagination.py new file mode 100644 index 0000000..dd8fd42 --- /dev/null +++ b/mipac/utils/pagination.py @@ -0,0 +1,61 @@ +from typing import Any, Generic, Literal, TypeVar +from mipac.http import HTTPClient, Route + +T = TypeVar('T') + + +class Pagination(Generic[T]): + def __init__( + self, + http_client: HTTPClient, + route: Route, + json: dict[str, Any], + auth: bool = True, + remove_none: bool = True, + lower: bool = True, + pagination_type: Literal['until', 'count'] = 'until', + can_use_limit: bool = True, + limit: int = 100, + max_limit: int = 100, + ) -> None: + self.http_client: HTTPClient = http_client + self.route: Route = route + self.json: dict[str, Any] = json + self.auth: bool = auth + self.remove_none: bool = remove_none + self.lower: bool = lower + self.pagination_type: Literal['until', 'count'] = pagination_type + self.can_use_limit: bool = can_use_limit + self.limit: int = limit + self.max_limit: int = max_limit + self.count = 0 + self.latest_res: list[Any] = [] + + async def next(self) -> list[T]: + if self.pagination_type == 'count': + self.json['offset'] = self.json.get('limit', self.limit) * self.count + self.count += 1 + res: list[T] = await self.http_client.request( + self.route, + auth=self.auth, + remove_none=self.remove_none, + lower=self.lower, + json=self.json, + ) + if self.pagination_type == 'until': + self.json['untilId'] = res[-1]['id'] # type: ignore + self.latest_res = res + return res + + @property + def is_final(self) -> bool: + if ( + self.pagination_type == 'count' + and len(self.latest_res) == 0 + or len(self.latest_res) < self.max_limit + ): + return True + if self.pagination_type == 'until' and len(self.latest_res) == 0: + return True + return False +