diff --git a/Helpers/__init__.py b/Helpers/__init__.py index 11feeb4..4402f2b 100644 --- a/Helpers/__init__.py +++ b/Helpers/__init__.py @@ -6,4 +6,5 @@ from . import cache_key from . import mpd_parse from . import download from . import binary_check -from . import os_check \ No newline at end of file +from . import os_check +from . import gui \ No newline at end of file diff --git a/Helpers/binary_check.py b/Helpers/binary_check.py index d8e523a..6df6bdf 100644 --- a/Helpers/binary_check.py +++ b/Helpers/binary_check.py @@ -304,6 +304,7 @@ def create_binaries(): # Remove binary from download folder if Linux if operating_system == "Linux": + os.remove(f"{os.getcwd()}/download/temp/yt-dlp.tar.gz") shutil.rmtree(f"{os.getcwd()}/download/temp/yt-dlp") # Print a new line diff --git a/Helpers/download.py b/Helpers/download.py index 385e75e..f5c21fb 100644 --- a/Helpers/download.py +++ b/Helpers/download.py @@ -25,9 +25,9 @@ def web_dl_generic(mpd: str = None, device: str = None, api_key: str = None, rem # Retrieve the keys if not remote: - mp4decrypt_keys = Sites.Generic.decrypt_generic(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers) + mp4decrypt_keys, _ = Sites.Generic.decrypt_generic(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers) if remote: - mp4decrypt_keys = Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd) + mp4decrypt_keys, _ = Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd) # Define n_m3u8dl-re download parameters n_m3u8dl_re_download = [ @@ -79,9 +79,9 @@ def web_dl_crunchyroll(mpd: str = None, device: str = None, api_key: str = None, # Retrieve the keys if not remote: - mp4decrypt_keys = Sites.Crunchyroll.decrypt_crunchyroll(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers) + mp4decrypt_keys, _ = Sites.Crunchyroll.decrypt_crunchyroll(mpd_url=mpd, wvd=device, license_curl_headers=license_curl.headers) if remote: - mp4decrypt_keys = Sites.Crunchyroll.decrypt_crunchyroll_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd) + mp4decrypt_keys, _ = Sites.Crunchyroll.decrypt_crunchyroll_remotely(api_key=api_key, license_curl_headers=license_curl.headers, mpd_url=mpd) # Define n_m3u8dl-re download parameters n_m3u8dl_re_download = [ @@ -135,9 +135,9 @@ def youtube_dlp(url: str = None, device: str = None, api_key: str = None, remote # Retrieve the keys if not remote: - mp4decrypt_keys = Sites.YouTube.decrypt_youtube(wvd=device, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies) + mp4decrypt_keys, _ = Sites.YouTube.decrypt_youtube(wvd=device, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies) if remote: - mp4decrypt_keys = Sites.YouTube.decrypt_youtube_remotely(api_key=api_key, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies) + mp4decrypt_keys, _ = Sites.YouTube.decrypt_youtube_remotely(api_key=api_key, license_curl_headers=license_curl.headers, license_curl_json=license_curl.json_data, license_curl_cookies=license_curl.cookies) # Define yt-dlp download parameters yt_dlp_download = [ diff --git a/Helpers/gui.py b/Helpers/gui.py new file mode 100644 index 0000000..1e358fb --- /dev/null +++ b/Helpers/gui.py @@ -0,0 +1,195 @@ +import PySimpleGUI as sg +import Sites +import ast + + +def clean_dict(dict: str = None): + header_string = f"'''" \ + f"{dict}" \ + f"'''" + cleaned_string = '\n'.join(line for line in header_string.split('\n') if not line.strip().startswith('#')) + clean_dict = ast.literal_eval(cleaned_string) + return clean_dict + + +def start_gui(wvd: str = None, api_key: str = None): + + sg.theme('Dark Amber') # Add theme + + # 1- the layout + left_frame_normal = sg.Col([ + [sg.Text('PSSH:'), sg.Text(size=(15, 1), key='-PSSH_TEXT-')], + [sg.Input(key="-PSSH-")], + [sg.Text(text='License URL:'), sg.Text(size=(15, 1), key='-LIC_URL_TEXT-')], + [sg.Input(key='-LIC_URL-')], + [sg.Text('Keys:')], + [sg.Output(size=(45, 6), key='-OUTPUT-')], + [sg.Button('Decrypt'), sg.Button('Reset')] + ], p=0) + + right_frame_normal = sg.Col([ + [sg.Text('Headers:')], + [sg.Multiline(key='-HEADERS-', size=(50, 10))], + [sg.Text('JSON:', key='-JSON_TEXT-', visible=False)], + [sg.Multiline(key='-JSON-', size=(50, 10), visible=False)], + [sg.Text('Cookies:', key='-COOKIES_TEXT-', visible=False)], + [sg.Multiline(key='-COOKIES-', size=(50, 10), visible=False)], + [sg.Combo(values=['Generic', 'Crunchyroll', 'YouTube'], default_value='Generic', key='-OPTIONS-', enable_events=True),sg.Push(), sg.Checkbox(text="Use CDM-Project API", key='-USE_API-')] + ], p=0) + + window_layout = [ + [left_frame_normal, right_frame_normal] + ] + + # 2 - the window + window = sg.Window('TPD-Keys', layout=window_layout) + + # 3 - the event loop + while True: + + event, values = window.read() + + if event == sg.WIN_CLOSED: + break + + if event == 'Decrypt': + + if values['-PSSH-'] != '' and values['-LIC_URL-'] == '' and values['-OPTIONS-'] == 'Generic': + window['-OUTPUT-'].update(f"No License URL provided") + + if values['-LIC_URL-'] != '' and values['-PSSH-'] == '' and values['-OPTIONS-'] == 'Generic': + window['-OUTPUT-'].update(f"No PSSH provided") + + if values['-PSSH-'] == '' and values['-LIC_URL-'] == '' and values['-OPTIONS-'] == 'Generic': + window['-OUTPUT-'].update(f"No PSSH or License URL provided") + + if values['-PSSH-'] != '' and values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'Generic': + if values['-HEADERS-'] == '': + if not values['-USE_API-']: + try: + _, key_out = Sites.Generic.decrypt_generic(wvd=wvd, in_pssh=values['-PSSH-'], + in_license_url=values['-LIC_URL-']) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + if values['-USE_API-']: + try: + _, key_out = Sites.Generic.decrypt_generic_remotely(api_key=api_key, in_pssh=values['-PSSH-'], + in_license_url=values['-LIC_URL-']) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + + if values['-HEADERS-'] != '': + if not values['-USE_API-']: + try: + _, key_out = Sites.Generic.decrypt_generic(wvd=wvd, in_pssh=values['-PSSH-'], + in_license_url=values['-LIC_URL-'], + license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-']))) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + if values['-USE_API-']: + try: + _, key_out = Sites.Generic.decrypt_generic_remotely(api_key=api_key, + in_pssh=values['-PSSH-'], + in_license_url=values['-LIC_URL-'], + license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-']))) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + + if values['-PSSH-'] != '' and values['-OPTIONS-'] == 'Crunchyroll' and values['-HEADERS-'] != '': + if not values['-USE_API-']: + try: + _, key_out = Sites.Crunchyroll.decrypt_crunchyroll(wvd=wvd, in_pssh=values['-PSSH-'], + license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-']))) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + if values['-USE_API-']: + try: + _, key_out = Sites.Crunchyroll.decrypt_crunchyroll_remotely(api_key=api_key, in_pssh=values['-PSSH-'], + license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-']))) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + + if values['-PSSH-'] != '' and values['-OPTIONS-'] == 'Crunchyroll' and values['-HEADERS-'] == '': + window['-OUTPUT-'].update(f"No Headers provided") + + if values['-PSSH-'] == '' and values['-OPTIONS-'] == 'Crunchyroll': + window['-OUTPUT-'].update(f"No PSSH provided") + + if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-HEADERS-'] != '' and values['-JSON-'] != '' and values['-COOKIES-'] != '': + if not values['-USE_API-']: + try: + _, key_out = Sites.YouTube.decrypt_youtube(wvd=wvd, in_license_url=values['-LIC_URL-'], + license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])), + license_curl_json=ast.literal_eval(clean_dict(dict=values['-JSON-'])), + license_curl_cookies=ast.literal_eval(clean_dict(dict=values['-COOKIES-']))) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + if values['-USE_API-']: + try: + _, key_out = Sites.YouTube.decrypt_youtube_remotely(api_key=api_key, in_license_url=values['-LIC_URL-'], + license_curl_headers=ast.literal_eval(clean_dict(dict=values['-HEADERS-'])), + license_curl_json=ast.literal_eval(clean_dict(dict=values['-JSON-'])), + license_curl_cookies=ast.literal_eval(clean_dict(dict=values['-COOKIES-']))) + window['-OUTPUT-'].update(f"{key_out}") + except Exception as error: + window['-OUTPUT-'].update(f"{error}") + + if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-HEADERS-'] == '' and values['-JSON-'] != '' and values['-COOKIES-'] != '': + window['-OUTPUT-'].update(f"No Headers provided") + + if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-JSON-'] == '' and values['-HEADERS-'] != '' and values['-COOKIES-'] != '': + window['-OUTPUT-'].update(f"No JSON provided") + + if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-COOKIES-'] == '' and values['-HEADERS-'] != '' and values['-JSON-'] != '': + window['-OUTPUT-'].update(f"No Cookies provided") + + if values['-LIC_URL-'] != '' and values['-OPTIONS-'] == 'YouTube' and values['-HEADERS-'] == '' and values['-JSON-'] == '' and values['-COOKIES-'] == '': + window['-OUTPUT-'].update(f"All fields empty!") + + if values['-LIC_URL-'] == '' and values['-OPTIONS-'] == 'YouTube': + window['-OUTPUT-'].update(f"No license URL provided") + + + if event == 'Reset': + window['-PSSH-'].update(value="", disabled=False) + window['-LIC_URL-'].update(value="", disabled=False) + window['-OUTPUT-'].update(value="", disabled=False) + window['-HEADERS-'].update(value="", disabled=False) + window['-OPTIONS-'].update(value="Generic", disabled=False) + + if event == '-OPTIONS-' and values['-OPTIONS-'] == 'Crunchyroll': + window['-PSSH-'].update(value="", disabled=False) + window['-LIC_URL-'].update(value="", disabled=True) + window['-JSON-'].update(visible=False) + window['-JSON_TEXT-'].update(visible=False) + window['-COOKIES-'].update(visible=False) + window['-COOKIES_TEXT-'].update(visible=False) + + if event == '-OPTIONS-' and values['-OPTIONS-'] == 'Generic': + window['-PSSH-'].update(value="", disabled=False) + window['-LIC_URL-'].update(value="", disabled=False) + window['-JSON-'].update(visible=False) + window['-JSON_TEXT-'].update(visible=False) + window['-COOKIES-'].update(visible=False) + window['-COOKIES_TEXT-'].update(visible=False) + + if event == '-OPTIONS-' and values['-OPTIONS-'] == 'YouTube': + window['-PSSH-'].update(value="", disabled=True) + window['-LIC_URL-'].update(value="", disabled=False) + window['-JSON-'].update(visible=True) + window['-JSON_TEXT-'].update(visible=True) + window['-COOKIES-'].update(visible=True) + window['-COOKIES_TEXT-'].update(visible=True) + + + + + # 4 - the close + window.close() diff --git a/Sites/Crunchyroll.py b/Sites/Crunchyroll.py index 96dec30..d5c8716 100644 --- a/Sites/Crunchyroll.py +++ b/Sites/Crunchyroll.py @@ -10,7 +10,8 @@ import Helpers # Defining decrypt function for Crunchyroll -def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None): +def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None, + in_pssh: str = None): # Exit if no device if wvd is None: @@ -25,12 +26,15 @@ def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_ input_pssh = input(f"\nPSSH not found! Input PSSH: ") # Ask for PSSH if just keys function - if mpd_url is None: + if mpd_url is None and in_pssh is None: # Ask for PSSH if web-dl not selected: input_pssh = input(f"\nPSSH: ") # prepare pssh - pssh = PSSH(input_pssh) + if in_pssh is None: + pssh = PSSH(input_pssh) + if in_pssh is not None: + pssh = PSSH(in_pssh) # load device device = Device.load(wvd) @@ -93,17 +97,21 @@ def decrypt_crunchyroll(wvd: str = None, license_curl_headers: dict = None, mpd_ cdm.close(session_id) # Cache the keys - Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys) + if in_pssh is None: + Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys) + if in_pssh is not None: + Helpers.cache_key.cache_keys(pssh=in_pssh, keys=returned_keys) # Print out the keys print(f'\nKeys:\n{returned_keys}') # Return the keys for future ripper use. - return mp4decrypt_keys + return mp4decrypt_keys, returned_keys # Defining remote decrypt function for Crunchyroll -def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None): +def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None, + in_pssh: str = None): # Exit if no device if api_key is None: @@ -116,7 +124,7 @@ def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict api_device = "CDM" # Try getting pssh via MPD URL if web-dl - if mpd_url is not None: + if mpd_url is not None and in_pssh is None: input_pssh = Helpers.mpd_parse.parse_pssh(mpd_url) if input_pssh is not None: print(f'\nPSSH found: {input_pssh}') @@ -124,10 +132,13 @@ def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict input_pssh = input(f"\nPSSH not found! Input PSSH: ") # Ask for PSSH if just keys function - if mpd_url is None: + if mpd_url is None and in_pssh is None: # Ask for PSSH if web-dl not selected: input_pssh = input(f"\nPSSH: ") + if in_pssh is not None: + input_pssh = in_pssh + # Set headers for API key api_key_headers = { "X-Secret-Key": api_key @@ -198,4 +209,4 @@ def decrypt_crunchyroll_remotely(api_key: str = None, license_curl_headers: dict requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers) # return mp4decrypt keys - return mp4decrypt_keys + return mp4decrypt_keys, returned_keys diff --git a/Sites/Generic.py b/Sites/Generic.py index db0e958..0c0a7c6 100644 --- a/Sites/Generic.py +++ b/Sites/Generic.py @@ -10,7 +10,8 @@ import Helpers # Defining decrypt function for generic services -def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None): +def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url: str = None, + in_pssh: str = None, in_license_url: str = None): # Exit if no device if wvd is None: @@ -25,16 +26,22 @@ def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url: input_pssh = input(f"\nPSSH not found! Input PSSH: ") # Ask for PSSH if just keys function - if mpd_url is None: + if mpd_url is None and in_pssh is None: # Ask for PSSH if web-dl not selected: input_pssh = input(f"\nPSSH: ") # prepare pssh - pssh = PSSH(input_pssh) + if in_pssh is None: + pssh = PSSH(input_pssh) + if in_pssh is not None: + pssh = PSSH(in_pssh) # Ask for license URL - license_url = input(f"\nLicense URL: ") + if in_license_url is None: + license_url = input(f"\nLicense URL: ") + if in_license_url is not None: + license_url = in_license_url # load device device = Device.load(wvd) @@ -97,16 +104,21 @@ def decrypt_generic(wvd: str = None, license_curl_headers: dict = None, mpd_url: cdm.close(session_id) # Cache the keys - Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys) + if in_pssh is None: + Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys) + if in_pssh is not None: + Helpers.cache_key.cache_keys(pssh=in_pssh, keys=returned_keys) # Print out the keys print(f'\nKeys:\n{returned_keys}') # Return the keys for future ripper use. - return mp4decrypt_keys + return mp4decrypt_keys, returned_keys + # Defining remote decrypt function for generic services -def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None): +def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = None, mpd_url: str = None, + in_pssh: str = None, in_license_url: str = None): # Exit if no API key if api_key is None: @@ -119,7 +131,7 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N api_device = "CDM" # Try getting pssh via MPD URL if web-dl - if mpd_url is not None: + if mpd_url is not None and in_pssh is None: input_pssh = Helpers.mpd_parse.parse_pssh(mpd_url) if input_pssh is not None: print(f'\nPSSH found: {input_pssh}') @@ -127,12 +139,18 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N input_pssh = input(f"\nPSSH not found! Input PSSH: ") # Ask for PSSH if just keys function - if mpd_url is None: + if mpd_url is None and in_pssh is None: # Ask for PSSH if web-dl not selected: input_pssh = input(f"\nPSSH: ") + if in_pssh is not None: + input_pssh = in_pssh + # Ask for license URL - input_license_url = input(f"\nLicense URL: ") + if in_license_url is None: + input_license_url = input(f"\nLicense URL: ") + if in_license_url is not None: + input_license_url = in_license_url # Set headers for API key api_key_headers = { @@ -197,6 +215,7 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N # Cache the keys Helpers.cache_key.cache_keys(pssh=input_pssh, keys=returned_keys) + # Print out keys print(f'\nKeys:\n{returned_keys}') @@ -204,4 +223,4 @@ def decrypt_generic_remotely(api_key: str = None, license_curl_headers: dict = N requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers) # Return mp4decrypt keys - return mp4decrypt_keys + return mp4decrypt_keys, returned_keys diff --git a/Sites/YouTube.py b/Sites/YouTube.py index 5c62e88..b384cc0 100644 --- a/Sites/YouTube.py +++ b/Sites/YouTube.py @@ -10,7 +10,8 @@ import Helpers # Defining decrypt function for YouTube -def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_curl_cookies: dict = None, license_curl_json: dict = None): +def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_curl_cookies: dict = None, license_curl_json: dict = None, + in_license_url: str = None): # Exit if no device if wvd is None: @@ -19,8 +20,11 @@ def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_ # prepare pssh pssh = PSSH("AAAAQXBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACEiGVlUX01FRElBOjZlMzI4ZWQxYjQ5YmYyMWZI49yVmwY=") - # Ask for the license URL - license_url = input("License URL: ") + # Ask for license URL + if in_license_url is None: + license_url = input(f"\nLicense URL: ") + if in_license_url is not None: + license_url = in_license_url # Print a new line between PSSH/License URL and keys print("\n") @@ -81,11 +85,12 @@ def decrypt_youtube(wvd: str = None, license_curl_headers: dict = None, license_ print(f'Keys:\n{returned_keys}') # Return the keys for future ripper use. - return mp4decrypt_keys + return mp4decrypt_keys, returned_keys # Defining remote decrypt function for YouTube -def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = None, license_curl_json: dict = None, license_curl_cookies: dict = None): +def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = None, license_curl_json: dict = None, license_curl_cookies: dict = None, + in_license_url: str = None): # Exit if no API key if api_key is None: @@ -98,7 +103,10 @@ def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = N api_device = "CDM" # Ask for License URL - input_license_url = input("License URL: ") + if in_license_url is None: + input_license_url = input(f"\nLicense URL: ") + if in_license_url is not None: + input_license_url = in_license_url # Print a line between license URL and keys print("\n") @@ -177,4 +185,4 @@ def decrypt_youtube_remotely(api_key: str = None, license_curl_headers: dict = N requests.get(url=f'{api_url}/{api_device}/close/{session_id}', headers=api_key_headers) # Return mp4decrypt keys - return mp4decrypt_keys + return mp4decrypt_keys, returned_keys diff --git a/license_curl.py b/license_curl.py index 780d16d..c1c5118 100644 --- a/license_curl.py +++ b/license_curl.py @@ -3,13 +3,12 @@ headers = { 'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.5', # 'Accept-Encoding': 'gzip, deflate, br', - 'Content-Type': 'application/octet-stream', 'DNT': '1', + 'Connection': 'keep-alive', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', - 'Sec-Fetch-Site': 'same-site', + 'Sec-Fetch-Site': 'cross-site', 'Sec-GPC': '1', - 'Connection': 'keep-alive', # Requests doesn't support trailers # 'TE': 'trailers', } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 9931c2c..a9b98ed 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/tpd-keys.py b/tpd-keys.py index 240c13e..c21f7a6 100644 --- a/tpd-keys.py +++ b/tpd-keys.py @@ -21,6 +21,7 @@ services.add_argument('--crunchyroll', action='store_true', help="Decrypt Crunch services.add_argument('--crunchyroll-remote', action='store_true', help="Decrypt Crunchyroll remotely") services.add_argument('--youtube', action='store_true', help="Decrypt YouTube") services.add_argument('--youtube-remote', action='store_true', help="Decrypt YouTube remotely") +services.add_argument('--generic', action='store_true', help="Decrypt generic services") services.add_argument('--generic-remote', action='store_true', help="Decrypt generic services remotely") # Add web download switch @@ -79,7 +80,7 @@ elif switches.generic_remote: Sites.Generic.decrypt_generic_remotely(api_key=api_key, license_curl_headers=license_curl.headers) -else: +elif switches.generic: # If no switch is provided, perform a default action if switches.web_dl: mpd = input("MPD URL: ") @@ -87,3 +88,6 @@ else: print(f'Saved at {file[0]}') else: Sites.Generic.decrypt_generic(wvd=device, license_curl_headers=license_curl.headers) + +else: + Helpers.gui.start_gui(wvd=device, api_key=api_key) \ No newline at end of file