From 5c142398b5adb60c5c7ade03f0c438a2a807fb73 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Wed, 9 Jun 2021 22:59:52 +0200
Subject: [PATCH] #1 - added script do backup followed artists

---
 SpotifyFollowedArtistsBackup.py | 99 +++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 SpotifyFollowedArtistsBackup.py

diff --git a/SpotifyFollowedArtistsBackup.py b/SpotifyFollowedArtistsBackup.py
new file mode 100644
index 0000000..842d8a8
--- /dev/null
+++ b/SpotifyFollowedArtistsBackup.py
@@ -0,0 +1,99 @@
+import csv
+import json
+import os
+from datetime import datetime, timedelta
+from typing import List
+
+import spotipy
+from TheCodeLabs_BaseUtils.DefaultLogger import DefaultLogger
+from spotipy.oauth2 import SpotifyPKCE
+
+LOG_FORMAT = '[%(levelname)-7s] - %(asctime)s - %(message)s'
+LOGGER = DefaultLogger().create_logger_if_not_exists('SpotifyFollowerBackup', logFormat=LOG_FORMAT)
+
+
+class SpotifyFollowedArtistsBackup:
+    DATE_FORMAT = '%Y-%m-%d_%H-%M-%S'
+    DATE_FORMAT_SHORT = '%Y-%m-%d'
+    INVALID_CHARS = [' ', '\t', '\n']
+    REPLACE_CHAR = '_'
+
+    def __init__(self, clientID: str, exportFolder: str):
+        self._exportFolder = exportFolder
+        if self._exportFolder:
+            os.makedirs(self._exportFolder, exist_ok=True)
+
+        client_credentials_manager = SpotifyPKCE(client_id=clientID, redirect_uri='http://localhost:8080',
+                                                 scope='user-follow-read')
+        self._spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
+
+    def backup_followed_artists(self):
+        followedArtists = self.__get_followed_artists()
+
+        exportPath = self.__determine_export_path('followed_artists')
+
+        LOGGER.info(f'>>> Exporting followed artists to "{exportPath}"...')
+        self.__export_csv(exportPath, followedArtists)
+        LOGGER.info('Exporting DONE')
+
+    def __get_followed_artists(self):
+        followedArtists = self._spotify.current_user_followed_artists(limit=20, after=None)['artists']
+
+        results = followedArtists['items']
+        while followedArtists['next']:
+            followedArtists = self._spotify.next(followedArtists)['artists']
+            results.extend(followedArtists['items'])
+
+        LOGGER.info(f'Fetched {len(results)} followed artists')
+        return results
+
+    def __determine_export_path(self, fileName):
+        for item in self.INVALID_CHARS:
+            fileName = fileName.replace(item, self.REPLACE_CHAR)
+        completeFileName = f'{datetime.strftime(datetime.now(), self.DATE_FORMAT)}_{fileName}.csv'
+        exportPath = os.path.join(self._exportFolder, completeFileName)
+        return exportPath
+
+    def __export_csv(self, exportPath: str, artists: List):
+        with open(exportPath, 'w', newline='', encoding='utf-8') as f:
+            writer = csv.writer(f, delimiter=';', quotechar='|', quoting=csv.QUOTE_MINIMAL)
+            writer.writerow(('id', 'name', 'url', 'uri'))
+
+            for artist in artists:
+                try:
+                    id = artist['id']
+                    name = artist['name']
+                    url = artist['external_urls'].get('spotify', '')
+                    uri = artist['uri']
+
+                    writer.writerow((id, name, url, uri))
+                except Exception:
+                    LOGGER.exception(f'Error while exporting artist "{artist}"')
+
+    def clean_old_exports(self, daysToKeep):
+        if not daysToKeep:
+            LOGGER.info('Skipping deletion of old files')
+            return
+
+        minimumDate = datetime.today() - timedelta(days=int(daysToKeep))
+        LOGGER.info(f'>>> Deleting files older than {minimumDate} ({daysToKeep} days)')
+
+        files = [file for file in sorted(os.listdir(self._exportFolder)) if
+                 os.path.isfile(os.path.join(self._exportFolder, file))]
+
+        for file in files:
+            parts = file.split('_')
+            creationDate = datetime.strptime(parts[0], self.DATE_FORMAT_SHORT)
+            if creationDate < minimumDate:
+                LOGGER.info(f'Removing old file "{file}"')
+                os.remove(os.path.join(self._exportFolder, file))
+
+
+if __name__ == '__main__':
+    with open('config/settings.json', 'r', encoding='utf-8') as f:
+        SETTINGS = json.load(f)
+
+    spotifyBackup = SpotifyFollowedArtistsBackup(SETTINGS['spotifyAPI']['clientID'], SETTINGS['exportFolder'])
+    spotifyBackup.clean_old_exports(SETTINGS['daysToKeep'])
+    spotifyBackup.backup_followed_artists()
+    LOGGER.info('### DONE ###')
-- 
GitLab