imseldrith commited on
Commit
ffccd9e
·
verified ·
1 Parent(s): c6654f0

Update cli.py

Browse files
Files changed (1) hide show
  1. cli.py +140 -115
cli.py CHANGED
@@ -1,115 +1,140 @@
1
- import threading
2
- import time
3
- import traceback
4
-
5
- from tqdm import tqdm
6
-
7
- from base import VERSION, LoginException, Scraper, Udemy, scraper_dict
8
- from colors import bw, by, fb, fg, fr
9
-
10
- # DUCE-CLI
11
-
12
-
13
- def create_scraping_thread(site: str):
14
-
15
- code_name = scraper_dict[site]
16
- try:
17
- t = threading.Thread(target=getattr(scraper, code_name), daemon=True)
18
- t.start()
19
-
20
- while getattr(scraper, f"{code_name}_length") == 0:
21
- time.sleep(0.1) # Avoid busy waiting
22
- if getattr(scraper, f"{code_name}_length") == -1:
23
- raise Exception(f"Error in: {site}")
24
- progress_bar = tqdm(
25
- total=getattr(scraper, f"{code_name}_length"), desc=site, leave=False
26
- )
27
- prev_progress = -1
28
-
29
- while not getattr(scraper, f"{code_name}_done"):
30
- time.sleep(0.1)
31
- current_progress = getattr(scraper, f"{code_name}_progress")
32
- progress_bar.update(current_progress - prev_progress)
33
- prev_progress = current_progress
34
-
35
- progress_bar.update(getattr(scraper, f"{code_name}_length") - prev_progress)
36
-
37
- except Exception:
38
- error = getattr(scraper, f"{code_name}_error", traceback.format_exc())
39
- print(error)
40
- print("\nError in: " + site + " " + str(VERSION))
41
-
42
-
43
- ##########################################
44
-
45
- udemy = Udemy("cli")
46
- udemy.load_settings()
47
- login_title, main_title = udemy.check_for_update()
48
- if login_title.__contains__("Update"):
49
- print(by + fr + login_title)
50
-
51
- ############## MAIN #############
52
-
53
- login_successful = False
54
- while not login_successful:
55
- try:
56
- if udemy.settings["use_browser_cookies"]:
57
- udemy.fetch_cookies()
58
- login_method = "Browser Cookies"
59
- elif udemy.settings["email"] and udemy.settings["password"]:
60
- email, password = udemy.settings["email"], udemy.settings["password"]
61
- login_method = "Saved Email and Password"
62
- else:
63
- email = input("Email: ")
64
- password = input("Password: ")
65
- login_method = "Email and Password"
66
- print(fb + f"Trying to login using {login_method}")
67
- if "Email" in login_method:
68
- udemy.manual_login(email, password)
69
- udemy.get_session_info()
70
- if "Email" in login_method:
71
- udemy.settings["email"], udemy.settings["password"] = email, password
72
- login_successful = True
73
- except LoginException as e:
74
- print(fr + str(e))
75
- if "Browser" in login_method:
76
- print("Cant login using cookies")
77
- udemy.settings["use_browser_cookies"] = False
78
- elif "Email" in login_method:
79
- udemy.settings["email"], udemy.settings["password"] = "", ""
80
-
81
- udemy.save_settings()
82
-
83
- print(fg + f"Logged in as {udemy.display_name}")
84
- user_dumb = udemy.is_user_dumb()
85
- if user_dumb:
86
- print(bw + fr + "What do you even expect to happen!")
87
- exit()
88
- if not user_dumb:
89
- scraper = Scraper(udemy.sites)
90
- try:
91
- udemy.scraped_data = scraper.get_scraped_courses(create_scraping_thread)
92
- time.sleep(0.5)
93
- print("\n")
94
- udemy.start_enrolling()
95
-
96
- udemy.print(
97
- f"\nSuccessfully Enrolled: {udemy.successfully_enrolled_c}", color="green"
98
- )
99
- udemy.print(
100
- f"Amount Saved: {round(udemy.amount_saved_c,2)} {udemy.currency.upper()}",
101
- color="light green",
102
- )
103
- udemy.print(f"Already Enrolled: {udemy.already_enrolled_c}", color="blue")
104
- udemy.print(f"Excluded Courses: {udemy.excluded_c}", color="yellow")
105
- udemy.print(f"Expired Courses: {udemy.expired_c}", color="red")
106
-
107
- except:
108
- e = traceback.format_exc()
109
- print(
110
- (
111
- "Error",
112
- e + f"\n\n{udemy.link}\n{udemy.title}" + f"|:|Unknown Error {VERSION}",
113
- )
114
- )
115
- input("Press Enter to exit...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import threading
2
+ import time
3
+ import traceback
4
+ import pickle
5
+ import os
6
+ import requests
7
+ import cloudscraper # Required for Udemy session handling
8
+ from base import VERSION, LoginException, Scraper, Udemy, scraper_dict
9
+ from colors import bw, by, fb, fg, fr
10
+ from requests.utils import cookiejar_from_dict, dict_from_cookiejar
11
+
12
+ # DUCE-CLI
13
+
14
+ COOKIE_FILE = "udemy_cookies.pkl" # File to store cookies
15
+
16
+
17
+ def save_cookies(session):
18
+ """Save session cookies as a dictionary"""
19
+ with open(COOKIE_FILE, "wb") as f:
20
+ pickle.dump(dict_from_cookiejar(session.cookies), f) # Convert cookies to a dictionary
21
+
22
+
23
+ def load_cookies():
24
+ """Load cookies from a file if it exists and return as a dictionary"""
25
+ if os.path.exists(COOKIE_FILE):
26
+ with open(COOKIE_FILE, "rb") as f:
27
+ cookies = pickle.load(f)
28
+ if isinstance(cookies, dict): # Ensure cookies are stored as a dictionary
29
+ return cookies
30
+ return None
31
+
32
+
33
+ def create_scraping_thread(site: str):
34
+ """Creates a separate thread to scrape each site"""
35
+ code_name = scraper_dict[site]
36
+ try:
37
+ t = threading.Thread(target=getattr(scraper, code_name), daemon=True)
38
+ t.start()
39
+
40
+ while getattr(scraper, f"{code_name}_length") == 0:
41
+ time.sleep(0.1) # Avoid busy waiting
42
+
43
+ if getattr(scraper, f"{code_name}_length") == -1:
44
+ raise Exception(f"Error in: {site}")
45
+
46
+ print(f"Scraping {site} completed successfully.")
47
+
48
+ except Exception as e:
49
+ error = traceback.format_exc()
50
+ print(f"Error in {site}: {error}")
51
+
52
+
53
+ ############## MAIN #############
54
+ udemy = Udemy("cli")
55
+ udemy.load_settings()
56
+ login_title, main_title = udemy.check_for_update()
57
+
58
+ if "Update" in login_title:
59
+ print(login_title)
60
+
61
+ login_successful = False
62
+ session = cloudscraper.create_scraper() # Use cloudscraper instead of requests.Session()
63
+
64
+ # Attempt to use saved cookies first
65
+ cookies = load_cookies()
66
+ if cookies:
67
+ print("Trying to log in using saved cookies...")
68
+ try:
69
+ session.cookies = cookiejar_from_dict(cookies) # Convert dict back to cookie jar
70
+ udemy.client = session # Attach session to Udemy object
71
+ udemy.cookie_dict = cookies # Set the cookie dictionary
72
+ udemy.get_session_info() # Check if session is valid
73
+ print(f"Logged in as {udemy.display_name} using cookies ✅")
74
+ login_successful = True
75
+ except LoginException:
76
+ print("Cookies expired or invalid. Switching to manual login.")
77
+ os.remove(COOKIE_FILE) # Delete invalid cookies
78
+
79
+ # If cookies are not valid, use email/password login
80
+ if not login_successful:
81
+ while not login_successful:
82
+ try:
83
+ if udemy.settings.get("email") and udemy.settings.get("password"):
84
+ email, password = udemy.settings["email"], udemy.settings["password"]
85
+ print(f"Trying to log in using saved credentials: {email}")
86
+ else:
87
+ email = input("Email: ")
88
+ password = input("Password: ")
89
+
90
+ udemy.manual_login(email, password)
91
+ udemy.get_session_info() # Ensure login was successful
92
+
93
+ # Save successful login credentials
94
+ udemy.settings["email"], udemy.settings["password"] = email, password
95
+ udemy.save_settings()
96
+
97
+ # Save cookies after successful login
98
+ save_cookies(udemy.client)
99
+
100
+ print(f"Logged in as {udemy.display_name} ✅")
101
+ login_successful = True
102
+
103
+ except LoginException as e:
104
+ print(f"Login Failed: {e}")
105
+ if "Browser" in login_title:
106
+ print("Can't login using cookies")
107
+ os.remove(COOKIE_FILE) # Delete invalid cookies
108
+ elif "Email" in login_title:
109
+ udemy.settings["email"], udemy.settings["password"] = "", ""
110
+ udemy.save_settings()
111
+
112
+ print(fg + f"Logged in as {udemy.display_name}")
113
+
114
+ # Check if the user has valid settings
115
+ if udemy.is_user_dumb():
116
+ print(bw + fr + "Invalid settings! Exiting.")
117
+ exit()
118
+
119
+ scraper = Scraper(udemy.sites)
120
+
121
+ try:
122
+ # Scrape courses
123
+ print("Starting to scrape free Udemy courses...")
124
+ udemy.scraped_data = scraper.get_scraped_courses(create_scraping_thread)
125
+ time.sleep(0.5)
126
+ print("\nScraping completed. Enrolling in courses...\n")
127
+
128
+ # Start enrolling
129
+ udemy.start_enrolling()
130
+
131
+ print(f"\nSuccessfully Enrolled: {udemy.successfully_enrolled_c}")
132
+ print(f"Amount Saved: {round(udemy.amount_saved_c, 2)} {udemy.currency.upper()}")
133
+ print(f"Already Enrolled: {udemy.already_enrolled_c}")
134
+ print(f"Excluded Courses: {udemy.excluded_c}")
135
+ print(f"Expired Courses: {udemy.expired_c}")
136
+
137
+ except Exception as e:
138
+ print(f"Error:\n{traceback.format_exc()}\n")
139
+
140
+ input("Press Enter to exit...")