Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced utils.py and webdriver.py #274

Merged
merged 15 commits into from
Jun 29, 2024
Merged
8 changes: 7 additions & 1 deletion lib/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import socket
import time
import random
from datetime import datetime, timezone
from enum import IntEnum
from typing import Any, Dict, Union
Expand All @@ -20,6 +21,9 @@
RESERVATION_NOT_FOUND_CODE = 400620389


def set_sleep_duration() -> None:
return random.uniform(1, 6)

def make_request(method: str, site: str, headers: JSON, info: JSON, max_attempts=20) -> JSON:
"""
Makes a request to the Southwest servers. For increased reliability, the request is performed
Expand Down Expand Up @@ -52,7 +56,9 @@ def make_request(method: str, site: str, headers: JSON, info: JSON, max_attempts
logger.debug("Reservation not found")
break

time.sleep(0.5)
attempts_sleep = set_sleep_duration()
logger.debug(f"Attempt {attempts}: Sleeping for {attempts_sleep:.2f} seconds")
dmytrokoren marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(attempts_sleep)

error_msg = response.reason + " " + str(response.status_code)
logger.debug("Failed to make request after %d attempts: %s", attempts, error_msg)
Expand Down
24 changes: 18 additions & 6 deletions lib/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import re
import sys
import time
import random
from typing import TYPE_CHECKING, Any, Dict, List

from seleniumbase import Driver
Expand All @@ -20,11 +21,12 @@
BASE_URL = "https://mobile.southwest.com"
LOGIN_URL = BASE_URL + "/api/security/v4/security/token"
TRIPS_URL = BASE_URL + "/api/mobile-misc/v1/mobile-misc/page/upcoming-trips"
CHECKIN_URL = BASE_URL + "/check-in"
RESERVATION_URL = BASE_URL + "/view-reservation"
HEADERS_URLS = [
BASE_URL + "/api/chase/v2/chase/offers",
BASE_URL + "/api/mobile-air-booking/v1/mobile-air-booking/feature/shopping-details",
BASE_URL + "/api/chase/v2/chase/offers"
]
USER_AGENT = "Mozilla/5.0 (Wayland; Linux x86_64; Touch; Microsoft Corporation/Surface Pro 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Ubuntu/23.10 Edg/117.0.2045.40"

# Southwest's code when logging in with the incorrect information
INVALID_CREDENTIALS_CODE = 400518024
Expand Down Expand Up @@ -60,6 +62,9 @@ def __init__(self, checkin_scheduler: CheckInScheduler) -> None:
self.login_status_code = None
self.trips_request_id = None

def _set_sleep_duration(self) -> None:
return random.uniform(1, 5)
dmytrokoren marked this conversation as resolved.
Show resolved Hide resolved

def _should_take_screenshots(self) -> bool:
"""
Determines if the webdriver should take screenshots for debugging based on the CLI arguments
Expand Down Expand Up @@ -130,7 +135,7 @@ def get_reservations(self, account_monitor: AccountMonitor) -> List[JSON]:
return reservations

def _get_driver(self) -> Driver:
logger.debug("Starting webdriver for current session (this may take a few minutes)")
jdholtz marked this conversation as resolved.
Show resolved Hide resolved
logger.debug("Starting webdriver for current session")
browser_path = self.checkin_scheduler.reservation_monitor.config.browser_path

driver_version = "mlatest"
Expand All @@ -142,16 +147,18 @@ def _get_driver(self) -> Driver:
driver = Driver(
binary_location=browser_path,
driver_version=driver_version,
headless=True,
uc_cdp_events=True,
undetectable=True,
headless=True,
guest_mode=True,
agent=USER_AGENT
)
logger.debug("Using browser version: %s", driver.caps["browserVersion"])

driver.add_cdp_listener("Network.requestWillBeSent", self._headers_listener)

logger.debug("Loading Southwest check-in page (this may take a few minutes)")
driver.get(CHECKIN_URL)
logger.debug("Loading Southwest reservation page (this may take a moment)")
driver.open(RESERVATION_URL)
return driver

def _headers_listener(self, data: JSON) -> None:
Expand Down Expand Up @@ -190,6 +197,8 @@ def _wait_for_login(self, driver: Driver, account_monitor: AccountMonitor) -> No
Waits for the login request to go through and sets the account name appropriately.
Handles login errors, if necessary.
"""
beforelogin_sleep = self._set_sleep_duration()
time.sleep(beforelogin_sleep)
self._click_login_button(driver)
self._wait_for_attribute("login_request_id")
login_response = self._get_response_body(driver, self.login_request_id)
Expand All @@ -201,6 +210,9 @@ def _wait_for_login(self, driver: Driver, account_monitor: AccountMonitor) -> No
raise error

self._set_account_name(account_monitor, login_response)
afterlogin_sleep = self._set_sleep_duration()
time.sleep(afterlogin_sleep)
driver.click(".upcoming-trips-link")

def _click_login_button(self, driver: Driver) -> None:
"""
Expand Down