Przeglądaj źródła

extend calendar retry to cover priceless responses

Empty-day/empty-dict retry missed the case where the API returns days
but with price=None on all of them (eventual consistency returning a
stale replica without price data). Both clients now also retry when no
day in the response carries a price.
ZiB 4 miesięcy temu
rodzic
commit
b897a068d4

+ 7 - 4
room_cal/service_api/_airbnb.py

@@ -233,15 +233,18 @@ class _AirbnbClient:
       ) or {}
       ) or {}
       return section.get('days', [])
       return section.get('days', [])
 
 
+    def _has_prices(days: list[dict]) -> bool:
+      return any(d.get('priceData', {}).get('price') is not None for d in days)
+
     resp = await self._gql('getDLSHostCalendar', _HASHES['getDLSHostCalendar'], variables, referer)
     resp = await self._gql('getDLSHostCalendar', _HASHES['getDLSHostCalendar'], variables, referer)
     days = _extract_days(resp)
     days = _extract_days(resp)
-    if not days:
-      _log.warning('Airbnb: empty calendar for %d-%02d; retrying', year, month)
+    if not days or not _has_prices(days):
+      _log.warning('Airbnb: empty or priceless calendar for %d-%02d; retrying', year, month)
       await asyncio.sleep(1)
       await asyncio.sleep(1)
       resp = await self._gql('getDLSHostCalendar', _HASHES['getDLSHostCalendar'], variables, referer)
       resp = await self._gql('getDLSHostCalendar', _HASHES['getDLSHostCalendar'], variables, referer)
       days = _extract_days(resp)
       days = _extract_days(resp)
-      if not days:
-        _log.warning('Airbnb: still empty calendar for %d-%02d after retry', year, month)
+      if not days or not _has_prices(days):
+        _log.warning('Airbnb: still empty/priceless calendar for %d-%02d after retry', year, month)
     return days
     return days
 
 
   async def _get_month_days(self, month: int, year: int) -> list[dict]:
   async def _get_month_days(self, month: int, year: int) -> list[dict]:

+ 4 - 4
room_cal/service_api/_booking.py

@@ -502,15 +502,15 @@ class _BookingClient:
       f'{_BASE}/fresa/extranet/inventory/fetch', self._monthly_referer(), body
       f'{_BASE}/fresa/extranet/inventory/fetch', self._monthly_referer(), body
     )
     )
     result = self._parse_calendar_days(raw)
     result = self._parse_calendar_days(raw)
-    if not result:
-      _log.warning('Booking.com: empty calendar for %d-%02d; retrying', year, month)
+    if not result or not any(info.price is not None for info in result.values()):
+      _log.warning('Booking.com: empty or priceless calendar for %d-%02d; retrying', year, month)
       await asyncio.sleep(1)
       await asyncio.sleep(1)
       raw = await self._multipart_post(
       raw = await self._multipart_post(
         f'{_BASE}/fresa/extranet/inventory/fetch', self._monthly_referer(), body
         f'{_BASE}/fresa/extranet/inventory/fetch', self._monthly_referer(), body
       )
       )
       result = self._parse_calendar_days(raw)
       result = self._parse_calendar_days(raw)
-      if not result:
-        _log.warning('Booking.com: still empty calendar for %d-%02d after retry', year, month)
+      if not result or not any(info.price is not None for info in result.values()):
+        _log.warning('Booking.com: still empty/priceless calendar for %d-%02d after retry', year, month)
     return result
     return result
 
 
   async def _get_month_calendar(self, month: int, year: int) -> dict[str, DayInfo]:
   async def _get_month_calendar(self, month: int, year: int) -> dict[str, DayInfo]: