aboutsummaryrefslogtreecommitdiff
path: root/code/utils/source_helpers/apple
diff options
context:
space:
mode:
authorParker <contact@pkrm.dev>2024-11-28 00:04:48 -0600
committerParker <contact@pkrm.dev>2024-11-28 00:04:48 -0600
commit382c42262954767acc3f5ee3e008e03acbfc4f26 (patch)
tree1617f4cf15e349d34408f71b07032ea7a6ba6594 /code/utils/source_helpers/apple
parent5eb665c99b1fcfaf9500daf7811f835d002e078e (diff)
Overhaul \`play\` command
- Split custom sources into helper functions - Add proper logging and handling - Fix LoadError embed messsage
Diffstat (limited to 'code/utils/source_helpers/apple')
-rw-r--r--code/utils/source_helpers/apple/album.py79
-rw-r--r--code/utils/source_helpers/apple/playlist.py90
-rw-r--r--code/utils/source_helpers/apple/song.py74
3 files changed, 243 insertions, 0 deletions
diff --git a/code/utils/source_helpers/apple/album.py b/code/utils/source_helpers/apple/album.py
new file mode 100644
index 0000000..3195e2d
--- /dev/null
+++ b/code/utils/source_helpers/apple/album.py
@@ -0,0 +1,79 @@
+import datetime
+import discord
+import requests
+from typing import Tuple, Optional
+from requests.exceptions import JSONDecodeError
+
+from utils.config import BOT_COLOR, LOG
+
+
+async def load(
+ headers: dict,
+ query: str,
+ user: discord.User,
+) -> Tuple[Optional[dict], Optional[discord.Embed]]:
+ """
+ Get the album info from the Apple Music API
+ """
+ album_id = query.split("/album/")[1].split("/")[1]
+
+ try:
+ # Get the album info
+ response = requests.get(
+ f"https://api.music.apple.com/v1/catalog/us/albums/{album_id}",
+ headers=headers,
+ )
+
+ if response.status_code == 404:
+ embed = discord.Embed(
+ title="Album Not Found",
+ description=(
+ "The album could not be found as the provided link is"
+ " invalid. Please try again."
+ ),
+ color=BOT_COLOR,
+ )
+ return None, embed
+
+ if response.status_code == 401:
+ LOG.error(
+ "Could not authorize with Apple Music API. Likely need to"
+ " restart the bot."
+ )
+ return None, None
+
+ response.raise_for_status()
+ # Unpack the album info
+ album = response.json()
+ name = album["data"][0]["attributes"]["name"]
+ artist = album["data"][0]["attributes"]["artistName"]
+ num_tracks = len(album["data"][0]["relationships"]["tracks"]["data"])
+ except IndexError:
+ LOG.error("Failed unpacking Apple Music album info")
+ return None, None
+ except (JSONDecodeError, requests.HTTPError):
+ LOG.error("Failed making request to Apple Music API")
+ return None, None
+
+ # Extract artwork URL, if available
+ artwork_url = (
+ album["data"][0]["attributes"].get("artwork", {}).get("url", None)
+ )
+ if artwork_url:
+ artwork_url = artwork_url.replace("{w}x{h}", "300x300")
+
+ embed = discord.Embed(
+ title="Album Queued",
+ description=(
+ f"**{name}** by **{artist}**\n"
+ f"` {num_tracks} ` tracks\n\n"
+ f"Queued by: {user.mention}"
+ ),
+ color=BOT_COLOR,
+ )
+ embed.set_thumbnail(url=artwork_url)
+ embed.set_footer(
+ text=datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + " UTC"
+ )
+
+ return album, embed
diff --git a/code/utils/source_helpers/apple/playlist.py b/code/utils/source_helpers/apple/playlist.py
new file mode 100644
index 0000000..8a27315
--- /dev/null
+++ b/code/utils/source_helpers/apple/playlist.py
@@ -0,0 +1,90 @@
+import datetime
+import discord
+import requests
+from typing import Tuple, Optional
+from requests.exceptions import JSONDecodeError
+
+from utils.config import BOT_COLOR, LOG
+
+
+async def load(
+ headers: dict,
+ query: str,
+ user: discord.User,
+) -> Tuple[Optional[dict], Optional[discord.Embed]]:
+ """
+ Get the playlist info from the Apple Music API
+ """
+ playlist_id = query.split("/playlist/")[1].split("/")[1]
+ try:
+ # Get all of the tracks in the playlist (limit at 100)
+ response = requests.get(
+ f"https://api.music.apple.com/v1/catalog/us/playlists/{playlist_id}/tracks?limit=100",
+ headers=headers,
+ )
+
+ if response.status_code == 404:
+ embed = discord.Embed(
+ title="Playlist Not Found",
+ description=(
+ "The playlist could not be found as the provided link is"
+ " invalid. Please try again."
+ ),
+ color=BOT_COLOR,
+ )
+ return None, embed
+
+ if response.status_code == 401:
+ LOG.error(
+ "Could not authorize with Apple Music API. Likely need to"
+ " restart the bot."
+ )
+ return None, None
+
+ response.raise_for_status()
+ playlist = response.json()
+
+ # Get the general playlist info (name, artwork)
+ response = requests.get(
+ f"https://api.music.apple.com/v1/catalog/us/playlists/{playlist_id}",
+ headers=headers,
+ )
+
+ response.raise_for_status()
+ # Unpack the playlist info
+ playlist_info = response.json()
+ name = playlist_info["data"][0]["attributes"]["name"]
+ num_tracks = len(playlist["data"])
+ except IndexError:
+ LOG.error("Failed unpacking Apple Music playlist info")
+ return None, None
+ except (JSONDecodeError, requests.HTTPError):
+ LOG.error("Failed making request to Apple Music API")
+ return None, None
+
+ # Extract artwork URL, if available
+ artwork_url = (
+ playlist_info["data"][0]["attributes"]
+ .get("artwork", {})
+ .get("url", None)
+ )
+ if artwork_url:
+ artwork_url = artwork_url.replace("{w}x{h}", "300x300")
+
+ embed = discord.Embed(
+ title="Playlist Queued",
+ description=(
+ f"**{name}**\n` {num_tracks} ` tracks\n\nQueued by: {user.mention}"
+ ),
+ color=BOT_COLOR,
+ )
+
+ # Add small alert if the playlist is the max size
+ if len(playlist["data"]) == 100:
+ embed.description += (
+ "\n\n*This playlist is longer than the 100 song"
+ " maximum. Only the first 100 songs will be"
+ " queued.*"
+ )
+
+ return playlist, embed
diff --git a/code/utils/source_helpers/apple/song.py b/code/utils/source_helpers/apple/song.py
new file mode 100644
index 0000000..55db003
--- /dev/null
+++ b/code/utils/source_helpers/apple/song.py
@@ -0,0 +1,74 @@
+import datetime
+import discord
+import requests
+from typing import Tuple, Optional
+from requests.exceptions import JSONDecodeError
+
+from utils.config import BOT_COLOR, LOG
+
+
+async def load(
+ headers: dict,
+ query: str,
+ user: discord.User,
+) -> Tuple[Optional[dict], Optional[discord.Embed]]:
+ """
+ Get the song info from the Apple Music API
+ """
+ song_id = query.split("/album/")[1].split("?i=")[1]
+
+ try:
+ # Get the song info
+ response = requests.get(
+ f"https://api.music.apple.com/v1/catalog/us/songs/{song_id}",
+ headers=headers,
+ )
+
+ if response.status_code == 404:
+ embed = discord.Embed(
+ title="Song Not Found",
+ description=(
+ "The song could not be found as the provided link is"
+ " invalid. Please try again."
+ ),
+ color=BOT_COLOR,
+ )
+ return None, embed
+
+ if response.status_code == 401:
+ LOG.error(
+ "Could not authorize with Apple Music API. Likely need to"
+ " restart the bot."
+ )
+ return None, None
+
+ response.raise_for_status()
+ # Unpack the song info
+ song = response.json()
+ name = song["data"][0]["attributes"]["name"]
+ artist = song["data"][0]["attributes"]["artistName"]
+ except IndexError:
+ LOG.error("Failed unpacking Apple Music song info")
+ return None, None
+ except (JSONDecodeError, requests.HTTPError):
+ LOG.error("Failed making request to Apple Music API")
+ return None, None
+
+ # Extract artwork URL, if available
+ artwork_url = (
+ song["data"][0]["attributes"].get("artwork", {}).get("url", None)
+ )
+ if artwork_url:
+ artwork_url = artwork_url.replace("{w}x{h}", "300x300")
+
+ embed = discord.Embed(
+ title="Song Queued",
+ description=f"**{name}** by **{artist}**\n\nQueued by: {user.mention}",
+ color=BOT_COLOR,
+ )
+ embed.set_thumbnail(url=artwork_url)
+ embed.set_footer(
+ text=datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") + " UTC"
+ )
+
+ return song, embed