From 3fe194441ac7e7b33c91508f6028c29944942c0c Mon Sep 17 00:00:00 2001 From: Casey Callendrello Date: Thu, 23 Feb 2023 21:33:17 +0100 Subject: [PATCH] handle spotify web URLs as well This automatically converts spotify web URLs (e.g. https://open.spotify.com/track/XXX) to spotify URIs. Signed-off-by: Casey Callendrello --- custom_components/spotcast/__init__.py | 4 ++++ custom_components/spotcast/helpers.py | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/custom_components/spotcast/__init__.py b/custom_components/spotcast/__init__.py index 44f4ea3d..724c1899 100644 --- a/custom_components/spotcast/__init__.py +++ b/custom_components/spotcast/__init__.py @@ -56,6 +56,7 @@ get_random_playlist_from_category, get_search_results, is_valid_uri, + url_to_spotify_uri, ) from .spotcast_controller import SpotcastController @@ -206,6 +207,9 @@ def start_casting(call: ha_core.ServiceCall): # remove ? from badly formatted URI uri = uri.split("?")[0] + if uri.startswith("https"): + uri = url_to_spotify_uri(uri) + if not is_valid_uri(uri): _LOGGER.error("Invalid URI provided, aborting casting") return diff --git a/custom_components/spotcast/helpers.py b/custom_components/spotcast/helpers.py index 7895fefd..80f3b70c 100644 --- a/custom_components/spotcast/helpers.py +++ b/custom_components/spotcast/helpers.py @@ -3,7 +3,7 @@ import asyncio import logging import requests -import urllib +import urllib.parse import difflib import random from functools import partial, wraps @@ -171,6 +171,28 @@ def get_random_playlist_from_category(spotify_client:spotipy.Spotify, category:s return chosen['uri'] + +def url_to_spotify_uri(url: str) -> str: + """ + Convert a spotify web url (e.g. https://open.spotify.com/track/XXXX) to + a spotify-style URI (spotify:track:XXXX). Returns None on error. + """ + + o: urllib.parse.ParseResult + try: + o = urllib.parse.urlparse(url) + except ValueError: + return None + + if o.hostname != "open.spotify.com": + return None + + path = o.path.split("/") + if len(path) != 3: + return None + + return f'spotify:{path[1]}:{path[2]}' + def is_valid_uri(uri: str) -> bool: # list of possible types