Spaces:
Sleeping
Sleeping
import threading | |
import time | |
import traceback | |
import pickle | |
import os | |
import requests | |
import cloudscraper # Required for Udemy session handling | |
from base import VERSION, LoginException, Scraper, Udemy, scraper_dict | |
from colors import bw, by, fb, fg, fr | |
from requests.utils import cookiejar_from_dict, dict_from_cookiejar | |
# DUCE-CLI | |
COOKIE_FILE = "udemy_cookies.pkl" # File to store cookies | |
def save_cookies(session): | |
"""Save session cookies as a dictionary""" | |
with open(COOKIE_FILE, "wb") as f: | |
pickle.dump(dict_from_cookiejar(session.cookies), f) # Convert cookies to a dictionary | |
def load_cookies(): | |
"""Load cookies from a file if it exists and return as a dictionary""" | |
if os.path.exists(COOKIE_FILE): | |
with open(COOKIE_FILE, "rb") as f: | |
cookies = pickle.load(f) | |
if isinstance(cookies, dict): # Ensure cookies are stored as a dictionary | |
return cookies | |
return None | |
def create_scraping_thread(site: str): | |
"""Creates a separate thread to scrape 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}") | |
print(f"Scraping {site} completed successfully.") | |
except Exception as e: | |
error = traceback.format_exc() | |
print(f"Error in {site}: {error}") | |
############## MAIN ############# | |
udemy = Udemy("cli") | |
udemy.load_settings() | |
login_title, main_title = udemy.check_for_update() | |
if "Update" in login_title: | |
print(login_title) | |
login_successful = False | |
session = cloudscraper.create_scraper() # Use cloudscraper instead of requests.Session() | |
# Attempt to use saved cookies first | |
cookies = load_cookies() | |
if cookies: | |
print("Trying to log in using saved cookies...") | |
try: | |
session.cookies = cookiejar_from_dict(cookies) # Convert dict back to cookie jar | |
udemy.client = session # Attach session to Udemy object | |
udemy.cookie_dict = cookies # Set the cookie dictionary | |
udemy.get_session_info() # Check if session is valid | |
print(f"Logged in as {udemy.display_name} using cookies β ") | |
login_successful = True | |
except LoginException: | |
print("Cookies expired or invalid. Switching to manual login.") | |
os.remove(COOKIE_FILE) # Delete invalid cookies | |
# If cookies are not valid, use email/password login | |
if not login_successful: | |
while not login_successful: | |
try: | |
if udemy.settings.get("email") and udemy.settings.get("password"): | |
email, password = udemy.settings["email"], udemy.settings["password"] | |
print(f"Trying to log in using saved credentials: {email}") | |
else: | |
email = input("Email: ") | |
password = input("Password: ") | |
udemy.manual_login(email, password) | |
udemy.get_session_info() # Ensure login was successful | |
# Save successful login credentials | |
udemy.settings["email"], udemy.settings["password"] = email, password | |
udemy.save_settings() | |
# Save cookies after successful login | |
save_cookies(udemy.client) | |
print(f"Logged in as {udemy.display_name} β ") | |
login_successful = True | |
except LoginException as e: | |
print(f"Login Failed: {e}") | |
if "Browser" in login_title: | |
print("Can't login using cookies") | |
os.remove(COOKIE_FILE) # Delete invalid cookies | |
elif "Email" in login_title: | |
udemy.settings["email"], udemy.settings["password"] = "", "" | |
udemy.save_settings() | |
print(fg + f"Logged in as {udemy.display_name}") | |
# Check if the user has valid settings | |
if udemy.is_user_dumb(): | |
print(bw + fr + "Invalid settings! Exiting.") | |
exit() | |
scraper = Scraper(udemy.sites) | |
try: | |
# Scrape courses | |
print("Starting to scrape free Udemy courses...") | |
udemy.scraped_data = scraper.get_scraped_courses(create_scraping_thread) | |
time.sleep(0.5) | |
print("\nScraping completed. Enrolling in courses...\n") | |
# Start enrolling | |
udemy.start_enrolling() | |
print(f"\nSuccessfully Enrolled: {udemy.successfully_enrolled_c}") | |
print(f"Amount Saved: {round(udemy.amount_saved_c, 2)} {udemy.currency.upper()}") | |
print(f"Already Enrolled: {udemy.already_enrolled_c}") | |
print(f"Excluded Courses: {udemy.excluded_c}") | |
print(f"Expired Courses: {udemy.expired_c}") | |
except Exception as e: | |
print(f"Error:\n{traceback.format_exc()}\n") | |
input("Press Enter to exit...") |