Skip to content

Instantly share code, notes, and snippets.

@onhernandes
Last active August 8, 2018 20:09
Show Gist options
  • Save onhernandes/72d75a8f834264017a65866a2b6cbf9b to your computer and use it in GitHub Desktop.
Save onhernandes/72d75a8f834264017a65866a2b6cbf9b to your computer and use it in GitHub Desktop.
Shuffle your Spotify's playlist!
# Shuffle your playlist songs!
# This script uses Spotify's API endpoint for *replacing* all songs
# within your playlist. So after shuffling, your songs will appear with a new added date
#
# You need to pass part of your playlist's name and a valid token
# Generate token here: https://developer.spotify.com/console/put-playlist-tracks/
#
# This script uses riffle shuffle 7 times
# https://stackoverflow.com/questions/19898138/how-can-we-riffle-shuffle-the-elements-of-a-list-in-python#19898430
#
# Usage: python3 spotify-shuffle.py "<playlist's name>" <token>
# python3 spotify-shuffle.py dazzling <token>
# python3 spotify-shuffle.py "all black" <token>
from urllib import request,parse
from functools import reduce
import re
import json
import sys
if len(sys.argv) < 3:
print("You must give a playlist name and an API token!")
sys.exit()
playlist_name = sys.argv[1]
token = sys.argv[2]
def make_url(path, additional):
additional = parse.urlencode(additional)
return "https://api.spotify.com/v1/%s?%s" % (path, additional)
def req(path, additional = {}, data = None, method = 'GET'):
req = request.Request(make_url(path, additional), data=data, method=method)
req.add_header("Authorization", "Bearer %s" % (token))
req.add_header("Content-Type", "application/json")
req.add_header("Accept", "application/json")
r = request.urlopen(req)
return json.loads(r.read())
def get_playlists(offset = 0):
data = req("me/playlists", { "offset": offset, "limit": 50 })
results = data["items"]
if len(results) < data["total"]:
results = results + get_playlists(offset + 1)
return results
def find_playlist():
playlists = get_playlists()
result = list(filter(lambda p: playlist_name in p["name"], playlists))
return result[0] if len(result) > 0 else False
def get_playlist_tracks(user_id, playlist_id, offset = 0):
data = req("users/%s/playlists/%s/tracks" % (user_id, playlist_id), { "offset": offset })
results = data["items"]
if data["next"]:
offset = len(results)
results = results + get_playlist_tracks(user_id, playlist_id, offset)
return results
def reorder_tracks(uris):
half = int(len(uris) / 2)
first = iter(uris[0:half])
second = iter(uris[half:])
result = []
for i in range(half):
result.append(next(first))
result.append(next(second))
if len(uris) % 2 != 0:
result.append(next(second))
return result
def main():
playlist = find_playlist()
user_id = playlist["owner"]["id"]
playlist_id = playlist["id"]
tracks = get_playlist_tracks(user_id, playlist_id)
uris = list(map(lambda t: t["track"]["uri"], tracks))
for i in range(0,8):
uris = reorder_tracks(uris)
response = req("users/%s/playlists/%s/tracks" % (user_id, playlist_id), {}, str.encode(json.dumps({ "uris": uris[0:100] })), "PUT")
counter = 100
while len(uris[counter:counter+100]) > 0:
req("users/%s/playlists/%s/tracks" % (user_id, playlist_id), {}, str.encode(json.dumps({ "uris": uris[counter:counter+100] })), "POST")
counter += 100
print("Success! Your playlist has been shuffled")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment