RegsonDR / spotify-save-playlists-cron

Save Spotify's auto-generated playlists automatically - Powered by Github Actions.
MIT License
26 stars 41 forks source link

Save weekly as a new playlist #4

Open IDeserveToBeWrited opened 1 year ago

IDeserveToBeWrited commented 1 year ago

Hi, first I want to say thank you for the script, it works wonderfully. But I always "archieved" the weekly playlist by making a new playlist and naming it YEAR-MONTH-DAY it came out. I was doing that manually, but I didn't always remember to do that. Your script helped me achieve a backup so I always could retrieve it from there, but I finally found some time and will to expand it a little bit.

I see the code changed quite a bit since I pulled it and used it, so I'll leave the code with my additions here

from dotenv import load_dotenv, find_dotenv
import requests
import base64
import json
import os
from datetime import datetime

load_dotenv(find_dotenv())
REFRESH_TOKEN = os.environ.get("REFRESH_TOKEN").strip()
CLIENT_ID = os.environ.get("CLIENT_ID").strip()
CLIENT_SECRET = os.environ.get("CLIENT_SECRET").strip()
DISCOVER_WEEKLY_ID = os.environ.get("DISCOVER_WEEKLY_ID").strip()
SAVE_TO_ID = os.environ.get("SAVE_TO_ID").strip()

OAUTH_TOKEN_URL = "https://accounts.spotify.com/api/token"
def refresh_access_token():
    payload = {
        "refresh_token": REFRESH_TOKEN,
        "grant_type": "refresh_token",
        "client_id": CLIENT_ID,
    }
    encoded_client = base64.b64encode((CLIENT_ID + ":" + CLIENT_SECRET).encode('ascii'))
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
        "Authorization": "Basic %s" % encoded_client.decode('ascii')
    }
    response = requests.post(OAUTH_TOKEN_URL, data=payload, headers=headers)
    return response.json()

def get_playlist(access_token):
    url = "https://api.spotify.com/v1/playlists/%s" % DISCOVER_WEEKLY_ID
    headers = {
       "Content-Type": "application/json",
       "Authorization": "Bearer %s" % access_token
    }
    response = requests.get(url, headers=headers)
    return response.json()

def add_to_playlist(access_token, tracklist, playlist_id):
    url = "https://api.spotify.com/v1/playlists/%s/tracks" % playlist_id
    payload = {
        "uris" : tracklist
    }
    headers = {
       "Content-Type": "application/json",
       "Authorization": "Bearer %s" % access_token
    }
    response = requests.post(url, data=json.dumps(payload), headers=headers)
    return response.json()

# get users id for creating a new playlist
def get_user_id(access_token):
    url = "https://api.spotify.com/v1/me/"
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer %s" % access_token
    }
    response = requests.get(url, headers=headers)
    return response.json()['id']

# create a new playlist and return its id
def create_new_playlist_and_get_id(access_token, user_id):
    url = "https://api.spotify.com/v1/users/%s/playlists" % user_id
    payload = {
        "name": datetime.now().strftime('%Y-%m-%d'), # name playlist YEAR-MOTH-DAY
        "public": True
    }
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer %s" % access_token
    }
    response = requests.post(url, data=json.dumps(payload), headers=headers)
    print(response.status_code)
    if not response.status_code == 201:
        print("There was a problem creating a playlist, response " + response.status_code)
    else:
        return response.json()["id"]

def main():
    if REFRESH_TOKEN is None or CLIENT_ID is None or CLIENT_SECRET is None or DISCOVER_WEEKLY_ID is None or SAVE_TO_ID is None:
        print("Environment variables have not been loaded!")
        return

    access_token = refresh_access_token()['access_token']
    tracks =  get_playlist(access_token)['tracks']['items']
    tracklist = []
    for item in tracks:
        tracklist.append(item['track']['uri'])
    user_id = get_user_id(access_token)
    playlist_id = create_new_playlist_and_get_id(access_token, user_id)
    response = add_to_playlist(access_token, tracklist, playlist_id)

    if "snapshot_id" in response:
        print("Successfully added all songs")
    else:
        print(response)

main()

It's not perfect as it'll probably crash if there's a problem when creating a new playlist, but when it works it works. I like to keep them in a separate folder, but I couldn't find in the API documentation anything about folders, but can be done manually. What's important to me that the playlist is saved.