udemyBot / gui.py
imseldrith's picture
Upload folder using huggingface_hub (#1)
a004773 verified
raw
history blame
20.9 kB
import sys
import threading
import time
import traceback
from webbrowser import open as web
import FreeSimpleGUI as sg
from base import LINKS, VERSION, LoginException, Scraper, Udemy, scraper_dict
from images import (
auto_login,
back,
check_mark,
exit_,
icon,
login,
logout,
manual_login_,
start,
)
sg.set_global_icon(icon)
sg.change_look_and_feel("dark")
sg.theme_background_color
sg.set_options(
button_color=(sg.theme_background_color(), sg.theme_background_color()),
border_width=0,
font=10,
)
def update_enrolled_courses():
while True:
new_menu = [
["Help", ["Support", "Github", "Discord"]],
[f"Total Courses: {len(udemy.enrolled_courses)}"],
]
main_window.write_event_value("Update-Menu", new_menu)
time.sleep(10)
def create_scraping_thread(site: str):
code_name = scraper_dict[site]
main_window[f"i{site}"].update(visible=False)
main_window[f"p{site}"].update(0, visible=True)
try:
threading.Thread(target=getattr(scraper, code_name), daemon=True).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}")
main_window[f"p{site}"].update(0, max=getattr(scraper, f"{code_name}_length"))
while not getattr(scraper, f"{code_name}_done") and not getattr(
scraper, f"{code_name}_error"
):
main_window[f"p{site}"].update(
getattr(scraper, f"{code_name}_progress") + 1
)
time.sleep(0.1) # Update every 0.1 seconds
if getattr(scraper, f"{code_name}_error"):
raise Exception(f"Error in: {site}")
except Exception:
error_message = getattr(scraper, f"{code_name}_error", "Unknown Error")
main_window.write_event_value(
"Error", f"{error_message}|:|Unknown Error in: {site} {VERSION}"
)
finally:
main_window[f"p{site}"].update(0, visible=False)
main_window[f"i{site}"].update(visible=True)
##########################################
def scrape():
try:
for site in udemy.sites:
main_window[f"pcol{site}"].update(visible=True)
main_window["main_col"].update(visible=False)
main_window["scrape_col"].update(visible=True)
udemy.scraped_data = scraper.get_scraped_courses(create_scraping_thread)
main_window["scrape_col"].update(visible=False)
main_window["output_col"].update(visible=True)
# ------------------------------------------
udemy.start_enrolling()
main_window["output_col"].Update(visible=False)
main_window["done_col"].update(visible=True)
main_window["se_c"].update(
value=f"Successfully Enrolled: {udemy.successfully_enrolled_c}"
)
main_window["as_c"].update(
value=f"Amount Saved: {round(udemy.amount_saved_c,2)} {udemy.currency.upper()}"
)
main_window["ae_c"].update(
value=f"Already Enrolled: {udemy.already_enrolled_c}"
)
main_window["e_c"].update(value=f"Expired Courses: {udemy.expired_c}")
main_window["ex_c"].update(value=f"Excluded Courses: {udemy.excluded_c}")
except Exception:
e = traceback.format_exc()
main_window.write_event_value(
"Error",
f"{e}\n\nVersion:{VERSION}\nLink:{getattr(udemy, 'link', 'None')}\nTitle:{getattr(udemy, 'title','None')}|:|Error g100",
)
#################################
udemy = Udemy("gui")
udemy.load_settings()
login_title, main_title = udemy.check_for_update()
menu = [["Help", ["Support", "Github", "Discord"]]]
login_error = False
try:
if udemy.settings["stay_logged_in"]["auto"]:
udemy.fetch_cookies()
elif udemy.settings["stay_logged_in"]["manual"]:
udemy.manual_login(udemy.settings["email"], udemy.settings["password"])
else:
raise LoginException("No Saved Login Found")
udemy.get_session_info()
except LoginException:
login_error = True
# if (
# not udemy.settings["stay_logged_in"]["auto"]
# and not udemy.settings["stay_logged_in"]["manual"]
# ) or login_error:
if login_error:
c1 = [
[
sg.Button(key="a_login", image_data=auto_login),
sg.T(""),
sg.B(key="m_login", image_data=manual_login_),
],
[
sg.Checkbox(
"Stay logged-in",
default=udemy.settings["stay_logged_in"]["auto"],
key="sli_a",
)
],
]
c2 = [
[
sg.T("Email"),
sg.InputText(
default_text=udemy.settings["email"],
key="email",
size=(20, 1),
pad=(5, 5),
),
],
[
sg.T("Password"),
sg.InputText(
default_text=udemy.settings["password"],
key="password",
size=(20, 1),
pad=(5, 5),
password_char="*",
),
],
[
sg.Checkbox(
"Stay logged-in",
default=udemy.settings["stay_logged_in"]["manual"],
key="sli_m",
)
],
[
sg.B(key="Back", image_data=back),
sg.T(" "),
sg.B(key="Login", image_data=login),
],
]
login_layout = [
[sg.Menu(menu)],
[sg.Column(c1, key="col1"), sg.Column(c2, visible=False, key="col2")],
]
login_window = sg.Window(login_title, login_layout, finalize=True)
login_window.bind("a", "a_login")
login_window.bind("m", "m_login")
while True:
event, values = login_window.read()
if event in (None,):
login_window.close()
sys.exit()
elif event == "a_login" and not login_window["a_login"].Disabled:
login_window["a_login"].update(disabled=True)
login_window.refresh()
try:
udemy.fetch_cookies()
try:
udemy.get_session_info()
udemy.settings["stay_logged_in"]["auto"] = values["sli_a"]
udemy.save_settings()
login_window.close()
break
except Exception:
e = traceback.format_exc()
print(e)
sg.popup_auto_close(
"Make sure you are logged in to udemy.com in chrome browser",
title="Error",
auto_close_duration=3,
no_titlebar=True,
)
except Exception:
e = traceback.format_exc()
sg.popup_scrolled(e, title=f"Unknown Error {VERSION}")
login_window["a_login"].update(disabled=False)
elif event == "m_login":
login_window["col1"].update(visible=False)
login_window["col2"].update(visible=True)
login_window["email"].update(value=udemy.settings["email"])
login_window["password"].update(value=udemy.settings["password"])
elif event == "Github":
web(LINKS["github"])
elif event == "Support":
web(LINKS["support"])
elif event == "Discord":
web(LINKS["discord"])
elif event == "Back":
login_window["col1"].update(visible=True)
login_window["col2"].update(visible=False)
elif event == "Login":
udemy.settings["email"] = values["email"]
udemy.settings["password"] = values["password"]
try:
try:
udemy.manual_login(
udemy.settings["email"], udemy.settings["password"]
)
udemy.get_session_info()
udemy.settings["stay_logged_in"]["manual"] = values["sli_m"]
udemy.save_settings()
login_window.close()
break
except LoginException as e:
sg.popup_auto_close(
e,
title="Error",
auto_close_duration=3,
no_titlebar=True,
)
except Exception:
e = traceback.format_exc()
sg.popup_scrolled(e, title=f"Unknown Error {VERSION}")
checkbox_lo = []
for key in udemy.settings["sites"]:
checkbox_lo.append(
[sg.Checkbox(key, key=key, default=udemy.settings["sites"][key], size=(18, 1))]
)
categories_lo = []
categories_k = list(udemy.settings["categories"].keys())
categories_v = list(udemy.settings["categories"].values())
for index, _ in enumerate(udemy.settings["categories"]):
if index % 3 == 0:
try:
categories_lo.append(
[
sg.Checkbox(
categories_k[index],
default=categories_v[index],
key=categories_k[index],
size=(18, 1),
),
sg.Checkbox(
categories_k[index + 1],
default=categories_v[index + 1],
key=categories_k[index + 1],
size=(18, 1),
),
sg.Checkbox(
categories_k[index + 2],
default=categories_v[index + 2],
key=categories_k[index + 2],
size=(18, 1),
),
]
)
except IndexError:
categories_lo.append(
[
sg.Checkbox(
categories_k[index],
default=categories_v[index],
key=categories_k[index],
size=(18, 1),
)
]
)
languages_lo = []
languages_k = list(udemy.settings["languages"].keys())
languages_v = list(udemy.settings["languages"].values())
for index, _ in enumerate(udemy.settings["languages"]):
if index % 3 == 0:
try:
languages_lo.append(
[
sg.Checkbox(
languages_k[index],
default=languages_v[index],
key=languages_k[index],
size=(10, 1),
),
sg.Checkbox(
languages_k[index + 1],
default=languages_v[index + 1],
key=languages_k[index + 1],
size=(10, 1),
),
sg.Checkbox(
languages_k[index + 2],
default=languages_v[index + 2],
key=languages_k[index + 2],
size=(10, 1),
),
]
)
except IndexError:
languages_lo.append(
[
sg.Checkbox(
languages_k[index],
default=languages_v[index],
key=languages_k[index],
size=(10, 1),
),
sg.Checkbox(
languages_k[index + 1],
default=languages_v[index + 1],
key=languages_k[index + 1],
size=(10, 1),
),
]
)
main_tab = [
[
sg.Frame(
"Websites",
checkbox_lo,
"#4deeea",
border_width=4,
title_location="n",
key="fcb",
),
sg.Frame(
"Language",
languages_lo,
"#4deeea",
border_width=4,
title_location="n",
key="fl",
),
],
[
sg.Frame(
"Category",
categories_lo,
"#4deeea",
border_width=4,
title_location="n",
key="fc",
)
],
]
instructor_ex_lo = [
[
sg.Multiline(
default_text=udemy.instructor_exclude,
key="instructor_exclude",
size=(15, 10),
)
],
[sg.Text("Paste instructor(s)\nusername in new lines")],
]
title_ex_lo = [
[
sg.Multiline(
default_text=udemy.title_exclude, key="title_exclude", size=(20, 10)
)
],
[sg.Text("Keywords in new lines\nNot cAsE sensitive")],
]
rating_lo = [
[
sg.Spin(
[i * 0.5 for i in range(11)],
initial_value=udemy.settings["min_rating"],
key="min_rating",
),
sg.Text("0.0 <-> 5.0"),
]
]
courses_last_updated_lo = [
[
sg.Text("Past"),
sg.Spin(
[i for i in range(1, 48)],
initial_value=udemy.settings["course_update_threshold_months"],
key="course_update_threshold_months",
),
sg.Text("Month(s)"),
]
]
advanced_tab = [
[
sg.Frame(
"Exclude Instructor",
instructor_ex_lo,
"#4deeea",
border_width=4,
title_location="n",
),
sg.Frame(
"Title Keyword Exclusion",
title_ex_lo,
"#4deeea",
border_width=4,
title_location="n",
),
],
[
sg.Frame(
"Minimum Rating",
rating_lo,
"#4deeea",
border_width=4,
title_location="n",
key="f_min_rating",
font=25,
),
sg.Frame(
"Course Last Updated",
courses_last_updated_lo,
"#4deeea",
border_width=4,
title_location="n",
key="f_course_last_updated",
font=25,
),
],
[
sg.Checkbox(
"Save enrolled courses in txt",
key="save_txt",
default=udemy.settings["save_txt"],
)
],
[
sg.Checkbox(
"Enrol in Discounted courses only",
key="discounted_only",
default=udemy.settings["discounted_only"],
)
],
]
scrape_col = []
for key in udemy.settings["sites"]:
scrape_col.append(
[
sg.pin(
sg.Column(
[
[
sg.Text(key, size=(12, 1)),
sg.ProgressBar(
3,
orientation="h",
key=f"p{key}",
bar_color=("#1c6fba", "#000000"),
border_width=1,
size=(20, 20),
),
sg.Image(data=check_mark, visible=False, key=f"i{key}"),
]
],
key=f"pcol{key}",
visible=False,
)
)
]
)
output_col = [
[sg.Text("Output")],
[sg.Multiline(size=(69, 12), key="out", autoscroll=False, disabled=True)],
# [
# sg.ProgressBar(
# 3,
# orientation="h",
# key="pout",
# bar_color=("#1c6fba", "#000000"),
# border_width=1,
# size=(46, 20),
# )
# ],
]
done_col = [
[sg.Text(" Stats", text_color="#FFD700")],
[
sg.Text(
"Successfully Enrolled: ",
key="se_c",
text_color="#7CFC00",
)
],
[
sg.Text(
"Amount Saved: $ ",
key="as_c",
text_color="#00FA9A",
)
],
[sg.Text("Already Enrolled: ", key="ae_c", text_color="#00FFFF")],
[sg.Text("Expired Courses: ", key="e_c", text_color="#FF0000")],
[sg.Text("Excluded Courses: ", key="ex_c", text_color="#FF4500")],
]
main_col = [
[
sg.TabGroup(
[[sg.Tab("Main", main_tab), sg.Tab("Advanced", advanced_tab)]],
border_width=2,
)
],
[
sg.Button(
key="Start",
tooltip="Once started will not stop until completed",
image_data=start,
)
],
]
if (
udemy.settings["stay_logged_in"]["auto"]
or udemy.settings["stay_logged_in"]["manual"]
):
logout_btn_lo = sg.Button(key="Logout", image_data=logout)
else:
logout_btn_lo = sg.Button(key="Logout", image_data=logout, visible=False)
main_lo = [
[
sg.Menu(
menu,
key="mn",
)
],
[sg.Text(f"Logged in as: {udemy.display_name}", key="user_t"), logout_btn_lo],
[
sg.pin(sg.Column(main_col, key="main_col")),
sg.pin(sg.Column(output_col, key="output_col", visible=False)),
sg.pin(sg.Column(scrape_col, key="scrape_col", visible=False)),
sg.pin(sg.Column(done_col, key="done_col", visible=False)),
],
[sg.Button(key="Exit", image_data=exit_)],
]
# ,sg.Button(key='Dummy',image_data=back)
global main_window
# position windows in center
main_window = sg.Window(
main_title,
main_lo,
finalize=True,
)
threading.Thread(target=update_enrolled_courses, daemon=True).start()
while True:
event, values = main_window.read()
if event == "Dummy":
print(values)
if event in (None, "Exit"):
break
elif event == "Logout":
(
udemy.settings["stay_logged_in"]["auto"],
udemy.settings["stay_logged_in"]["manual"],
) = (
False,
False,
)
udemy.save_settings()
break
elif event == "Support":
web(LINKS["support"])
elif event == "Github":
web(LINKS["github"])
elif event == "Discord":
web(LINKS["discord"])
elif event == "Start" and main_window["main_col"].visible:
# for key in udemy.settings["languages"]:
# udemy.settings["languages"][key] = values[key]
# for key in udemy.settings["categories"]:
# udemy.settings["categories"][key] = values[key]
# for key in udemy.settings["sites"]:
# udemy.settings["sites"][key] = values[key]
for setting in ["languages", "categories", "sites"]:
for key in udemy.settings[setting]:
udemy.settings[setting][key] = values[key]
udemy.settings["instructor_exclude"] = str(values["instructor_exclude"]).split()
udemy.settings["title_exclude"] = list(
filter(None, values["title_exclude"].split("\n"))
)
udemy.settings["min_rating"] = float(values["min_rating"])
udemy.settings["course_update_threshold_months"] = int(
values["course_update_threshold_months"]
)
udemy.settings["save_txt"] = values["save_txt"]
udemy.settings["discounted_only"] = values["discounted_only"]
udemy.save_settings()
user_dumb = udemy.is_user_dumb()
if user_dumb:
sg.popup_auto_close(
"What do you even expect to happen!",
auto_close_duration=5,
no_titlebar=True,
)
continue
scraper = Scraper(udemy.sites)
udemy.window = main_window
threading.Thread(target=scrape, daemon=True).start()
elif event == "Error":
msg = values["Error"].split("|:|")
e = msg[0]
title = msg[1]
sg.popup_scrolled(e, title=title)
elif event == "Update-Menu":
menu = values["Update-Menu"]
main_window["mn"].update(menu)
main_window.close()