Skip to content

Instantly share code, notes, and snippets.

@brynedwards
Created July 20, 2017 13:58
Show Gist options
  • Save brynedwards/de55f52dc5eaee50472eb414b67a1b74 to your computer and use it in GitHub Desktop.
Save brynedwards/de55f52dc5eaee50472eb414b67a1b74 to your computer and use it in GitHub Desktop.
Script to dump Spotify playlists to xspf files.
"""
Script to dump Spotify playlists to xspf files. Replace the
playlists list and username string with your values. File name
format is <today_filename.xspf>; see line 65. You'll also need
to auth with the Spotify web API; see the Spotipy API docs:
https://spotipy.readthedocs.io/en/latest/#authorization-code-flow
"""
from datetime import date
import xml.etree.ElementTree as ET
import spotipy
import spotipy.util as util
limit = 100
# Each tuple is (filename, playlist_owner, playlist_id)
# Discover Weekly and Release Radar playlists are actually controlled by
# Spotify hence the 2nd value.
playlists = [
('discover_weekly', 'spotify', '37i9dQZEVXcCOH2b4uaCom'),
('release_radar', 'spotify', '37i9dQZEVXbvrKDaLca5Ap'),
]
scope = 'user-library-read'
username = 'brynser'
token = util.prompt_for_user_token(username, scope)
def get_tracks_from_playlist(client, username, playlist):
def load(offset, tracks):
response = client.user_playlist_tracks(username, playlist, limit=limit,
offset=offset)
if len(response['items']) == 0:
return tracks
else:
tracks = tracks + [i['track'] for i in response['items']]
return load(offset + limit, tracks)
return load(0, [])
def write_playlist(name, tracks):
def to_element(track):
kv = [
('location', track['uri']),
('title', track['name']),
('creator', ', '.join([a['name'] for a in track['artists']])),
('album', track['album']['name']),
('duration', str(track['duration_ms'])),
('trackNum', str(track['track_number']))
]
def el(tag, text):
e = ET.Element(tag)
e.text = text
return e
elements = [el(tag, text) for (tag, text) in kv]
parent = ET.Element('track')
parent.extend(elements)
return parent
root = ET.Element(
'playlist',
attrib={
'version': '1',
'xmlns': 'http://xspf.org/ns/0'})
track_list = ET.SubElement(root, 'trackList')
track_list.extend([to_element(t) for t in tracks])
tree = ET.ElementTree(element=root)
tree.write(date.today().isoformat() + '_' + name + '.xspf')
def main():
token = util.prompt_for_user_token('brynser', scope)
if token:
client = spotipy.Spotify(auth=token)
loaded_playlists = [
(name, get_tracks_from_playlist(
client, username, id)) for (
name, username, id) in playlists]
[write_playlist(*p) for p in loaded_playlists]
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment