diff --git a/requirements.txt b/requirements.txt index 293b2ae..e30c014 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ -aiohttp==3.9.0 +aiohttp==3.9.5 appdirs==1.4.4 argparse==1.4.0 async-cache==1.1.1 -pyytlounge==1.6.3 -rich==13.6.0 +pyytlounge==2.0.0 +rich==13.7.1 ssdp==1.3.0 -textual==0.40.0 +textual==0.58.0 textual-slider==0.1.1 xmltodict==0.13.0 diff --git a/src/iSponsorBlockTV/config_setup.py b/src/iSponsorBlockTV/config_setup.py index 51b0138..3e3bb95 100644 --- a/src/iSponsorBlockTV/config_setup.py +++ b/src/iSponsorBlockTV/config_setup.py @@ -5,9 +5,11 @@ from . import api_helpers, ytlounge -async def pair_device(): +async def pair_device(web_session): try: - lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV") + lounge_controller = ytlounge.YtLoungeApi( + "iSponsorBlockTV", web_session=web_session + ) pairing_code = input( "Enter pairing code (found in Settings - Link with TV code): " ) @@ -33,6 +35,7 @@ async def pair_device(): def main(config, debug: bool) -> None: print("Welcome to the iSponsorBlockTV cli setup wizard") loop = asyncio.get_event_loop_policy().get_event_loop() + web_session = aiohttp.ClientSession() if debug: loop.set_debug(True) asyncio.set_event_loop(loop) @@ -52,7 +55,7 @@ def main(config, debug: bool) -> None: 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()) + task = loop.create_task(pair_device(web_session)) loop.run_until_complete(task) device = task.result() if device: @@ -112,7 +115,6 @@ def main(config, debug: bool) -> None: " 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 = {} @@ -152,7 +154,6 @@ def main(config, debug: bool) -> None: 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 @@ -165,3 +166,4 @@ def main(config, debug: bool) -> None: ) print("Config finished") config.save() + loop.run_until_complete(web_session.close()) diff --git a/src/iSponsorBlockTV/main.py b/src/iSponsorBlockTV/main.py index 8cc6e9d..b624d00 100644 --- a/src/iSponsorBlockTV/main.py +++ b/src/iSponsorBlockTV/main.py @@ -10,13 +10,14 @@ class DeviceListener: - def __init__(self, api_helper, config, device, debug: bool): + def __init__(self, api_helper, config, device, debug: bool, web_session): self.task: Optional[asyncio.Task] = None self.api_helper = api_helper self.offset = device.offset self.name = device.name self.cancelled = False self.logger = logging.getLogger(f"iSponsorBlockTV-{device.screen_id}") + self.web_session = web_session if debug: self.logger.setLevel(logging.DEBUG) else: @@ -28,7 +29,7 @@ def __init__(self, api_helper, config, device, debug: bool): self.logger.addHandler(sh) self.logger.info(f"Starting device") self.lounge_controller = ytlounge.YtLoungeApi( - device.screen_id, config, api_helper, self.logger + device.screen_id, config, api_helper, self.logger, self.web_session ) # Ensures that we have a valid auth token @@ -155,7 +156,7 @@ def main(config, debug): web_session = aiohttp.ClientSession(loop=loop, connector=tcp_connector) api_helper = api_helpers.ApiHelper(config, web_session) for i in config.devices: - device = DeviceListener(api_helper, config, i, debug) + device = DeviceListener(api_helper, config, i, debug, web_session) devices.append(device) tasks.append(loop.create_task(device.loop())) tasks.append(loop.create_task(device.refresh_auth_loop())) @@ -165,3 +166,5 @@ def main(config, debug): print("Cancelling tasks and exiting...") loop.run_until_complete(finish(devices)) loop.run_until_complete(web_session.close()) + loop.run_until_complete(tcp_connector.close()) + loop.close() diff --git a/src/iSponsorBlockTV/setup_wizard.py b/src/iSponsorBlockTV/setup_wizard.py index e692abe..da4d66f 100644 --- a/src/iSponsorBlockTV/setup_wizard.py +++ b/src/iSponsorBlockTV/setup_wizard.py @@ -234,8 +234,8 @@ class AddDevice(ModalWithClickExit): def __init__(self, config, **kwargs) -> None: super().__init__(**kwargs) self.config = config - web_session = aiohttp.ClientSession() - self.api_helper = api_helpers.ApiHelper(config, web_session) + self.web_session = aiohttp.ClientSession() + self.api_helper = api_helpers.ApiHelper(config, self.web_session) self.devices_discovered_dial = [] def compose(self) -> ComposeResult: @@ -336,7 +336,9 @@ def changed_pairing_code(self, event: Input.Changed): @on(Button.Pressed, "#add-device-pin-add-button") async def handle_add_device_pin(self) -> None: self.query_one("#add-device-pin-add-button").disabled = True - lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV") + lounge_controller = ytlounge.YtLoungeApi( + "iSponsorBlockTV", web_session=self.web_session + ) pairing_code = self.query_one("#pairing-code-input").value pairing_code = int( pairing_code.replace("-", "").replace(" ", "") diff --git a/src/iSponsorBlockTV/ytlounge.py b/src/iSponsorBlockTV/ytlounge.py index 18087f7..625329f 100644 --- a/src/iSponsorBlockTV/ytlounge.py +++ b/src/iSponsorBlockTV/ytlounge.py @@ -2,6 +2,7 @@ import json import pyytlounge +from aiohttp import ClientSession from .constants import youtube_client_blacklist @@ -9,8 +10,17 @@ class YtLoungeApi(pyytlounge.YtLoungeApi): - def __init__(self, screen_id, config=None, api_helper=None, logger=None): + def __init__( + self, + screen_id, + config=None, + api_helper=None, + logger=None, + web_session: ClientSession = None, + ): super().__init__("iSponsorBlockTV", logger=logger) + if web_session is not None: + self.session = web_session # And use the one we passed self.auth.screen_id = screen_id self.auth.lounge_id_token = None self.api_helper = api_helper