From daa7026221592912f208bf4148a08c8c0410dcfc Mon Sep 17 00:00:00 2001 From: Ryan Kupka Date: Fri, 3 May 2024 10:18:16 -0600 Subject: [PATCH 1/4] Refactor CLI setup script, add prompts for muting and skipping native youtube ads --- src/iSponsorBlockTV/config_setup.py | 353 +++++++++++++++------------- 1 file changed, 186 insertions(+), 167 deletions(-) diff --git a/src/iSponsorBlockTV/config_setup.py b/src/iSponsorBlockTV/config_setup.py index 51b0138..bcc7651 100644 --- a/src/iSponsorBlockTV/config_setup.py +++ b/src/iSponsorBlockTV/config_setup.py @@ -1,167 +1,186 @@ -import asyncio - -import aiohttp - -from . import api_helpers, ytlounge - - -async def pair_device(): - try: - lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV") - pairing_code = input( - "Enter pairing code (found in Settings - Link with TV code): " - ) - pairing_code = int( - pairing_code.replace("-", "").replace(" ", "") - ) # remove dashes and spaces - print("Pairing...") - paired = await lounge_controller.pair(pairing_code) - if not paired: - print("Failed to pair device") - return - device = { - "screen_id": lounge_controller.auth.screen_id, - "name": lounge_controller.screen_name, - } - print(f"Paired device: {device['name']}") - return device - except Exception as e: - print(f"Failed to pair device: {e}") - return - - -def main(config, debug: bool) -> None: - print("Welcome to the iSponsorBlockTV cli setup wizard") - loop = asyncio.get_event_loop_policy().get_event_loop() - if debug: - loop.set_debug(True) - asyncio.set_event_loop(loop) - if hasattr(config, "atvs"): - print( - "The atvs config option is deprecated and has stopped working. Please read" - " this for more information on how to upgrade to V2:" - " \nhttps://github.com/dmunozv04/iSponsorBlockTV/wiki/Migrate-from-V1-to-V2" - ) - if ( - input( - "Do you want to remove the legacy 'atvs' entry (the app won't start" - " with it present)? (y/n) " - ) - == "y" - ): - del config["atvs"] - devices = config.devices - while not input(f"Paired with {len(devices)} Device(s). Add more? (y/n) ") == "n": - task = loop.create_task(pair_device()) - loop.run_until_complete(task) - device = task.result() - if device: - devices.append(device) - config.devices = devices - - apikey = config.apikey - if apikey: - if input("API key already specified. Change it? (y/n) ") == "y": - apikey = input("Enter your API key: ") - else: - if ( - input( - "API key only needed for the channel whitelist function. Add it? (y/n) " - ) - == "y" - ): - print( - "Get youtube apikey here:" - " https://developers.google.com/youtube/registering_an_application" - ) - apikey = input("Enter your API key: ") - config.apikey = apikey - - skip_categories = config.skip_categories - if skip_categories: - if input("Skip categories already specified. Change them? (y/n) ") == "y": - categories = input( - "Enter skip categories (space or comma sepparated) Options: [sponsor" - " selfpromo exclusive_access interaction poi_highlight intro outro" - " preview filler music_offtopic]:\n" - ) - skip_categories = categories.replace(",", " ").split(" ") - skip_categories = [ - x for x in skip_categories if x != "" - ] # Remove empty strings - else: - categories = input( - "Enter skip categories (space or comma sepparated) Options: [sponsor," - " selfpromo, exclusive_access, interaction, poi_highlight, intro, outro," - " preview, filler, music_offtopic:\n" - ) - skip_categories = categories.replace(",", " ").split(" ") - skip_categories = [ - x for x in skip_categories if x != "" - ] # Remove empty strings - config.skip_categories = skip_categories - - channel_whitelist = config.channel_whitelist - if ( - input("Do you want to whitelist any channels from being ad-blocked? (y/n) ") - == "y" - ): - if not apikey: - print( - "WARNING: You need to specify an API key to use this function," - " otherwise the program will fail to start.\nYou can add one by" - " re-running this setup wizard." - ) - web_session = aiohttp.ClientSession() - api_helper = api_helpers.ApiHelper(config, web_session) - while True: - channel_info = {} - channel = input('Enter a channel name or "/exit" to exit: ') - if channel == "/exit": - break - - task = loop.create_task( - api_helper.search_channels(channel, apikey, web_session) - ) - loop.run_until_complete(task) - results = task.result() - if len(results) == 0: - print("No channels found") - continue - - for i, item in enumerate(results): - print(f"{i}: {item[1]} - Subs: {item[2]}") - print("5: Enter a custom channel ID") - print("6: Go back") - - choice = -1 - choice = input("Select one option of the above [0-6]: ") - while choice not in [str(x) for x in range(7)]: - print("Invalid choice") - choice = input("Select one option of the above [0-6]: ") - - if choice == "5": - channel_info["id"] = input("Enter a channel ID: ") - channel_info["name"] = input("Enter the channel name: ") - channel_whitelist.append(channel_info) - continue - if choice == "6": - continue - - channel_info["id"] = results[int(choice)][0] - channel_info["name"] = results[int(choice)][1] - channel_whitelist.append(channel_info) - # Close web session asynchronously - loop.run_until_complete(web_session.close()) - - config.channel_whitelist = channel_whitelist - - config.skip_count_tracking = ( - not input( - "Do you want to report skipped segments to sponsorblock. Only the segment" - " UUID will be sent? (y/n) " - ) - == "n" - ) - print("Config finished") - config.save() +import asyncio + +import aiohttp + +from . import api_helpers, ytlounge + +# Constants for user input prompts +ATVS_REMOVAL_PROMPT = ( + "Do you want to remove the legacy 'atvs' entry (the app won't start" + " with it present)? (y/n) " +) +PAIRING_CODE_PROMPT = "Enter pairing code (found in Settings - Link with TV code): " +ADD_MORE_DEVICES_PROMPT = "Paired with {num_devices} Device(s). Add more? (y/n) " +CHANGE_API_KEY_PROMPT = "API key already specified. Change it? (y/n) " +ADD_API_KEY_PROMPT = "API key only needed for the channel whitelist function. Add it? (y/n) " +ENTER_API_KEY_PROMPT = "Enter your API key: " +CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/n) " +ENTER_SKIP_CATEGORIES_PROMPT = ( + "Enter skip categories (space or comma sepparated) Options: [sponsor," + " selfpromo, exclusive_access, interaction, poi_highlight, intro, outro," + " preview, filler, music_offtopic]:\n" +) +WHITELIST_CHANNELS_PROMPT = "Do you want to whitelist any channels from being ad-blocked? (y/n) " +SEARCH_CHANNEL_PROMPT = 'Enter a channel name or "/exit" to exit: ' +SELECT_CHANNEL_PROMPT = "Select one option of the above [0-6]: " +ENTER_CHANNEL_ID_PROMPT = "Enter a channel ID: " +ENTER_CUSTOM_CHANNEL_NAME_PROMPT = "Enter the channel name: " +REPORT_SKIPPED_SEGMENTS_PROMPT = ( + "Do you want to report skipped segments to sponsorblock. Only the segment" + " UUID will be sent? (y/n) " +) +MUTE_ADS_PROMPT = "Do you want to mute native YouTube ads automatically? (y/n) " +SKIP_ADS_PROMPT = "Do you want to skip native YouTube ads automatically? (y/n) " + + +def get_yn_input(prompt): + while choice := input(prompt): + if choice.lower() in ["y", "n"]: + return choice.lower() + print("Invalid input. Please enter 'y' or 'n'.") + +async def pair_device(): + try: + lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV") + pairing_code = input(PAIRING_CODE_PROMPT) + pairing_code = int( + pairing_code.replace("-", "").replace(" ", "") + ) # remove dashes and spaces + print("Pairing...") + paired = await lounge_controller.pair(pairing_code) + if not paired: + print("Failed to pair device") + return + device = { + "screen_id": lounge_controller.auth.screen_id, + "name": lounge_controller.screen_name, + } + print(f"Paired device: {device['name']}") + return device + except Exception as e: + print(f"Failed to pair device: {e}") + return + + +def main(config, debug: bool) -> None: + print("Welcome to the iSponsorBlockTV cli setup wizard") + loop = asyncio.get_event_loop_policy().get_event_loop() + if debug: + loop.set_debug(True) + asyncio.set_event_loop(loop) + if hasattr(config, "atvs"): + print( + "The atvs config option is deprecated and has stopped working. Please read" + " this for more information on how to upgrade to V2:" + " \nhttps://github.com/dmunozv04/iSponsorBlockTV/wiki/Migrate-from-V1-to-V2" + ) + choice = get_yn_input(ATVS_REMOVAL_PROMPT) + if choice == "y": + del config["atvs"] + + devices = config.devices + choice = get_yn_input(ADD_MORE_DEVICES_PROMPT.format(num_devices=len(devices))) + while choice == "y": + task = loop.create_task(pair_device()) + loop.run_until_complete(task) + device = task.result() + if device: + devices.append(device) + choice = get_yn_input(ADD_MORE_DEVICES_PROMPT.format(num_devices=len(devices))) + config.devices = devices + + apikey = config.apikey + if apikey: + choice = get_yn_input(CHANGE_API_KEY_PROMPT) + if choice == "y": + apikey = input(ENTER_API_KEY_PROMPT) + else: + choice = get_yn_input(ADD_API_KEY_PROMPT) + if choice == "y": + print( + "Get youtube apikey here:" + " https://developers.google.com/youtube/registering_an_application" + ) + apikey = input(ENTER_API_KEY_PROMPT) + config.apikey = apikey + + skip_categories = config.skip_categories + if skip_categories: + choice = get_yn_input(CHANGE_SKIP_CATEGORIES_PROMPT) + if choice == "y": + categories = input(ENTER_SKIP_CATEGORIES_PROMPT) + skip_categories = categories.replace(",", " ").split(" ") + skip_categories = [ + x for x in skip_categories if x != "" + ] # Remove empty strings + else: + categories = input(ENTER_SKIP_CATEGORIES_PROMPT) + skip_categories = categories.replace(",", " ").split(" ") + skip_categories = [ + x for x in skip_categories if x != "" + ] # Remove empty strings + config.skip_categories = skip_categories + + channel_whitelist = config.channel_whitelist + choice = get_yn_input(WHITELIST_CHANNELS_PROMPT) + if choice == "y": + if not apikey: + print( + "WARNING: You need to specify an API key to use this function," + " otherwise the program will fail to start.\nYou can add one by" + " re-running this setup wizard." + ) + web_session = aiohttp.ClientSession() + api_helper = api_helpers.ApiHelper(config, web_session) + while True: + channel_info = {} + channel = input(SEARCH_CHANNEL_PROMPT) + if channel == "/exit": + break + + task = loop.create_task( + api_helper.search_channels(channel, apikey, web_session) + ) + loop.run_until_complete(task) + results = task.result() + if len(results) == 0: + print("No channels found") + continue + + for i, item in enumerate(results): + print(f"{i}: {item[1]} - Subs: {item[2]}") + print("5: Enter a custom channel ID") + print("6: Go back") + + while choice := input(SELECT_CHANNEL_PROMPT): + if choice in [str(x) for x in range(7)]: + break + print("Invalid choice") + + if choice == "5": + channel_info["id"] = input(ENTER_CHANNEL_ID_PROMPT) + channel_info["name"] = input(ENTER_CUSTOM_CHANNEL_NAME_PROMPT) + channel_whitelist.append(channel_info) + continue + if choice == "6": + continue + + channel_info["id"] = results[int(choice)][0] + channel_info["name"] = results[int(choice)][1] + channel_whitelist.append(channel_info) + # Close web session asynchronously + loop.run_until_complete(web_session.close()) + + config.channel_whitelist = channel_whitelist + + choice = get_yn_input(REPORT_SKIPPED_SEGMENTS_PROMPT) + config.skip_count_tracking = choice == "y" + + choice = get_yn_input(MUTE_ADS_PROMPT) + config.mute_ads = choice == "y" + + choice = get_yn_input(SKIP_ADS_PROMPT) + config.skip_ads = choice == "y" + + print("Config finished") + config.save() From 865f5469a2eaa354eb966d2d517cd07817a59d15 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 16:24:21 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/iSponsorBlockTV/config_setup.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/iSponsorBlockTV/config_setup.py b/src/iSponsorBlockTV/config_setup.py index bcc7651..ca134d0 100644 --- a/src/iSponsorBlockTV/config_setup.py +++ b/src/iSponsorBlockTV/config_setup.py @@ -5,14 +5,16 @@ import aiohttp from . import api_helpers, ytlounge # Constants for user input prompts -ATVS_REMOVAL_PROMPT = ( +ATVS_REMOVAL_PROMPT = ( "Do you want to remove the legacy 'atvs' entry (the app won't start" " with it present)? (y/n) " ) PAIRING_CODE_PROMPT = "Enter pairing code (found in Settings - Link with TV code): " ADD_MORE_DEVICES_PROMPT = "Paired with {num_devices} Device(s). Add more? (y/n) " CHANGE_API_KEY_PROMPT = "API key already specified. Change it? (y/n) " -ADD_API_KEY_PROMPT = "API key only needed for the channel whitelist function. Add it? (y/n) " +ADD_API_KEY_PROMPT = ( + "API key only needed for the channel whitelist function. Add it? (y/n) " +) ENTER_API_KEY_PROMPT = "Enter your API key: " CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/n) " ENTER_SKIP_CATEGORIES_PROMPT = ( @@ -20,7 +22,9 @@ ENTER_SKIP_CATEGORIES_PROMPT = ( " selfpromo, exclusive_access, interaction, poi_highlight, intro, outro," " preview, filler, music_offtopic]:\n" ) -WHITELIST_CHANNELS_PROMPT = "Do you want to whitelist any channels from being ad-blocked? (y/n) " +WHITELIST_CHANNELS_PROMPT = ( + "Do you want to whitelist any channels from being ad-blocked? (y/n) " +) SEARCH_CHANNEL_PROMPT = 'Enter a channel name or "/exit" to exit: ' SELECT_CHANNEL_PROMPT = "Select one option of the above [0-6]: " ENTER_CHANNEL_ID_PROMPT = "Enter a channel ID: " @@ -39,6 +43,7 @@ def get_yn_input(prompt): return choice.lower() print("Invalid input. Please enter 'y' or 'n'.") + async def pair_device(): try: lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV") @@ -181,6 +186,6 @@ def main(config, debug: bool) -> None: choice = get_yn_input(SKIP_ADS_PROMPT) config.skip_ads = choice == "y" - + print("Config finished") config.save() From e2ace8629f01125ebe7142ee33ee93997098ff67 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 21 Jun 2024 15:01:56 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/iSponsorBlockTV/config_setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/iSponsorBlockTV/config_setup.py b/src/iSponsorBlockTV/config_setup.py index 7948c8e..b4a11ad 100644 --- a/src/iSponsorBlockTV/config_setup.py +++ b/src/iSponsorBlockTV/config_setup.py @@ -37,6 +37,7 @@ MUTE_ADS_PROMPT = "Do you want to mute native YouTube ads automatically? (y/n) " SKIP_ADS_PROMPT = "Do you want to skip native YouTube ads automatically? (y/n) " AUTOPLAY_PROMPT = "Do you want to enable autoplay? (y/n) " + def get_yn_input(prompt): while choice := input(prompt): if choice.lower() in ["y", "n"]: @@ -185,7 +186,7 @@ def main(config, debug: bool) -> None: choice = get_yn_input(SKIP_ADS_PROMPT) config.skip_ads = choice == "y" - + choice = get_yn_input(AUTOPLAY_PROMPT) config.auto_play = choice == "y" From 810cd5eec307346903b529bb1925d3b9e70c1595 Mon Sep 17 00:00:00 2001 From: dmunozv04 <39565245+dmunozv04@users.noreply.github.com> Date: Fri, 21 Jun 2024 17:08:15 +0200 Subject: [PATCH 4/4] change default options for autoplay and reporting, and mark default option --- src/iSponsorBlockTV/config_setup.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/iSponsorBlockTV/config_setup.py b/src/iSponsorBlockTV/config_setup.py index b4a11ad..a46015e 100644 --- a/src/iSponsorBlockTV/config_setup.py +++ b/src/iSponsorBlockTV/config_setup.py @@ -7,23 +7,23 @@ from . import api_helpers, ytlounge # Constants for user input prompts ATVS_REMOVAL_PROMPT = ( "Do you want to remove the legacy 'atvs' entry (the app won't start" - " with it present)? (y/n) " + " with it present)? (y/N) " ) PAIRING_CODE_PROMPT = "Enter pairing code (found in Settings - Link with TV code): " -ADD_MORE_DEVICES_PROMPT = "Paired with {num_devices} Device(s). Add more? (y/n) " -CHANGE_API_KEY_PROMPT = "API key already specified. Change it? (y/n) " +ADD_MORE_DEVICES_PROMPT = "Paired with {num_devices} Device(s). Add more? (y/N) " +CHANGE_API_KEY_PROMPT = "API key already specified. Change it? (y/N) " ADD_API_KEY_PROMPT = ( - "API key only needed for the channel whitelist function. Add it? (y/n) " + "API key only needed for the channel whitelist function. Add it? (y/N) " ) ENTER_API_KEY_PROMPT = "Enter your API key: " -CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/n) " +CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/N) " ENTER_SKIP_CATEGORIES_PROMPT = ( "Enter skip categories (space or comma sepparated) Options: [sponsor," " selfpromo, exclusive_access, interaction, poi_highlight, intro, outro," " preview, filler, music_offtopic]:\n" ) WHITELIST_CHANNELS_PROMPT = ( - "Do you want to whitelist any channels from being ad-blocked? (y/n) " + "Do you want to whitelist any channels from being ad-blocked? (y/N) " ) SEARCH_CHANNEL_PROMPT = 'Enter a channel name or "/exit" to exit: ' SELECT_CHANNEL_PROMPT = "Select one option of the above [0-6]: " @@ -31,11 +31,11 @@ ENTER_CHANNEL_ID_PROMPT = "Enter a channel ID: " ENTER_CUSTOM_CHANNEL_NAME_PROMPT = "Enter the channel name: " REPORT_SKIPPED_SEGMENTS_PROMPT = ( "Do you want to report skipped segments to sponsorblock. Only the segment" - " UUID will be sent? (y/n) " + " UUID will be sent? (Y/n) " ) -MUTE_ADS_PROMPT = "Do you want to mute native YouTube ads automatically? (y/n) " -SKIP_ADS_PROMPT = "Do you want to skip native YouTube ads automatically? (y/n) " -AUTOPLAY_PROMPT = "Do you want to enable autoplay? (y/n) " +MUTE_ADS_PROMPT = "Do you want to mute native YouTube ads automatically? (y/N) " +SKIP_ADS_PROMPT = "Do you want to skip native YouTube ads automatically? (y/N) " +AUTOPLAY_PROMPT = "Do you want to enable autoplay? (Y/n) " def get_yn_input(prompt): @@ -179,7 +179,7 @@ def main(config, debug: bool) -> None: config.channel_whitelist = channel_whitelist choice = get_yn_input(REPORT_SKIPPED_SEGMENTS_PROMPT) - config.skip_count_tracking = choice == "y" + config.skip_count_tracking = choice != "n" choice = get_yn_input(MUTE_ADS_PROMPT) config.mute_ads = choice == "y" @@ -188,7 +188,7 @@ def main(config, debug: bool) -> None: config.skip_ads = choice == "y" choice = get_yn_input(AUTOPLAY_PROMPT) - config.auto_play = choice == "y" + config.auto_play = choice != "n" print("Config finished") config.save()