import os import subprocess import sys from pathlib import Path from room_cal._utils import get_config def _data_home() -> Path: override = os.environ.get('ROOM_CAL_DATA_HOME') return Path(override) if override else Path.home() / '.local' / 'room_cal' def _ts_dir() -> Path: return Path(__file__).parent / 'typescript' def _npm_env() -> dict: dh = _data_home() env = os.environ.copy() env.setdefault('ROOM_CAL_DATA_HOME', str(dh)) env.setdefault('PLAYWRIGHT_BROWSERS_PATH', str(dh / '.playwright-browsers')) api_url = get_config().api_url if api_url: env.setdefault('ROOM_CAL_API_URL', api_url) return env def _ensure_installed(ts_dir: Path) -> None: if not (ts_dir / 'node_modules').exists(): print('=== npm install (service-api) ===') subprocess.run(['npm', 'install'], cwd=ts_dir, check=True) print() def refresh_booking_cookies() -> None: ts_dir = _ts_dir() _ensure_installed(ts_dir) env = _npm_env() env['HEADLESS'] = '1' try: subprocess.run(['npm', 'run', 'refresh-booking'], cwd=ts_dir, env=env, check=True) except subprocess.CalledProcessError as e: from .types import ServiceAuthError raise ServiceAuthError(f'Booking.com session expired — re-run without HEADLESS to re-authenticate (exit {e.returncode})') from None def refresh_airbnb_cookies() -> None: ts_dir = _ts_dir() _ensure_installed(ts_dir) env = _npm_env() env['HEADLESS'] = '1' try: subprocess.run(['npm', 'run', 'refresh-airbnb'], cwd=ts_dir, env=env, check=True) except subprocess.CalledProcessError as e: from .types import ServiceAuthError raise ServiceAuthError(f'Airbnb session expired — re-run without HEADLESS to re-authenticate (exit {e.returncode})') from None def trigger_booking_chat_auth() -> None: ts_dir = _ts_dir() _ensure_installed(ts_dir) result = subprocess.run(['npm', 'run', 'booking-2fa', '--'] + sys.argv[1:], cwd=ts_dir, env=_npm_env()) sys.exit(result.returncode) def refresh_cookies() -> None: ts_dir = _ts_dir() _ensure_installed(ts_dir) result = subprocess.run(['npm', 'run', 'refresh-all', '--'] + sys.argv[1:], cwd=ts_dir, env=_npm_env()) sys.exit(result.returncode)