import os import time import requests import logging from datetime import datetime # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # Load configuration LOGIN = os.getenv('EDU_LOGIN') PASSWORD = os.getenv('EDU_PASSWORD') URL_LOGIN = os.getenv('EDU_URL_LOGIN', 'https://edu.edu.vn.ua/user/login') URL_VERIFY = os.getenv('EDU_URL_VERIFY', 'https://edu.edu.vn.ua/course/userlist') INTERVAL = int(os.getenv('EDU_INTERVAL', 10)) USER_AGENT = os.getenv('EDU_USER_AGENT', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36') INITIAL_PHPSESSID = os.getenv('EDU_PHPSESSID') SUCCESS_FILE = '/tmp/last_success' def touch_success_file(): """Updates the timestamp of the success file for healthchecks.""" try: with open(SUCCESS_FILE, 'w') as f: f.write(str(datetime.now().timestamp())) except Exception as e: logger.error(f"Failed to touch success file: {e}") def main(): logger.info("Starting Session Keeper Bot") session = requests.Session() # Set headers headers = { 'User-Agent': USER_AGENT, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'Accept-Language': 'en-US,en;q=0.9', 'Cache-Control': 'max-age=0', 'Upgrade-Insecure-Requests': '1', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-User': '?1', 'Sec-Fetch-Dest': 'document', 'Sec-Ch-Ua': '"Not_A Brand";v="99", "Chromium";v="142"', 'Sec-Ch-Ua-Mobile': '?0', 'Sec-Ch-Ua-Platform': '"Linux"', 'Accept-Encoding': 'gzip, deflate, br', 'Priority': 'u=0, i' } session.headers.update(headers) # If an initial PHPSESSID is provided, set it in the session if INITIAL_PHPSESSID: logger.info(f"Setting initial PHPSESSID: {INITIAL_PHPSESSID}") session.cookies.set('PHPSESSID', INITIAL_PHPSESSID, domain='edu.edu.vn.ua') while True: try: logger.info("Attempting login...") # Login payload payload = { 'login': LOGIN, 'password': PASSWORD } # Perform Login # Note: The user request shows a POST to /user/login with form data # We need to make sure we handle the PHPSESSID correctly. # If we already have a PHPSESSID, requests will send it. login_response = session.post(URL_LOGIN, data=payload, allow_redirects=True) logger.info(f"Login Response Status: {login_response.status_code}") logger.info(f"Cookies after login: {session.cookies.get_dict()}") # Verify Session logger.info("Verifying session...") verify_response = session.get(URL_VERIFY, allow_redirects=False) logger.info(f"Verify Response Status: {verify_response.status_code}") if verify_response.status_code == 200: logger.info("Session verification SUCCESS (200 OK).") touch_success_file() elif verify_response.status_code == 302: logger.warning("Session verification FAILED (302 Redirect). Session might be invalid.") else: logger.warning(f"Session verification returned unexpected status: {verify_response.status_code}") except Exception as e: logger.error(f"An error occurred: {e}") logger.info(f"Sleeping for {INTERVAL} minutes...") time.sleep(INTERVAL * 60) if __name__ == "__main__": main()