diff --git a/g2f.py b/g2f.py index 4f43f43..5bcdee6 100644 --- a/g2f.py +++ b/g2f.py @@ -122,23 +122,52 @@ class FireflyClient: logger.error(f"Error connecting to Firefly III: {e}") return False + def _paginated_get(self, endpoint: str, resource_name: str) -> list: + """generic method to fetch all items from a paginated endpoint""" + all_items = [] + page = 1 + + try: + while True: + response = requests.get( + f"{self.base_url}{endpoint}", + headers=self.headers, + params={"page": page, "limit": 50} + ) + + if response.status_code != 200: + logger.error(f"Failed to fetch {resource_name} page {page}:" + f" {response.status_code} - {response.text}") + break + + data = response.json() + items_page = data["data"] + all_items.extend(items_page) + + # check pagination info + meta = data.get("meta", {}) + pagination = meta.get("pagination", {}) + current_page = pagination.get("current_page", 1) + total_pages = pagination.get("total_pages", 1) + + logger.debug(f"Fetched {resource_name} page {current_page} of {total_pages}" + f" ({len(items_page)} items)") + + if current_page >= total_pages: + break + + page += 1 + + logger.info(f"Found {len(all_items)} {resource_name} in Firefly III") + return all_items + + except Exception as e: + logger.error(f"Error fetching {resource_name}: {e}") + return all_items + def get_currencies(self) -> list: """Get all currencies from Firefly III""" - try: - response = requests.get(f"{self.base_url}/api/v1/currencies", - headers=self.headers) - if response.status_code == 200: - currencies = response.json()["data"] - logger.info(f"Found {len(currencies)} currencies in Firefly III") - return currencies - else: - logger.error( - f"Failed to fetch currencies: {response.status_code} - {response.text}" - ) - return [] - except Exception as e: - logger.error(f"Error fetching currencies: {e}") - return [] + return self._paginated_get("/api/v1/currencies", "currencies") def initialize_currencies(self) -> bool: """fetch all currencies and populate the mapping cache""" @@ -157,20 +186,7 @@ class FireflyClient: def get_accounts(self) -> list: """Get all accounts from Firefly III""" - try: - response = requests.get(f"{self.base_url}/api/v1/accounts", - headers=self.headers) - if response.status_code == 200: - accounts = response.json()["data"] - logger.info(f"Found {len(accounts)} accounts in Firefly III") - return accounts - else: - logger.error(f"Failed to fetch accounts:" - f" {response.status_code} - {response.text}") - return [] - except Exception as e: - logger.error(f"Error fetching accounts: {e}") - return [] + return self._paginated_get("/api/v1/accounts", "accounts") def enable_currency(self, currency_code: str) -> bool: """Enable a currency in Firefly III"""