Advertisement
Toumo

spotify_playlist_backup.py

Apr 9th, 2023 (edited)
1,297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.58 KB | None | 0 0
  1. import os
  2. import spotipy
  3. import requests
  4. import pandas as pd
  5.  
  6. def playlist_backup(spotify, user_id, playlist_id, cover_art_save_dir = ""):
  7.     playlist = spotify.user_playlist_tracks(user_id, playlist_id)
  8.     playlist_items = playlist["items"]
  9.     df = pd.DataFrame(columns = ["track", "artists" , "album", "datetime_added", "duration_ms", "track_URI", "album_URI"])
  10.     while playlist["next"]:
  11.         playlist = spotify.next(playlist)
  12.         playlist_items.extend(playlist["items"])
  13.     for element in playlist_items:
  14.         if cover_art_save_dir: save_cover(element, cover_art_save_dir)
  15.         df.loc[len(df)] = [element["track"]["name"],                                              # track
  16.                            ", ".join([artist["name"] for artist in element["track"]["artists"]]), # artists
  17.                            element["track"]["album"]["name"],                                     # album
  18.                            element["added_at"],                                                   # datetime_added
  19.                            element["track"]["duration_ms"],                                       # duration_ms
  20.                            element["track"]["uri"],                                               # track_URI
  21.                            element["track"]["album"]["uri"],]                                     # album_URI
  22.     df.to_json(os.path.join(os.path.dirname(__file__), "playlist.json"), orient="split")
  23.  
  24. def save_cover(playlist_element, save_dir):
  25.     album_uri = playlist_element["track"]["album"]["id"]
  26.     album_title = playlist_element["track"]["album"]["name"]
  27.     cover_url = playlist_element["track"]["album"]["images"][0]["url"]
  28.     album_filename = clean_filename(album_title)
  29.     full_save_path = os.path.join(save_dir, album_uri + "_" + album_filename + ".jpg")
  30.     if not os.path.isfile(full_save_path):
  31.         response = requests.get(cover_url)
  32.         with open(full_save_path, "wb") as f:
  33.             f.write(response.content)
  34.  
  35. def clean_filename(filename):
  36.     replacer_map = {"#": "no.", "%": "percent", "&": "and", "{": "(", "}": ")", "\\": "-", "<": "(", ">": ")", "*": "X", "?": "", "!": "", "$": "", " ": "_", "/": "-", "'": "", '"': "", ":": "_-", "@": "at", "+": "plus", "|": "-", "=": "equals", "`": "",}
  37.     for symbol in replacer_map.keys():
  38.         filename = filename.replace(symbol, replacer_map[symbol])
  39.     return filename
  40.  
  41. sp = spotipy.Spotify(client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials())
  42. playlist_backup(sp, "n58k0fnejbizfknk4i4m76mkt", "2YvcU4kgVHhFSQSmbO6cUS", "") # "/home/tomo/Downloads/cover_art/")
  43.  
  44. """
  45. https://spotipy.readthedocs.io/en/2.22.1/
  46. https://www.youtube.com/watch?v=3RGm4jALukM
  47. https://github.com/spotipy-dev/spotipy/issues/246#issuecomment-891805828
  48. https://developer.spotify.com/dashboard/2bbe2fd984d5441f96de1cb006841db7/settings
  49. https://unix.stackexchange.com/questions/117467/how-to-permanently-set-environmental-variables (.bashrc)
  50.  
  51. export SPOTIPY_CLIENT_ID=2bbe2fd984d5441f96de1cb006841db7
  52. export SPOTIPY_CLIENT_SECRET=...
  53. export SPOTIPY_REDIRECT_URI=https://localhost:8888/callback
  54.  
  55. Example of element in playlist_items:
  56. {'added_at': '2021-09-16T23:18:40Z',
  57. 'added_by': {'external_urls': {'spotify': 'https://open.spotify.com/user/n58k0fnejbizfknk4i4m76mkt'},
  58.              'href': 'https://api.spotify.com/v1/users/n58k0fnejbizfknk4i4m76mkt',
  59.              'id': 'n58k0fnejbizfknk4i4m76mkt',
  60.              'type': 'user',
  61.              'uri': 'spotify:user:n58k0fnejbizfknk4i4m76mkt'},
  62. 'is_local': False,
  63. 'primary_color': None,
  64. 'track': {'album': {'album_group': 'album',
  65.                     'album_type': 'album',
  66.                     'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/7M1FPw29m5FbicYzS2xdpi'},
  67.                                 'href': 'https://api.spotify.com/v1/artists/7M1FPw29m5FbicYzS2xdpi',
  68.                                 'id': '7M1FPw29m5FbicYzS2xdpi',
  69.                                 'name': 'King Crimson',
  70.                                 'type': 'artist',
  71.                                 'uri': 'spotify:artist:7M1FPw29m5FbicYzS2xdpi'}],
  72.                     'available_markets': [],
  73.                     'external_urls': {'spotify': 'https://open.spotify.com/album/5wec5BciMpDMzlEFpYeHse'},
  74.                     'href': 'https://api.spotify.com/v1/albums/5wec5BciMpDMzlEFpYeHse',
  75.                     'id': '5wec5BciMpDMzlEFpYeHse',
  76.                     'images': [{'height': 640,
  77.                                 'url': 'https://i.scdn.co/image/ab67616d0000b2739f2179592d196f575b7a0ff5',
  78.                                 'width': 640},
  79.                                {'height': 300,
  80.                                 'url': 'https://i.scdn.co/image/ab67616d00001e029f2179592d196f575b7a0ff5',
  81.                                 'width': 300},
  82.                                {'height': 64,
  83.                                 'url': 'https://i.scdn.co/image/ab67616d000048519f2179592d196f575b7a0ff5',
  84.                                 'width': 64}],
  85.                     'is_playable': True,
  86.                     'name': 'In The Court Of The Crimson King (Expanded & Remastered Original Album Mix)',
  87.                     'release_date': '1969-10-10',
  88.                     'release_date_precision': 'day',
  89.                     'total_tracks': 8,
  90.                     'type': 'album',
  91.                     'uri': 'spotify:album:5wec5BciMpDMzlEFpYeHse'},
  92.           'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/7M1FPw29m5FbicYzS2xdpi'},
  93.                       'href': 'https://api.spotify.com/v1/artists/7M1FPw29m5FbicYzS2xdpi',
  94.                       'id': '7M1FPw29m5FbicYzS2xdpi',
  95.                       'name': 'King Crimson',
  96.                       'type': 'artist',
  97.                       'uri': 'spotify:artist:7M1FPw29m5FbicYzS2xdpi'}],
  98.           'available_markets': [],
  99.           'disc_number': 1,
  100.           'duration_ms': 442580,
  101.           'episode': False,
  102.           'explicit': False,
  103.           'external_ids': {'isrc': 'GBCTX1400800'},
  104.           'external_urls': {'spotify': 'https://open.spotify.com/track/5yClziwiwTdqRmdPQl3NDz'},
  105.           'href': 'https://api.spotify.com/v1/tracks/5yClziwiwTdqRmdPQl3NDz',
  106.           'id': '5yClziwiwTdqRmdPQl3NDz',
  107.           'is_local': False,
  108.           'name': '21st Century Schizoid Man',
  109.           'popularity': 0,
  110.           'preview_url': None,
  111.           'track': True,
  112.           'track_number': 1,
  113.           'type': 'track',
  114.           'uri': 'spotify:track:5yClziwiwTdqRmdPQl3NDz'},
  115. 'video_thumbnail': {'url': None}}
  116.  
  117. If multiple artists per track, element["track"]["artists"] looks like so:
  118. 'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/29XOeO6KIWxGthejQqn793'},
  119.                              'href': 'https://api.spotify.com/v1/artists/29XOeO6KIWxGthejQqn793',
  120.                              'id': '29XOeO6KIWxGthejQqn793',
  121.                              'name': 'Flying Lotus',
  122.                              'type': 'artist',
  123.                              'uri': 'spotify:artist:29XOeO6KIWxGthejQqn793'},
  124.            {'external_urls': {'spotify': 'https://open.spotify.com/artist/4CvTDPKA6W06DRfBnZKrau'},
  125.                              'href': 'https://api.spotify.com/v1/artists/4CvTDPKA6W06DRfBnZKrau',
  126.                              'id': '4CvTDPKA6W06DRfBnZKrau',
  127.                              'name': 'Thom Yorke',
  128.                              'type': 'artist',
  129.                              'uri': 'spotify:artist:4CvTDPKA6W06DRfBnZKrau'}]
  130. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement