diff --git a/funpaybotengine/methods/get_transactions.py b/funpaybotengine/methods/get_transactions.py index 9a6c92d..f016ca8 100644 --- a/funpaybotengine/methods/get_transactions.py +++ b/funpaybotengine/methods/get_transactions.py @@ -16,6 +16,7 @@ if TYPE_CHECKING: from funpaybotengine.client import Bot + from funpaybotengine.client.session.base import RawResponse class GetTransactions(FunPayMethod[TransactionPreviewsBatch], BaseModel): @@ -33,7 +34,7 @@ class GetTransactions(FunPayMethod[TransactionPreviewsBatch], BaseModel): def __init__( self, filter: TransactionFilter | str = TransactionFilter.ALL, - from_transaction_id: int | None = None, + from_transaction_id: int = 0, locale: Language | None = None, ): super().__init__( @@ -48,6 +49,18 @@ def __init__( from_transaction_id=from_transaction_id, ) + if self.filter is TransactionFilter.UNKNOWN: + raise ValueError(f'Unknown filter.') + + async def transform_result( + self, + parsing_result: Any, + response: RawResponse[Any], + ) -> TransactionPreviewsBatch: + batch = await super().transform_result(parsing_result, response) + batch.filter = self.filter + return batch + async def make_data(method: GetTransactions, bot: Bot) -> dict[str, Any]: return { diff --git a/funpaybotengine/methods/get_transactions_page.py b/funpaybotengine/methods/get_transactions_page.py index 4e680ec..72d7b1e 100644 --- a/funpaybotengine/methods/get_transactions_page.py +++ b/funpaybotengine/methods/get_transactions_page.py @@ -4,15 +4,21 @@ __all__ = ('GetTransactionsPage',) +from typing import TYPE_CHECKING, Any + from pydantic import BaseModel from funpayparsers.parsers.page_parsers import TransactionsPageParser -from funpaybotengine.types.enums import Language +from funpaybotengine.types.enums import Language, TransactionFilter from funpaybotengine.types.pages import TransactionsPage from funpaybotengine.methods.base import FunPayMethod from funpaybotengine.client.session import HTTPMethod +if TYPE_CHECKING: + from funpaybotengine.client.session.base import RawResponse + + class GetTransactionsPage(FunPayMethod[TransactionsPage], BaseModel): """Get the transactions page (``https://funpay.com/account/balance``).""" @@ -27,3 +33,13 @@ def __init__(self, locale: Language | None = None): allow_anonymous=False, allow_uninitialized=True, ) + + async def transform_result( + self, + parsing_result: Any, + response: RawResponse[Any], + ) -> TransactionsPage: + page = await super().transform_result(parsing_result, response) + if page.transactions is not None: + page.transactions.filter = TransactionFilter.ALL + return page diff --git a/funpaybotengine/types/enums.py b/funpaybotengine/types/enums.py index 502ea59..daa62a7 100644 --- a/funpaybotengine/types/enums.py +++ b/funpaybotengine/types/enums.py @@ -31,6 +31,8 @@ class TransactionFilter(str, Enum): OTHER = 'other' """Other transactions.""" + UNKNOWN = 'unknown' + class OrderPreviewType(Enum): SALE = auto() diff --git a/funpaybotengine/types/finances.py b/funpaybotengine/types/finances.py index 16d6827..85de3ef 100644 --- a/funpaybotengine/types/finances.py +++ b/funpaybotengine/types/finances.py @@ -6,6 +6,7 @@ from types import MappingProxyType from collections.abc import Mapping +from typing import Any from pydantic import BaseModel, field_validator from funpayparsers.parsers.utils import parse_date_string @@ -83,21 +84,18 @@ class TransactionPreviewsBatch(FunPayObject, BaseModel): user_id: int | None """ID of the user to whom all transactions in this batch belong.""" - filter: TransactionFilter | None - """Transactions filter applied to the current batch.""" + filter: TransactionFilter + """ + Transactions filter applied to the current batch. - @field_validator('filter', mode='before') - @classmethod - def _coerce_transaction_filter( - cls, - value: str | TransactionFilter | None, - ) -> TransactionFilter | None: - if value is None or isinstance(value, TransactionFilter): - return value - try: - return TransactionFilter(value) - except ValueError: - return None + The building method stamps this with the filter that was actually requested + (see ``GetTransactions.transform_result``). The value scraped from the response + HTML is only a fallback for hand-built objects, since FunPay omits the hidden + ``filter`` input in some responses. + + ``None`` means the filter is unknown, which is not the same as + ``TransactionFilter.ALL``. + """ next_transaction_id: int | None """ @@ -109,11 +107,19 @@ def _coerce_transaction_filter( If ``None``, there are no more transactions to load. """ + @field_validator('filter', mode='before') + @classmethod + def _coerce_transaction_filter(cls, value: Any) -> TransactionFilter | None: + try: + return TransactionFilter(value) + except ValueError: + return TransactionFilter.UNKNOWN + async def next_batch(self) -> TransactionPreviewsBatch: if not self.next_transaction_id: raise ValueError('Last batch.') return await self.get_bound_bot().get_transactions( from_transaction_id=self.next_transaction_id, - filter=self.filter or '', + filter=self.filter, )