Last active
March 20, 2022 19:08
-
-
Save AgeOfMarcus/635c824688ed525ab181409a1a17997c to your computer and use it in GitHub Desktop.
Python script using the spotipy library to merge multiple child playlists' tracks into one parent playlist without duplicates.
This file contains hidden or 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
''' | |
Name : spotify_playlist_combine.py | |
Author : Marcus Weinberger | |
About : This program takes multiple "child" playlists and combines their tracks | |
(without duplicates). Then, tracks from playlists marked for removal are | |
removed from the list. The parent playlist is emptied, and all tracks added. | |
You might need to run it a couple times because it throws errors and idk why, | |
but run it twice and usually it will have done all it needs to. | |
''' | |
import spotipy | |
from spotipy.oauth2 import SpotifyOAuth | |
from dotenv import load_dotenv | |
import os | |
load_dotenv() # save your environment variables in the same directory as this script in a .env file | |
# Make sure your application has the redirect_uri configured the same. | |
# It doesn't need to be reachable. https://127.0.0.1/callback works fine. | |
auth_manager = SpotifyOAuth( | |
client_id=os.getenv('SPOTIFY_CLIENT_ID'), | |
client_secret=os.getenv('SPOTIFY_CLIENT_SECRET'), | |
scope='playlist-modify-public', | |
redirect_uri='https://127.0.0.1/callback' | |
) | |
sp = spotipy.Spotify(auth_manager=auth_manager) | |
####### EDIT THESE VARIABLES ####### | |
PL_PARENT = '5PHoZ0ogEayVPilp2cq4p7' # dxm | |
PL_CHILDS = [ | |
'5xSG6BCHFbRoj64Y7fM56n', # vyv | |
'0pSMHk2yCLedHzDHnzZoc8', # flp | |
'0atxFIMASi6z1YiYv6PrWb', # cnd | |
'5Hur608iMkjucDQqZS6YAa', # he | |
'6lvfbcgQ0O4BOcVSipH0Dr', # snm | |
'2laqXV38PevvZ5oCPPV7dx', # dav | |
] | |
PL_REMOVE = [ | |
'0dPPa4MSRuj1rP06oipf5e', # k | |
'4jZILf6GxjxBFK3Ju9xvHX', # non | |
] | |
####### END CONFIGURATION ####### | |
# get tracks in parent playlist | |
PARENT_TRACKS = set() | |
PL_TRACKS = sp.playlist(PL_PARENT)['tracks'] | |
while True: | |
for track in PL_TRACKS['items']: | |
song_id = track['track']['id'] | |
if song_id: PARENT_TRACKS.add(song_id) | |
if PL_TRACKS['next']: | |
PL_TRACKS = sp.next(PL_TRACKS) | |
else: | |
break | |
PARENT_TRACKS = list(PARENT_TRACKS) | |
# get tracks from children to add | |
tracks = set() | |
for PL in PL_CHILDS: | |
playlist = sp.playlist(PL)['tracks'] | |
while True: | |
for track in playlist['items']: | |
song_id = track['track']['id'] | |
if song_id and not song_id in PARENT_TRACKS: | |
tracks.add(song_id) | |
print('Added:', track['track']['name']) | |
if playlist['next']: | |
playlist = sp.next(playlist) | |
else: | |
break | |
tracks = list(tracks) | |
# get tracks scheduled for removal | |
remove = set() | |
for PL in PL_REMOVE: | |
playlist = sp.playlist(PL)['tracks'] | |
while True: | |
for track in playlist['items']: | |
song_id = track['track']['id'] | |
if song_id and not song_id in remove: | |
remove.add(song_id) | |
print('Removing:', track['track']['name']) | |
if playlist['next']: | |
playlist = sp.next(playlist) | |
else: | |
break | |
remove = list(remove) | |
# merging shit | |
NEW_PARENT_TRACKS = set() | |
for id in [*PARENT_TRACKS, *tracks]: | |
if not id in remove and not id in NEW_PARENT_TRACKS: | |
NEW_PARENT_TRACKS.add(id) | |
NEW_PARENT_TRACKS = list(NEW_PARENT_TRACKS) | |
# queued for removal | |
TO_REMOVE = [x for x in PARENT_TRACKS if not x in NEW_PARENT_TRACKS] | |
# queued for addition | |
TO_ADD = [x for x in NEW_PARENT_TRACKS if not x in PARENT_TRACKS] | |
# make changes | |
print('Removing old songs...') | |
removed = 0 | |
while not removed == len(TO_REMOVE): | |
newtracks = TO_REMOVE[removed:removed+99] | |
sp.playlist_remove_all_occurrences_of_items(PL_PARENT, newtracks) | |
removed += 99 | |
print('Syncing to parent playlist...') | |
added = 0 | |
while not added == len(TO_ADD): | |
newtracks = TO_ADD[added:added+99] # max 100 songs at a time | |
sp.playlist_add_items(PL_PARENT, newtracks) | |
added += 99 | |
print('Done!') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment