diff --git a/backend/services/direct_profiles/eviivo.py b/backend/services/direct_profiles/eviivo.py index ce4ea22..8502341 100644 --- a/backend/services/direct_profiles/eviivo.py +++ b/backend/services/direct_profiles/eviivo.py @@ -44,6 +44,30 @@ class EviivoProfile(BaseProfile): return {"property_slug": m.group(1)} return None + async def fetch_category_names(self, client, params: dict) -> tuple[dict, dict]: + slug = params["property_slug"] + try: + r = await client.get(f"https://via.eviivo.com/{slug}", headers=HEADERS, timeout=20) + except Exception: + return {}, {} + if r.status_code != 200: + return {}, {} + room_names: dict[str, str] = {} + rate_names: dict[str, str] = {} + for tag in _TAG_RE.finditer(r.text): + attrs = _extract_data_attrs(tag.group(0)) + room_id = attrs.get("room-type-id", "").strip() + if not room_id: + continue + room_name = attrs.get("item-name", "").strip() + rate_plan = attrs.get("rate-plan-name", "").strip() + rate_id = f"{room_id}_{_slugify(rate_plan) if rate_plan else 'standard'}" + if room_name: + room_names[room_id] = room_name + if rate_plan: + rate_names[rate_id] = rate_plan + return room_names, rate_names + async def fetch_arrival_dates(self, client, params: dict) -> list[str]: """Return the next 90 days as ISO date strings starting from tomorrow. diff --git a/backend/services/direct_profiles/mews.py b/backend/services/direct_profiles/mews.py index c86f39a..d495060 100644 --- a/backend/services/direct_profiles/mews.py +++ b/backend/services/direct_profiles/mews.py @@ -91,6 +91,40 @@ class MewsProfile(BaseProfile): return {"booking_engine_id": m.group(1)} return None + async def fetch_category_names(self, client, params: dict) -> tuple[dict, dict]: + if not await _ensure_config(client, params): + return {}, {} + tz = params.get("_tz", ZoneInfo("Europe/London")) + today = date.today() + r = await client.post( + f"{API_BASE}/services/getCalendarData", + json={ + "bookingEngineId": params["booking_engine_id"], + "serviceId": params["service_id"], + "startUtc": _midnight_utc(today, tz), + "endUtc": _midnight_utc(today + timedelta(days=7), tz), + "client": CLIENT, + "session": _session(), + }, + headers=HEADERS, + timeout=20, + ) + if r.status_code != 200: + return {}, {} + data = r.json() + lang = "en-US" + room_names = { + cat["id"]: cat["name"].get(lang, cat["id"]) + for cat in data.get("resourceCategories", []) + if "name" in cat + } + rate_names = { + rate["id"]: rate["name"].get(lang, rate["id"]) + for rate in data.get("rates", []) + if "name" in rate + } + return room_names, rate_names + async def fetch_arrival_dates(self, client, params: dict) -> list[str]: if not await _ensure_config(client, params): return [] diff --git a/backend/services/direct_profiles/qbook.py b/backend/services/direct_profiles/qbook.py index a25d70e..433395f 100644 --- a/backend/services/direct_profiles/qbook.py +++ b/backend/services/direct_profiles/qbook.py @@ -43,6 +43,37 @@ class QBookProfile(BaseProfile): dk = unquote(dk_match.group(1)) if dk_match else "" return {"hotel_id": hotel_id, "dk": dk} + async def fetch_category_names(self, client, params: dict) -> tuple[dict, dict]: + hotel_id = params["hotel_id"] + dk = params["dk"] + from datetime import date, timedelta + tomorrow = (date.today() + timedelta(days=1)).isoformat() + day_after = (date.today() + timedelta(days=2)).isoformat() + try: + r = await client.get( + "https://web-bookings.hotels.uk.com/api/pull", + params={ + "HotelAvailability": "", "k": _BUNDLE_K, + "HotelID": hotel_id, "from": tomorrow, "to": day_after, + "json": "", "dk": dk, "Qbook": "", + "GHABooking": "", "CookieBooking": "", "COOKIE_HotelID": "", + "guests": "", "adultsCheck": "", "childAges": "", + "roomId": "", "revised": "", + }, + headers={**HEADERS, "Auth": _build_auth(hotel_id, tomorrow, day_after)}, + timeout=20, + ) + except Exception: + return {}, {} + if r.status_code != 200: + return {}, {} + room_names: dict[str, str] = {} + for item_id, item in r.json().get("availability", {}).items(): + if isinstance(item, dict) and item.get("item_name"): + room_names[str(item_id)] = item["item_name"] + # QBook has no distinct rate plan names + return room_names, {} + async def fetch_arrival_dates(self, client, params: dict) -> list[str]: today = date.today() return [(today + timedelta(days=i)).isoformat() for i in range(1, 91)]