import threading import time import traceback import sys from base import VERSION, LoginException, Scraper, Udemy, scraper_dict from colors import bw, by, fb, fg, fr # DUCE-CLI def create_scraping_thread(site: str): """Creates a separate thread for scraping each site.""" code_name = scraper_dict[site] try: t = threading.Thread(target=getattr(scraper, code_name), daemon=True) t.start() while getattr(scraper, f"{code_name}_length") == 0: time.sleep(0.1) # Avoid busy waiting if getattr(scraper, f"{code_name}_length") == -1: raise Exception(f"Error in: {site}") prev_progress = 0 total = getattr(scraper, f"{code_name}_length") while not getattr(scraper, f"{code_name}_done"): time.sleep(0.5) current_progress = getattr(scraper, f"{code_name}_progress") percent = (current_progress / total) * 100 if total else 0 print(f"[{site}] Progress: {percent:.2f}%") sys.stdout.flush() print(f"[{site}] Scraping Completed āœ…") sys.stdout.flush() except Exception as e: error = getattr(scraper, f"{code_name}_error", traceback.format_exc()) print(f"[ERROR] {site}: {error}") sys.stdout.flush() ########################################## udemy = Udemy("cli") udemy.load_settings() login_title, main_title = udemy.check_for_update() if "Update" in login_title: print(by + fr + login_title) sys.stdout.flush() ############## MAIN ############# login_successful = False while not login_successful: try: if udemy.settings["use_browser_cookies"]: udemy.fetch_cookies() login_method = "Browser Cookies" elif udemy.settings["email"] and udemy.settings["password"]: email, password = udemy.settings["email"], udemy.settings["password"] login_method = "Saved Email and Password" else: email = input("Email: ") password = input("Password: ") login_method = "Email and Password" print(fb + f"Trying to login using {login_method}") sys.stdout.flush() if "Email" in login_method: udemy.manual_login(email, password) udemy.get_session_info() if "Email" in login_method: udemy.settings["email"], udemy.settings["password"] = email, password login_successful = True except LoginException as e: print(fr + f"Login Failed: {e}") sys.stdout.flush() if "Browser" in login_method: print("Can't login using cookies. Switching to manual login.") udemy.settings["use_browser_cookies"] = False elif "Email" in login_method: udemy.settings["email"], udemy.settings["password"] = "", "" udemy.save_settings() print(fg + f"Logged in as {udemy.display_name}") sys.stdout.flush() user_dumb = udemy.is_user_dumb() if user_dumb: print(bw + fr + "Invalid user settings. Exiting...") sys.stdout.flush() exit() scraper = Scraper(udemy.sites) try: print("šŸ”Ž Starting Course Scraping...") sys.stdout.flush() udemy.scraped_data = scraper.get_scraped_courses(create_scraping_thread) time.sleep(0.5) print("\nāœ… Scraping Completed. Starting Enrollment...\n") sys.stdout.flush() udemy.start_enrolling() udemy.print( f"\nāœ” Successfully Enrolled: {udemy.successfully_enrolled_c}", color="green" ) udemy.print( f"šŸ’° Amount Saved: {round(udemy.amount_saved_c,2)} {udemy.currency.upper()}", color="light green", ) udemy.print(f"šŸ”µ Already Enrolled: {udemy.already_enrolled_c}", color="blue") udemy.print(f"āš ļø Excluded Courses: {udemy.excluded_c}", color="yellow") udemy.print(f"āŒ Expired Courses: {udemy.expired_c}", color="red") sys.stdout.flush() except Exception as e: error = traceback.format_exc() print(f"\n[ERROR] {error}\n") sys.stdout.flush() # āœ… Remove `input("Press Enter to exit...")` to prevent blocking in Flask print("āœ… Process Completed!") sys.stdout.flush()