aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParker <contact@pkrm.dev>2024-11-29 22:57:11 -0600
committerParker <contact@pkrm.dev>2024-11-29 22:57:11 -0600
commit60bace9f2885270c566b406460731a49a2103fc4 (patch)
tree5da52db00925dfa530ec2b51566096d9869502b6
parent319fdc62f2bb944c441cb39057ff5b60e829fe51 (diff)
Add support for Spotify `artist` links
-rw-r--r--code/utils/custom_sources.py28
-rw-r--r--code/utils/source_helpers/parse.py13
-rw-r--r--code/utils/source_helpers/spotify/artist.py77
-rw-r--r--test.py3
4 files changed, 117 insertions, 4 deletions
diff --git a/code/utils/custom_sources.py b/code/utils/custom_sources.py
index ed00c66..ee441d6 100644
--- a/code/utils/custom_sources.py
+++ b/code/utils/custom_sources.py
@@ -153,6 +153,34 @@ class SpotifySource(Source):
LoadType.PLAYLIST, tracks, playlist_info=PlaylistInfo.none()
)
+ async def load_artist(self, user, metadata):
+ tracks = []
+ for track in metadata["tracks"]:
+ try:
+ artwork_url = track["album"]["images"][0]["url"]
+ except IndexError:
+ artwork_url = None
+ tracks.append(
+ CustomAudioTrack(
+ {
+ "identifier": track["id"],
+ "isSeekable": True,
+ "author": track["artists"][0]["name"],
+ "length": track["duration_ms"],
+ "isStream": False,
+ "title": track["name"],
+ "uri": track["external_urls"]["spotify"],
+ "duration": track["duration_ms"],
+ "artworkUrl": artwork_url,
+ },
+ requester=user,
+ )
+ )
+
+ return LoadResult(
+ LoadType.PLAYLIST, tracks, playlist_info=PlaylistInfo.none()
+ )
+
"""
Custom Source for Apple Music links
diff --git a/code/utils/source_helpers/parse.py b/code/utils/source_helpers/parse.py
index 8489515..b23a895 100644
--- a/code/utils/source_helpers/parse.py
+++ b/code/utils/source_helpers/parse.py
@@ -7,6 +7,7 @@ from utils.source_helpers.apple import (
)
from utils.source_helpers.spotify import (
album as spotify_album,
+ artist as spotify_artist,
playlist as spotify_playlist,
song as spotify_song,
)
@@ -29,6 +30,7 @@ async def parse_custom_source(
},
"spotify": {
"album": spotify_album.load,
+ "artist": spotify_artist.load,
"playlist": spotify_playlist.load,
"song": spotify_song.load,
},
@@ -43,7 +45,6 @@ async def parse_custom_source(
"apple": AppleSource,
"spotify": SpotifySource,
}
-
# Catch all songs
if "?i=" in query or "/track/" in query:
song, embed = await load_funcs[provider]["song"](
@@ -76,5 +77,15 @@ async def parse_custom_source(
results = await sources[provider].load_album(self, user, album)
else:
return None, embed
+ # Catch Spotify artists
+ elif "/artist/" in query:
+ artist, embed = await load_funcs[provider]["artist"](
+ headers[provider], query, user
+ )
+
+ if artist:
+ results = await sources[provider].load_artist(self, user, artist)
+ else:
+ return None, embed
return results, embed
diff --git a/code/utils/source_helpers/spotify/artist.py b/code/utils/source_helpers/spotify/artist.py
new file mode 100644
index 0000000..995e208
--- /dev/null
+++ b/code/utils/source_helpers/spotify/artist.py
@@ -0,0 +1,77 @@
+import datetime
+import discord
+import requests
+from typing import Tuple, Optional
+from requests.exceptions import JSONDecodeError
+
+from utils.config import create_embed, LOG
+
+
+async def load(
+ headers: dict,
+ query: str,
+ user: discord.User,
+) -> Tuple[Optional[dict], Optional[discord.Embed]]:
+ """
+ Get the artists top tracks from the Spotify API
+ """
+ artist_id = query.split("/artist/")[1]
+
+ try:
+ # Get the artists songs
+ response = requests.get(
+ f"https://api.spotify.com/v1/artists/{artist_id}/top-tracks",
+ headers=headers,
+ )
+
+ if response.status_code == 404:
+ embed = create_embed(
+ title="Artist Not Found",
+ description=(
+ "Either the provided link is malformed, the artist does"
+ " not exist, or the artist does not have any songs."
+ ),
+ )
+ return None, embed
+
+ if response.status_code == 401:
+ LOG.error(
+ "Could not authorize with Spotify API. Likely need to"
+ " restart the bot."
+ )
+ return None, None
+
+ response.raise_for_status()
+ # Unpack the artists songs
+ artist = response.json()
+ name = artist["tracks"][0]["artists"][0]["name"]
+ num_tracks = len(artist["tracks"])
+
+ # Get the artist info (for the thumbnail)
+ response = requests.get(
+ f"https://api.spotify.com/v1/artists/{artist_id}",
+ headers=headers,
+ )
+
+ response.raise_for_status()
+ try:
+ artwork_url = response.json()["images"][0]["url"]
+ except IndexError:
+ artwork_url = None
+
+ except IndexError:
+ LOG.error("Failed unpacking Spotify artist info")
+ return None, None
+ except (JSONDecodeError, requests.HTTPError):
+ LOG.error("Failed making request to Spotify API")
+ return None, None
+
+ embed = create_embed(
+ title="Artist Queued",
+ description=(
+ f"Top `{num_tracks}` track by **{name}**\n\n"
+ f"Queued by {user.mention}"
+ ),
+ thumbnail=artwork_url,
+ )
+ return artist, embed
diff --git a/test.py b/test.py
deleted file mode 100644
index bbfe23b..0000000
--- a/test.py
+++ /dev/null
@@ -1,3 +0,0 @@
-while not Exception:
- print("Test")
- Exception