Skip to content

Commit

Permalink
fix: parse Spotify playlist ids from playlists with a share id query …
Browse files Browse the repository at this point in the history
…parameter correctly (#76)

* fix: parse id from URLs with tracking(?) query parameter

Such as [https://open.spotify.com/playlist/37i9dQZF1DX5KpP2LN299J?si=asdf](open.spotify.com/playlist/37i9dQZF1DX5KpP2LN299J?si=asdf)

* refactor: make this a classmethod

* chore: add tests

* refactor: don't cache regex
  • Loading branch information
benthillerkus authored Oct 20, 2023
1 parent 6a502ef commit 42690d8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
22 changes: 10 additions & 12 deletions spotify_to_ytmusic/spotify.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import html
import string
from urllib.parse import urlparse
import re

import spotipy
from spotipy import CacheFileHandler
Expand Down Expand Up @@ -42,9 +42,7 @@ def __init__(self):
self.api = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

def getSpotifyPlaylist(self, url):
playlistId = get_id_from_url(url)
if len(playlistId) != 22:
raise Exception(f"Bad playlist id: {playlistId}")
playlistId = extract_playlist_id_from_url(url)

print("Getting Spotify tracks...")
results = self.api.playlist(playlistId)
Expand Down Expand Up @@ -91,7 +89,6 @@ def getLikedPlaylist(self):
"description": "Your liked tracks from spotify",
}


def build_results(tracks, album=None):
results = []
for track in tracks:
Expand All @@ -112,10 +109,11 @@ def build_results(tracks, album=None):
return results


def get_id_from_url(url):
url_parts = parse_url(url)
return url_parts.path.split("/")[2]


def parse_url(url):
return urlparse(url)
def extract_playlist_id_from_url(url: str) -> str:
if (match := re.search(r"playlist\/(?P<id>\w{22})\W?", url)):
return match.group("id")
elif (match := re.search(r"playlist\/(?P<id>\w+)\W?", url)):
id = match.group("id")
raise ValueError(f"Bad playlist id: {id}\nA playlist id should be 22 characters long, not {len(id)}")
else:
raise ValueError(f"Couldn't understand playlist url: {url}\nA playlist url should look like this: https://open.spotify.com/playlist/37i9dQZF1DZ06evO41HwPk")
21 changes: 21 additions & 0 deletions tests/test_parsing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import unittest

from spotify_to_ytmusic.spotify import extract_playlist_id_from_url


class TestParsing(unittest.TestCase):
def test_idFromSpotifyUrl(self):
url = "https://open.spotify.com/playlist/37i9dQZF1DX5KpP2LN299J"
self.assertEqual(extract_playlist_id_from_url(url), "37i9dQZF1DX5KpP2LN299J")

def test_idFromSpotifyUrlWithShareId(self):
url = "http://open.spotify.com/playlist/37i9dQZF1DZ06evO3siF1W?si=grips"
self.assertEqual(extract_playlist_id_from_url(url), "37i9dQZF1DZ06evO3siF1W")

def test_idFromSpotifyUrlRejectBadId(self):
url = "https://open.spotify.com/playlist/420"
self.assertRaisesRegex(ValueError, r"Bad playlist id", extract_playlist_id_from_url, url)

def test_idFromSpotifyUrlRejectBadUrl(self):
url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
self.assertRaises(ValueError, extract_playlist_id_from_url, url)

0 comments on commit 42690d8

Please sign in to comment.