imseldrith commited on
Commit
03b32ac
Β·
verified Β·
1 Parent(s): 9e30224

Update cli.py

Browse files
Files changed (1) hide show
  1. cli.py +81 -88
cli.py CHANGED
@@ -1,37 +1,15 @@
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)
@@ -43,98 +21,113 @@ def create_scraping_thread(site: str):
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...")
 
 
 
1
  import threading
2
  import time
3
  import traceback
4
+ import sys
5
+
 
 
6
  from base import VERSION, LoginException, Scraper, Udemy, scraper_dict
7
  from colors import bw, by, fb, fg, fr
 
8
 
9
  # DUCE-CLI
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  def create_scraping_thread(site: str):
12
+ """Creates a separate thread for scraping each site."""
13
  code_name = scraper_dict[site]
14
  try:
15
  t = threading.Thread(target=getattr(scraper, code_name), daemon=True)
 
21
  if getattr(scraper, f"{code_name}_length") == -1:
22
  raise Exception(f"Error in: {site}")
23
 
24
+ prev_progress = 0
25
+ total = getattr(scraper, f"{code_name}_length")
26
+
27
+ while not getattr(scraper, f"{code_name}_done"):
28
+ time.sleep(0.5)
29
+ current_progress = getattr(scraper, f"{code_name}_progress")
30
+ percent = (current_progress / total) * 100 if total else 0
31
+ print(f"[{site}] Progress: {percent:.2f}%")
32
+ sys.stdout.flush()
33
+
34
+ print(f"[{site}] Scraping Completed βœ…")
35
+ sys.stdout.flush()
36
 
37
  except Exception as e:
38
+ error = getattr(scraper, f"{code_name}_error", traceback.format_exc())
39
+ print(f"[ERROR] {site}: {error}")
40
+ sys.stdout.flush()
41
 
42
+ ##########################################
43
 
 
44
  udemy = Udemy("cli")
45
  udemy.load_settings()
46
  login_title, main_title = udemy.check_for_update()
47
 
48
  if "Update" in login_title:
49
+ print(by + fr + login_title)
50
+ sys.stdout.flush()
51
 
52
+ ############## MAIN #############
 
53
 
54
+ login_successful = False
55
+ while not login_successful:
 
 
56
  try:
57
+ if udemy.settings["use_browser_cookies"]:
58
+ udemy.fetch_cookies()
59
+ login_method = "Browser Cookies"
60
+ elif udemy.settings["email"] and udemy.settings["password"]:
61
+ email, password = udemy.settings["email"], udemy.settings["password"]
62
+ login_method = "Saved Email and Password"
63
+ else:
64
+ email = input("Email: ")
65
+ password = input("Password: ")
66
+ login_method = "Email and Password"
67
+
68
+ print(fb + f"Trying to login using {login_method}")
69
+ sys.stdout.flush()
70
+
71
+ if "Email" in login_method:
 
 
 
 
 
 
72
  udemy.manual_login(email, password)
 
73
 
74
+ udemy.get_session_info()
75
+ if "Email" in login_method:
76
  udemy.settings["email"], udemy.settings["password"] = email, password
77
+ login_successful = True
78
+ except LoginException as e:
79
+ print(fr + f"Login Failed: {e}")
80
+ sys.stdout.flush()
81
+ if "Browser" in login_method:
82
+ print("Can't login using cookies. Switching to manual login.")
83
+ udemy.settings["use_browser_cookies"] = False
84
+ elif "Email" in login_method:
85
+ udemy.settings["email"], udemy.settings["password"] = "", ""
86
 
87
+ udemy.save_settings()
 
 
 
 
 
 
 
88
 
89
  print(fg + f"Logged in as {udemy.display_name}")
90
+ sys.stdout.flush()
91
+
92
+ user_dumb = udemy.is_user_dumb()
93
 
94
+ if user_dumb:
95
+ print(bw + fr + "Invalid user settings. Exiting...")
96
+ sys.stdout.flush()
97
  exit()
98
 
99
  scraper = Scraper(udemy.sites)
100
 
101
  try:
102
+ print("πŸ”Ž Starting Course Scraping...")
103
+ sys.stdout.flush()
104
+
105
  udemy.scraped_data = scraper.get_scraped_courses(create_scraping_thread)
106
  time.sleep(0.5)
 
107
 
108
+ print("\nβœ… Scraping Completed. Starting Enrollment...\n")
109
+ sys.stdout.flush()
110
+
111
  udemy.start_enrolling()
112
 
113
+ udemy.print(
114
+ f"\nβœ” Successfully Enrolled: {udemy.successfully_enrolled_c}", color="green"
115
+ )
116
+ udemy.print(
117
+ f"πŸ’° Amount Saved: {round(udemy.amount_saved_c,2)} {udemy.currency.upper()}",
118
+ color="light green",
119
+ )
120
+ udemy.print(f"πŸ”΅ Already Enrolled: {udemy.already_enrolled_c}", color="blue")
121
+ udemy.print(f"⚠️ Excluded Courses: {udemy.excluded_c}", color="yellow")
122
+ udemy.print(f"❌ Expired Courses: {udemy.expired_c}", color="red")
123
+
124
+ sys.stdout.flush()
125
 
126
  except Exception as e:
127
+ error = traceback.format_exc()
128
+ print(f"\n[ERROR] {error}\n")
129
+ sys.stdout.flush()
130
 
131
+ # βœ… Remove `input("Press Enter to exit...")` to prevent blocking in Flask
132
+ print("βœ… Process Completed!")
133
+ sys.stdout.flush()