From b1e6cb8256d80b855e634d57226375aa3dde5e48 Mon Sep 17 00:00:00 2001 From: Jay McDoniel Date: Sat, 15 Apr 2023 07:20:58 -0700 Subject: [PATCH 1/7] Allow for ytmusicapi 1.0.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f56bf4f..4dce818 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ install_requires = [ "Mopidy>=3,<4", "pytube>=12.1.0,<13.0.0", - "ytmusicapi>=0.22.0,<0.30.0", + "ytmusicapi>=0.22.0,<2.0.0", ] entry_points = {"mopidy.ext": ["ytmusic = mopidy_ytmusic:Extension"]} From 5a2839e127d9dc8e3ef85040a1f323d3a6c74b82 Mon Sep 17 00:00:00 2001 From: Jay McDoniel Date: Sat, 15 Apr 2023 07:34:48 -0700 Subject: [PATCH 2/7] Update the authentication according to library update --- mopidy_ytmusic/backend.py | 6 +++--- mopidy_ytmusic/command.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mopidy_ytmusic/backend.py b/mopidy_ytmusic/backend.py index 0da4e84..fe60f74 100644 --- a/mopidy_ytmusic/backend.py +++ b/mopidy_ytmusic/backend.py @@ -16,7 +16,7 @@ TITLE_TEXT, nav, ) -from ytmusicapi.ytmusic import YTMusic +from ytmusicapi import setup from mopidy_ytmusic import logger @@ -62,9 +62,9 @@ def __init__(self, config, audio): self.auth = True if self.auth: - self.api = YTMusic(self._ytmusicapi_auth_json) + self.api = setup(self._ytmusicapi_auth_json) else: - self.api = YTMusic() + self.api = setup() self.playback = YTMusicPlaybackProvider(audio=audio, backend=self) self.library = YTMusicLibraryProvider(backend=self) diff --git a/mopidy_ytmusic/command.py b/mopidy_ytmusic/command.py index 932e52e..7c0944a 100644 --- a/mopidy_ytmusic/command.py +++ b/mopidy_ytmusic/command.py @@ -17,7 +17,7 @@ class SetupCommand(commands.Command): help = "Generate auth.json" def run(self, args, config): - from ytmusicapi.ytmusic import YTMusic + from ytmusicapi import setup filepath = input( "Enter the path where you want to save auth.json [default=current dir]: " @@ -37,7 +37,7 @@ def run(self, args, config): ) print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") try: - print(YTMusic.setup(filepath=str(path))) + print(setup(filepath=str(path))) except Exception: logger.exception("YTMusic setup failed") return 1 @@ -54,7 +54,7 @@ class ReSetupCommand(commands.Command): help = "Regenerate auth.json" def run(self, args, config): - from ytmusicapi.ytmusic import YTMusic + from ytmusicapi import setup path = config["ytmusic"]["auth_json"] if not path: @@ -69,7 +69,7 @@ def run(self, args, config): ) print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") try: - print(YTMusic.setup(filepath=str(path))) + print(setup(filepath=str(path))) except Exception: logger.exception("YTMusic setup failed") return 1 From c0042f577b76258359db9ce8379ab7412f98aa64 Mon Sep 17 00:00:00 2001 From: Jay McDoniel Date: Sun, 23 Jul 2023 14:42:39 -0700 Subject: [PATCH 3/7] feat: oauth capabilites feat: oauth capabilites --- mopidy_ytmusic/backend.py | 16 ++++++++++++---- mopidy_ytmusic/command.py | 29 ++++++++++++++++++----------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/mopidy_ytmusic/backend.py b/mopidy_ytmusic/backend.py index fe60f74..619d744 100644 --- a/mopidy_ytmusic/backend.py +++ b/mopidy_ytmusic/backend.py @@ -16,7 +16,7 @@ TITLE_TEXT, nav, ) -from ytmusicapi import setup +from ytmusicapi import YTMusic from mopidy_ytmusic import logger @@ -36,6 +36,7 @@ def __init__(self, config, audio): self.audio = audio self.uri_schemes = ["ytmusic"] self.auth = False + self.oauth = False self._auto_playlist_refresh_rate = ( config["ytmusic"]["auto_playlist_refresh"] * 60 @@ -61,10 +62,16 @@ def __init__(self, config, audio): self._ytmusicapi_auth_json = config["ytmusic"]["auth_json"] self.auth = True - if self.auth: - self.api = setup(self._ytmusicapi_auth_json) + if config["ytmusic"]["oauth_json"]: + self._ytmusicapi_oauth_json = config["ytmusic"]["oauth_json"] + self.oauth = True + + if self.auth and not self.oauth: + self.api = YTMusic(self._ytmusicapi_auth_json) + elif self.oauth: + self.api = YTMusic(self._ytmusicapi_oauth_json) else: - self.api = setup() + self.api = YTMusic() self.playback = YTMusicPlaybackProvider(audio=audio, backend=self) self.library = YTMusicLibraryProvider(backend=self) @@ -103,6 +110,7 @@ def _refresh_youtube_player(self): def _get_youtube_player(self): # Refresh our js player URL so YDL can decode the signature correctly. try: + self.api.headers.pop('filepath', None) response = requests.get( "https://music.youtube.com", headers=self.api.headers, diff --git a/mopidy_ytmusic/command.py b/mopidy_ytmusic/command.py index 7c0944a..8648733 100644 --- a/mopidy_ytmusic/command.py +++ b/mopidy_ytmusic/command.py @@ -17,7 +17,7 @@ class SetupCommand(commands.Command): help = "Generate auth.json" def run(self, args, config): - from ytmusicapi import setup + from ytmusicapi import YTMusic filepath = input( "Enter the path where you want to save auth.json [default=current dir]: " @@ -37,7 +37,7 @@ def run(self, args, config): ) print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") try: - print(setup(filepath=str(path))) + print(YTMusic(filepath=str(path))) except Exception: logger.exception("YTMusic setup failed") return 1 @@ -54,22 +54,29 @@ class ReSetupCommand(commands.Command): help = "Regenerate auth.json" def run(self, args, config): - from ytmusicapi import setup + from ytmusicapi import YTMusic path = config["ytmusic"]["auth_json"] + usingOauth = False if not path: logger.error("auth_json path not defined in config") return 1 + if config["ytmusic"]["oauth_json"] is not None: + path = config["ytmusic"]["oauth_json"] + usingOauth = True print('Updating credentials in "' + str(path) + '"') - print( - "Open Youtube Music, open developer tools (F12), go to Network tab," - ) - print( - 'right click on a POST request and choose "Copy request headers".' - ) - print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") + if not usingOauth: + print( + "Open Youtube Music, open developer tools (F12), go to Network tab," + ) + print( + 'right click on a POST request and choose "Copy request headers".' + ) + print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") + else: + print("Updating via oauth, follow the instructions from ytmusicapi") try: - print(setup(filepath=str(path))) + print(YTMusic(path)) except Exception: logger.exception("YTMusic setup failed") return 1 From 15b022de2dc38392c53a01da0c4a52cafbfd8acd Mon Sep 17 00:00:00 2001 From: Jay McDoniel Date: Sun, 23 Jul 2023 14:42:39 -0700 Subject: [PATCH 4/7] feat: oauth capabilites feat: oauth capabilites --- mopidy_ytmusic/__init__.py | 1 + mopidy_ytmusic/backend.py | 16 ++++++++++++---- mopidy_ytmusic/command.py | 29 ++++++++++++++++++----------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/mopidy_ytmusic/__init__.py b/mopidy_ytmusic/__init__.py index 75b7e2a..8bb535c 100644 --- a/mopidy_ytmusic/__init__.py +++ b/mopidy_ytmusic/__init__.py @@ -21,6 +21,7 @@ def get_default_config(self): def get_config_schema(self): schema = super().get_config_schema() schema["auth_json"] = config.Path(optional=True) + schema["oauth_json"] = config.Path(optional=True) schema["auto_playlist_refresh"] = config.Integer( minimum=0, optional=True ) diff --git a/mopidy_ytmusic/backend.py b/mopidy_ytmusic/backend.py index fe60f74..619d744 100644 --- a/mopidy_ytmusic/backend.py +++ b/mopidy_ytmusic/backend.py @@ -16,7 +16,7 @@ TITLE_TEXT, nav, ) -from ytmusicapi import setup +from ytmusicapi import YTMusic from mopidy_ytmusic import logger @@ -36,6 +36,7 @@ def __init__(self, config, audio): self.audio = audio self.uri_schemes = ["ytmusic"] self.auth = False + self.oauth = False self._auto_playlist_refresh_rate = ( config["ytmusic"]["auto_playlist_refresh"] * 60 @@ -61,10 +62,16 @@ def __init__(self, config, audio): self._ytmusicapi_auth_json = config["ytmusic"]["auth_json"] self.auth = True - if self.auth: - self.api = setup(self._ytmusicapi_auth_json) + if config["ytmusic"]["oauth_json"]: + self._ytmusicapi_oauth_json = config["ytmusic"]["oauth_json"] + self.oauth = True + + if self.auth and not self.oauth: + self.api = YTMusic(self._ytmusicapi_auth_json) + elif self.oauth: + self.api = YTMusic(self._ytmusicapi_oauth_json) else: - self.api = setup() + self.api = YTMusic() self.playback = YTMusicPlaybackProvider(audio=audio, backend=self) self.library = YTMusicLibraryProvider(backend=self) @@ -103,6 +110,7 @@ def _refresh_youtube_player(self): def _get_youtube_player(self): # Refresh our js player URL so YDL can decode the signature correctly. try: + self.api.headers.pop('filepath', None) response = requests.get( "https://music.youtube.com", headers=self.api.headers, diff --git a/mopidy_ytmusic/command.py b/mopidy_ytmusic/command.py index 7c0944a..8648733 100644 --- a/mopidy_ytmusic/command.py +++ b/mopidy_ytmusic/command.py @@ -17,7 +17,7 @@ class SetupCommand(commands.Command): help = "Generate auth.json" def run(self, args, config): - from ytmusicapi import setup + from ytmusicapi import YTMusic filepath = input( "Enter the path where you want to save auth.json [default=current dir]: " @@ -37,7 +37,7 @@ def run(self, args, config): ) print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") try: - print(setup(filepath=str(path))) + print(YTMusic(filepath=str(path))) except Exception: logger.exception("YTMusic setup failed") return 1 @@ -54,22 +54,29 @@ class ReSetupCommand(commands.Command): help = "Regenerate auth.json" def run(self, args, config): - from ytmusicapi import setup + from ytmusicapi import YTMusic path = config["ytmusic"]["auth_json"] + usingOauth = False if not path: logger.error("auth_json path not defined in config") return 1 + if config["ytmusic"]["oauth_json"] is not None: + path = config["ytmusic"]["oauth_json"] + usingOauth = True print('Updating credentials in "' + str(path) + '"') - print( - "Open Youtube Music, open developer tools (F12), go to Network tab," - ) - print( - 'right click on a POST request and choose "Copy request headers".' - ) - print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") + if not usingOauth: + print( + "Open Youtube Music, open developer tools (F12), go to Network tab," + ) + print( + 'right click on a POST request and choose "Copy request headers".' + ) + print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") + else: + print("Updating via oauth, follow the instructions from ytmusicapi") try: - print(setup(filepath=str(path))) + print(YTMusic(path)) except Exception: logger.exception("YTMusic setup failed") return 1 From d2b01490aeb37f6a9f37c97e6fea0b733f4ea4fd Mon Sep 17 00:00:00 2001 From: Jay McDoniel Date: Sun, 23 Jul 2023 14:42:39 -0700 Subject: [PATCH 5/7] feat: oauth capabilites feat: oauth capabilites Signed-off-by: Jay McDoniel --- mopidy_ytmusic/backend.py | 4 ++-- mopidy_ytmusic/command.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mopidy_ytmusic/backend.py b/mopidy_ytmusic/backend.py index 619d744..cab38c9 100644 --- a/mopidy_ytmusic/backend.py +++ b/mopidy_ytmusic/backend.py @@ -67,9 +67,9 @@ def __init__(self, config, audio): self.oauth = True if self.auth and not self.oauth: - self.api = YTMusic(self._ytmusicapi_auth_json) + self.api = YTMusic(auth=self._ytmusicapi_auth_json) elif self.oauth: - self.api = YTMusic(self._ytmusicapi_oauth_json) + self.api = YTMusic(auth=self._ytmusicapi_oauth_json) else: self.api = YTMusic() diff --git a/mopidy_ytmusic/command.py b/mopidy_ytmusic/command.py index 8648733..757c37a 100644 --- a/mopidy_ytmusic/command.py +++ b/mopidy_ytmusic/command.py @@ -76,7 +76,7 @@ def run(self, args, config): else: print("Updating via oauth, follow the instructions from ytmusicapi") try: - print(YTMusic(path)) + print(YTMusic(auth=path)) except Exception: logger.exception("YTMusic setup failed") return 1 From 6509b58c9bfd8f9f2f09f4f8eba7da0bdcaf8329 Mon Sep 17 00:00:00 2001 From: cprn Date: Sun, 31 Dec 2023 11:45:44 +0100 Subject: [PATCH 6/7] fixed oauth in `mopidy ytmusic setup` command Also removed the upper boundary of pytube version because it collides with 15.0.0 and there are no changes preventing the current code from working. --- mopidy_ytmusic/command.py | 15 ++++----------- setup.py | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/mopidy_ytmusic/command.py b/mopidy_ytmusic/command.py index 757c37a..7a0e33c 100644 --- a/mopidy_ytmusic/command.py +++ b/mopidy_ytmusic/command.py @@ -17,27 +17,20 @@ class SetupCommand(commands.Command): help = "Generate auth.json" def run(self, args, config): - from ytmusicapi import YTMusic + from ytmusicapi.setup import setup_oauth filepath = input( "Enter the path where you want to save auth.json [default=current dir]: " ) if not filepath: filepath = os.getcwd() - path = Path(filepath + "/auth.json") + path = Path(filepath + "/oauth.json") print('Using "' + str(path) + '"') if path.exists(): print("File already exists!") return 1 - print( - "Open Youtube Music, open developer tools (F12), go to Network tab," - ) - print( - 'right click on a POST request and choose "Copy request headers".' - ) - print("Then paste (CTRL+SHIFT+V) them here and press CTRL+D.") try: - print(YTMusic(filepath=str(path))) + setup_oauth(filepath=str(path)) except Exception: logger.exception("YTMusic setup failed") return 1 @@ -54,7 +47,7 @@ class ReSetupCommand(commands.Command): help = "Regenerate auth.json" def run(self, args, config): - from ytmusicapi import YTMusic + from ytmusicapi.setup import setup_oauth path = config["ytmusic"]["auth_json"] usingOauth = False diff --git a/setup.py b/setup.py index 4dce818..2c75924 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ install_requires = [ "Mopidy>=3,<4", - "pytube>=12.1.0,<13.0.0", + "pytube>=12.1.0", "ytmusicapi>=0.22.0,<2.0.0", ] From 445ecd85ef4806cee4077fe415ca9d3c71e0ec10 Mon Sep 17 00:00:00 2001 From: cprn Date: Sun, 31 Dec 2023 11:59:52 +0100 Subject: [PATCH 7/7] reverting one overzealous change --- mopidy_ytmusic/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mopidy_ytmusic/command.py b/mopidy_ytmusic/command.py index 7a0e33c..e767cd5 100644 --- a/mopidy_ytmusic/command.py +++ b/mopidy_ytmusic/command.py @@ -47,7 +47,7 @@ class ReSetupCommand(commands.Command): help = "Regenerate auth.json" def run(self, args, config): - from ytmusicapi.setup import setup_oauth + from ytmusicapi import YTMusic path = config["ytmusic"]["auth_json"] usingOauth = False