Add get_playlist; refactoring

This commit is contained in:
Nic
2024-12-07 17:20:52 +01:00
parent 086c50f070
commit a04fa4bbad
4 changed files with 169 additions and 49 deletions

View File

@@ -13,7 +13,7 @@ Diese drei Parameter müssen vorab als Environment Variables definiert werden:
```bash
export SPOTIPY_CLIENT_ID='client id'
export SPOTIPY_CLIENT_SECRET='client secret'
export SPOTIPY_CALLBACK_URL='http://localhost:8888/callback'
export SPOTIPY_REDIRECT_URI='http://localhost:8888/callback'
```
Die Callback URL muss mit der in der App angegebenen Callback URL

111
fetch.py
View File

@@ -4,62 +4,77 @@ import os
import spotipy
import spotipy.util as util
# get credentials and callback URL from environment variables
# HINT: callback URL has to match Spotify App settings
client_id: str = os.environ.get("SPOTIPY_CLIENT_ID")
client_secret: str = os.environ.get("SPOTIPY_CLIENT_SECRET")
redirect_uri: str = os.environ.get("SPOTIPY_REDIRECT_URI")
from utils import get_artists
# don't edit scope, but edit user name!
scope: str = "user-library-read"
username: str = "hntngprty"
# get user auth token
token: str = util.prompt_for_user_token(
username,
scope,
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
)
def main():
"""
Main execution point.
"""
# raw responses from Spotify API
items: list[dict] = []
# get credentials and callback URL from environment variables
# HINT: callback URL has to match Spotify App settings
client_id: str = os.environ.get("SPOTIPY_CLIENT_ID")
client_secret: str = os.environ.get("SPOTIPY_CLIENT_SECRET")
redirect_uri: str = os.environ.get("SPOTIPY_REDIRECT_URI")
# response elements reduced to (artist, title) tuples
tracks: list[tuple[str, str]] = []
# don't edit scope, but edit user name!
scope: str = "user-library-read"
username: str = "username"
shall_continue: bool = True
i: int = 0
# get user auth token
token: str = util.prompt_for_user_token(
username,
scope,
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
)
if token:
while shall_continue:
sp = spotipy.Spotify(auth=token)
results = sp.current_user_saved_tracks(offset=i, limit=50)
# raw responses from Spotify API
items: list[dict] = []
# break if response is empty
if len(results["items"]) == 0:
break
# response elements reduced to (artist, title) tuples
tracks: list[tuple[str, str]] = []
# add items; increase offset
print(results)
items += results["items"]
i += 50
shall_continue: bool = True
i: int = 0
# reduce API responses to just artists and tracks
for item in items:
track: str = item["track"]
artist: str = track["artists"][0]["name"]
title: str = track["name"]
# add track
tracks.append((artist, title))
if token:
# initialize API client
client = spotipy.Spotify(auth=token)
while shall_continue:
results = client.current_user_saved_tracks(offset=i, limit=50)
# output artist and track
print(f"{artist} - {title}")
# break if response is empty
if len(results["items"]) == 0:
break
# final step: write tracks to tracks.csv file
with open("tracks.csv", "w", encoding="utf8") as file:
writer = csv.writer(file, quotechar='"')
writer.writerow(("Artist", "Title"))
writer.writerows(tracks)
# add items; increase offset
print(results)
items += results["items"]
i += 50
# reduce API responses to just artists and tracks
for item in items:
track: str = item["track"]
artist: str = get_artists(track["artists"])
title: str = track["name"]
# add track
tracks.append((artist, title))
# output artist and track
print(f"{artist} - {title}")
# final step: write tracks to tracks.csv file
with open("tracks.csv", "w", encoding="utf8") as file:
writer = csv.writer(file, quotechar='"')
writer.writerow(("Artist", "Title"))
writer.writerows(tracks)
if __name__ == "__main__":
# execution
main()

91
get_playlist.py Normal file
View File

@@ -0,0 +1,91 @@
import csv
import os
import sys
import spotipy
import spotipy.util as util
from utils import get_artists
def main(playlist_id: str):
"""
Main execution point.
"""
# get credentials and callback URL from environment variables
# HINT: callback URL has to match Spotify App settings
client_id: str = os.environ.get("SPOTIPY_CLIENT_ID")
client_secret: str = os.environ.get("SPOTIPY_CLIENT_SECRET")
redirect_uri: str = os.environ.get("SPOTIPY_REDIRECT_URI")
# don't edit scope, but edit user name and playlist_id!
scope: str = "user-library-read"
username: str = "hntngprty"
# get user auth token
token: str = util.prompt_for_user_token(
username,
scope,
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
)
# raw responses from Spotify API
items: list[dict] = []
# response elements reduced to (artist, title) tuples
tracks: list[tuple[str, str]] = []
shall_continue: bool = True
i: int = 0
if token:
# initialize API client
client = spotipy.Spotify(auth=token)
while shall_continue:
results = client.playlist_items(playlist_id=playlist_id, offset=i, limit=50)
# break if response is empty
if len(results["items"]) == 0:
break
# add items; increase offset
print(results)
items += results["items"]
i += 50
# reduce API responses to just artists and tracks
for item in items:
track: str = item["track"]
artist: str = get_artists(track["artists"])
title: str = track["name"]
# add track
tracks.append((artist, title))
# output artist and track
print(f"{artist} - {title}")
# final step: write tracks to tracks.csv file
with open(f"playlist-{playlist_id}.csv", "w", encoding="utf8") as file:
writer = csv.writer(file, quotechar='"')
writer.writerow(("Artist", "Title"))
writer.writerows(tracks)
if __name__ == "__main__":
playlist_id: str = ""
# get argument vector; ask for playlist id if it's not given,
# otherwise use argv[1] as playlist id
args = sys.argv[1:]
if len(args) == 0:
playlist_id = input("Playlist ID: ")
else:
playlist_id = args[0]
# execution
main(playlist_id)

14
utils.py Normal file
View File

@@ -0,0 +1,14 @@
def get_artists(artists: list[dict]) -> str:
"""
Builds an artists name from a list of artist objects.
:param artists: list of artists as provided by spotipy
:returns: artists string (comma-space-separated artist names)
"""
artist_names: list[str] = []
for artist in artists:
artist_names.append(artist["name"])
return ", ".join(artist_names)