Fix Guestline + Mews direct scrapers after engine API changes
Both competitor booking engines changed their API contracts, silently
breaking their direct scrapes ~16 days ago (200 responses with empty
bodies, so no exception was ever raised):
- Guestline: the /enhanced availability endpoint now returns a bare []
for every date. Switch to the base /api/availabilities/{coll}/{hotel}
endpoint, which returns {"rooms":[...]} with the same room shape.
- Mews: getAvailability now rejects the old body with "Invalid
EnterpriseId" — it requires enterpriseId + serviceId. getPricing
additionally requires currencyCode. Capture the enterprise's
defaultCurrencyCode in _ensure_config and send all three.
Also stop last_scraped_at advancing when a run saves 0 rows, so the
overview no longer reports a phantom-fresh scrape while the per-date
data stays stale — the symptom that surfaced this.
Verified live: Three Ways now yields 41 rows/night, Old Stocks 10.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
22e3670531
commit
b916f1a09b
3 changed files with 31 additions and 14 deletions
|
|
@ -123,19 +123,25 @@ def run_scrape(hotel_id: int, profile_name: str, params: dict):
|
|||
|
||||
loop = asyncio.new_event_loop()
|
||||
try:
|
||||
loop.run_until_complete(_run_scrape_async(hotel_id, profile, params, scraped_at))
|
||||
rows_saved = loop.run_until_complete(_run_scrape_async(hotel_id, profile, params, scraped_at))
|
||||
finally:
|
||||
loop.close()
|
||||
|
||||
db = SyncSessionLocal()
|
||||
try:
|
||||
db.execute(
|
||||
text("UPDATE direct_competitor_hotels SET last_scraped_at = :ts WHERE id = :id"),
|
||||
{"ts": scraped_at, "id": hotel_id}
|
||||
)
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
# Only advance last_scraped_at when the run actually captured data. A run that
|
||||
# saved nothing means the engine returned empty/errored — don't let the overview
|
||||
# report a phantom-fresh scrape while the per-date data stays stale.
|
||||
if rows_saved:
|
||||
db = SyncSessionLocal()
|
||||
try:
|
||||
db.execute(
|
||||
text("UPDATE direct_competitor_hotels SET last_scraped_at = :ts WHERE id = :id"),
|
||||
{"ts": scraped_at, "id": hotel_id}
|
||||
)
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
else:
|
||||
log.warning(f"Hotel {hotel_id}: scrape saved 0 rows — last_scraped_at left unchanged")
|
||||
|
||||
|
||||
async def _run_scrape_async(hotel_id: int, profile, params: dict, scraped_at: datetime):
|
||||
|
|
@ -144,7 +150,7 @@ async def _run_scrape_async(hotel_id: int, profile, params: dict, scraped_at: da
|
|||
arrival_dates = await profile.fetch_arrival_dates(client, params)
|
||||
except Exception as e:
|
||||
log.error(f"Hotel {hotel_id}: failed to fetch arrival dates: {e}")
|
||||
return
|
||||
return 0
|
||||
|
||||
log.info(f"Hotel {hotel_id}: {len(arrival_dates)} bookable dates")
|
||||
|
||||
|
|
@ -305,3 +311,4 @@ async def _run_scrape_async(hotel_id: int, profile, params: dict, scraped_at: da
|
|||
db.close()
|
||||
|
||||
log.info(f"Hotel {hotel_id}: scrape complete, {rows_saved} rows saved")
|
||||
return rows_saved
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue