MDC
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from twilio.rest import Client import time import os from dotenv import load_dotenv load_dotenv() # Configuration PORTAL_URL = os.getenv('PORTAL_URL') USERNAME = os.getenv('USERNAME') PASSWORD = os.getenv('PASSWORD') # Twilio configuration account_sid = os.getenv('TWILIO_ACCOUNT_SID') auth_token = os.getenv('TWILIO_AUTH_TOKEN') twilio_phone = os.getenv('TWILIO_PHONE_NUMBER') your_phone = os.getenv('MY_PHONE_NUMBER') def setup_driver(): """ Set up and return a headless Chrome WebDriver instance. This function creates a new instance of a Chrome WebDriver configured with options for headless operation. This is particularly useful for running tests or web scraping tasks in environments without a graphical interface. :return: A configured instance of `webdriver.Chrome` with headless options. :rtype: selenium.webdriver.Chrome """ chrome_options = Options() chrome_options.add_argument('--headless') return webdriver.Chrome(options=chrome_options) def check_portal_status(driver): """ Checks the status of an application portal by verifying the presence and content of specific elements on the web page within a specified timeout period. This method is designed for use with Selenium WebDriver. :param driver: The Selenium WebDriver instance used to interact with the web page. :return: A boolean indicating the status of the portal. Returns ``False`` if applications are closed or in case of an error. Returns ``True`` otherwise. :raises: This function does not explicitly declare raised exceptions, but any exceptions encountered during execution will be logged and handled internally. """ try: # Check for closed message error_element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "b.text-danger")) ) # Get the inner text of the element element_text = error_element.text # Log the text of the element and return the portal status print(f"Portal status message: {element_text}") return "Applications are closed" not in error_element.text except Exception as e: print(f"Error checking portal status: {e}") return False def initial_login(driver): """ Performs the initial login process for the medical portal using the provided web driver. This function handles the navigation to the portal, selecting the appropriate user type, entering credentials, submitting the login form, and navigating to the housemanship application section. Returns a success status as a boolean value. :param driver: The Selenium WebDriver instance used to perform actions on the web application. :return: A boolean flag indicating whether the login operation was successful (True) or failed (False). """ try: driver.get(PORTAL_URL) doctor_radio = WebDriverWait(driver, 10).until( EC.presence_of_element_located( (By.XPATH, "//input[@type='radio' and following-sibling::text()[contains(., 'Doctor')]]")) ) doctor_radio.click() username_field = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[name='username']")) ) username_field.send_keys(USERNAME) password_field = driver.find_element(By.CSS_SELECTOR, "input[name='password']") password_field.send_keys(PASSWORD) submit_button = driver.find_element(By.CSS_SELECTOR, "button.btn-primary") submit_button.click() housemanship_link = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "a[href='#/housemanship-application']")) ) housemanship_link.click() time.sleep(2) return True except Exception as e: print(f"Login failed: {e}") return False def refresh_page(driver): """ Refreshes the current page by locating and clicking on the refresh button. The method waits until the refresh button is located within a defined timeout and then performs the click operation. After triggering the refresh, it waits briefly to allow the operation to complete. If the operation fails at any point, it logs the failure and returns a failure status. :param driver: The Selenium WebDriver instance used to interact with the browser. :return: A boolean value indicating the success or failure of the refresh operation. """ try: refresh_button = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, "//button[contains(@class, 'btn-primary')]//i[contains(@class, 'fa-refresh')]/..")) ) refresh_button.click() time.sleep(2) # Wait for refresh to complete return True except Exception as e: print(f"Refresh failed: {e}") return False def send_sms(): """ Send an SMS message using the Twilio API client. This function initializes a Twilio client with the provided credentials (`account_sid` and `auth_token`) and sends a pre-defined SMS message to the recipient's phone number (`your_phone`) from the specified Twilio phone number (`twilio_phone`). The content of the message notifies users about the opening of the housemanship portal. The function prints the unique SID of the sent message as confirmation. :rtype: None :return: This function does not return a value. """ client = Client(account_sid, auth_token) message = client.messages.create( body="🏥 Housemanship portal is now OPEN! Login immediately!", from_=twilio_phone, to=your_phone ) print(f"SMS sent: {message.sid}") def main(): print("Starting portal monitor...") check_interval = 30 max_retries = 3 driver = None try: driver = setup_driver() if not initial_login(driver): print("Initial login failed. Exiting...") return while True: if check_portal_status(driver): print("Portal is open!") send_sms() break print(f"Portal still closed. Refreshing in {check_interval} seconds...") time.sleep(check_interval) retries = 0 while retries < max_retries: if refresh_page(driver): break retries += 1 print(f"Refresh attempt {retries} failed. Retrying...") time.sleep(5) if retries == max_retries: print("Multiple refresh attempts failed. Attempting to re-login...") if not initial_login(driver): print("Re-login failed. Exiting...") break except Exception as e: print(f"Unexpected error: {e}") finally: if driver: driver.quit() if __name__ == "__main__": main()
Leave a Comment