Last active
August 8, 2018 20:09
-
-
Save onhernandes/72d75a8f834264017a65866a2b6cbf9b to your computer and use it in GitHub Desktop.
Shuffle your Spotify's playlist!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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