Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
  • v1.0.0
  • v1.1.0
  • v1.10.0
  • v1.11.0
  • v1.12.0
  • v1.12.1
  • v1.12.2
8 results

Target

Select target project
  • deadlocker8/SpotifyBackup
1 result
Select Git revision
  • master
  • v1.0.0
  • v1.1.0
  • v1.10.0
  • v1.11.0
  • v1.12.0
  • v1.12.1
  • v1.12.2
8 results
Show changes

Commits on Source 2

exports/ exports/
config/settings.json config/settings.json
config/settings-import.json config/settings-import.json
config/settings-creator.json config/settings-creator-latest.json
config/settings-creator-random.json
config/settings-recorder.json config/settings-recorder.json
.cache .cache
.cache_creator .cache_creator
.cache_recorder .cache_recorder
.cache_spotify_creator
recorder/ recorder/
import json import json
import random
from typing import Dict, List from typing import Dict, List
import click
import spotipy import spotipy
from TheCodeLabs_BaseUtils.DefaultLogger import DefaultLogger from TheCodeLabs_BaseUtils.DefaultLogger import DefaultLogger
from spotipy import CacheFileHandler from spotipy import CacheFileHandler
...@@ -10,12 +12,17 @@ LOG_FORMAT = '[%(levelname)-7s] - %(asctime)s - %(message)s' ...@@ -10,12 +12,17 @@ LOG_FORMAT = '[%(levelname)-7s] - %(asctime)s - %(message)s'
LOGGER = DefaultLogger().create_logger_if_not_exists('SpotifyAutoPlaylistCreator', logFormat=LOG_FORMAT) LOGGER = DefaultLogger().create_logger_if_not_exists('SpotifyAutoPlaylistCreator', logFormat=LOG_FORMAT)
MODE_LATEST = 'LATEST'
MODE_RANDOM = 'RANDOM'
class SpotifyAutoPlaylistCreator: class SpotifyAutoPlaylistCreator:
def __init__(self, clientID: str, def __init__(self, clientID: str,
clientSecret: str, clientSecret: str,
playlistInfo: List[Dict[str, str]], playlistInfo: List[Dict[str, str]],
destinationPlaylistInfo: Dict[str, str], destinationPlaylistInfo: Dict[str, str],
numberOfTracks: int, numberOfTracks: int,
mode: str,
redirectUrl: str, redirectUrl: str,
openBrowser: bool, openBrowser: bool,
cacheFilePath: str): cacheFilePath: str):
...@@ -24,6 +31,7 @@ class SpotifyAutoPlaylistCreator: ...@@ -24,6 +31,7 @@ class SpotifyAutoPlaylistCreator:
self._playlistInfo = playlistInfo self._playlistInfo = playlistInfo
self._destinationPlaylistInfo = destinationPlaylistInfo self._destinationPlaylistInfo = destinationPlaylistInfo
self._numberOfTracks = numberOfTracks self._numberOfTracks = numberOfTracks
self._mode = mode
self._redirectUrl = redirectUrl self._redirectUrl = redirectUrl
self._openBrowser = openBrowser self._openBrowser = openBrowser
self._cacheFilePath = cacheFilePath self._cacheFilePath = cacheFilePath
...@@ -47,10 +55,19 @@ class SpotifyAutoPlaylistCreator: ...@@ -47,10 +55,19 @@ class SpotifyAutoPlaylistCreator:
LOGGER.info(f'>>> Fetching tracks for all source playlists...') LOGGER.info(f'>>> Fetching tracks for all source playlists...')
allTracks = [] allTracks = []
for playlistInfo in SETTINGS['playlists']: for playlistInfo in self._playlistInfo:
playlist = self.__get_playlist(playlistInfo['user'], playlistInfo['id']) playlist = self.__get_playlist(playlistInfo['user'], playlistInfo['id'])
allTracks.extend(self.__get_tracks(playlist)) allTracks.extend(self.__get_tracks(playlist))
LOGGER.info(f'>>> Run mode {self._mode}...')
if self._mode == MODE_LATEST:
self.__RunModeLatestTracks(allTracks, destinationPlaylist)
elif self._mode == MODE_RANDOM:
self.__RunModeRandom(allTracks, destinationPlaylist)
else:
raise RuntimeError(f'Unknown mode {self._mode}')
def __RunModeLatestTracks(self, allTracks: List, destinationPlaylist) -> None:
sortedTracks = sorted(allTracks, key=lambda d: d['added_at'], reverse=True) sortedTracks = sorted(allTracks, key=lambda d: d['added_at'], reverse=True)
LOGGER.info(f'>>> Collecting latest tracks (limit: {self._numberOfTracks})...') LOGGER.info(f'>>> Collecting latest tracks (limit: {self._numberOfTracks})...')
...@@ -61,6 +78,20 @@ class SpotifyAutoPlaylistCreator: ...@@ -61,6 +78,20 @@ class SpotifyAutoPlaylistCreator:
LOGGER.info(f'>>> Adding tracks to destination playlist "{destinationPlaylist["name"]}"...') LOGGER.info(f'>>> Adding tracks to destination playlist "{destinationPlaylist["name"]}"...')
self._spotify.playlist_add_items(self._destinationPlaylistInfo['id'], latestTrackUris) self._spotify.playlist_add_items(self._destinationPlaylistInfo['id'], latestTrackUris)
def __RunModeRandom(self, allTracks: List, destinationPlaylist) -> None:
randomTracks = []
filteredTracks = [t for t in allTracks if not t['is_local']]
while len(randomTracks) < self._numberOfTracks:
numberOfExercisesToGenerate = self._numberOfTracks - len(randomTracks)
randomTracks.extend(random.sample(filteredTracks, min(len(filteredTracks), numberOfExercisesToGenerate)))
LOGGER.info(f'>>> Found {len(randomTracks)} random tracks (limit: {self._numberOfTracks})')
LOGGER.info(f'>>> Adding tracks to destination playlist "{destinationPlaylist["name"]}"...')
randomTrackUris = self.__extract_track_uris(randomTracks)
self._spotify.playlist_add_items(self._destinationPlaylistInfo['id'], randomTrackUris)
def __CollectLatestTracks(self, sortedTracks): def __CollectLatestTracks(self, sortedTracks):
tracksToAdd = [] tracksToAdd = []
for track in sortedTracks: for track in sortedTracks:
...@@ -83,6 +114,7 @@ class SpotifyAutoPlaylistCreator: ...@@ -83,6 +114,7 @@ class SpotifyAutoPlaylistCreator:
LOGGER.info(f'>>> Removing {len(existingTracks)} tracks from destination ' LOGGER.info(f'>>> Removing {len(existingTracks)} tracks from destination '
f'playlist "{destinationPlaylist["name"]}"...') f'playlist "{destinationPlaylist["name"]}"...')
existingTracksUris = self.__extract_track_uris(existingTracks) existingTracksUris = self.__extract_track_uris(existingTracks)
if existingTracksUris:
self._spotify.playlist_remove_all_occurrences_of_items(self._destinationPlaylistInfo['id'], existingTracksUris) self._spotify.playlist_remove_all_occurrences_of_items(self._destinationPlaylistInfo['id'], existingTracksUris)
def __get_playlist(self, username: str, playlistID: str) -> Dict: def __get_playlist(self, username: str, playlistID: str) -> Dict:
...@@ -107,8 +139,10 @@ class SpotifyAutoPlaylistCreator: ...@@ -107,8 +139,10 @@ class SpotifyAutoPlaylistCreator:
return [track['track']['uri'] for track in tracks] return [track['track']['uri'] for track in tracks]
if __name__ == '__main__': @click.command()
with open('config/settings-creator.json', 'r', encoding='utf-8') as f: @click.option('--settings-path', '-s', 'settingsPath', help='Path to the settings file.', required=True)
def start(settingsPath) -> None:
with open(settingsPath, 'r', encoding='utf-8') as f:
SETTINGS = json.load(f) SETTINGS = json.load(f)
spotifyBackup = SpotifyAutoPlaylistCreator(SETTINGS['spotifyAPI']['clientID'], spotifyBackup = SpotifyAutoPlaylistCreator(SETTINGS['spotifyAPI']['clientID'],
...@@ -116,6 +150,7 @@ if __name__ == '__main__': ...@@ -116,6 +150,7 @@ if __name__ == '__main__':
SETTINGS['playlists'], SETTINGS['playlists'],
SETTINGS['destinationPlaylist'], SETTINGS['destinationPlaylist'],
SETTINGS['numberOfTracks'], SETTINGS['numberOfTracks'],
SETTINGS['mode'],
SETTINGS['redirectUrl'], SETTINGS['redirectUrl'],
SETTINGS['openBrowser'], SETTINGS['openBrowser'],
SETTINGS['cacheFilePath']) SETTINGS['cacheFilePath'])
...@@ -123,3 +158,7 @@ if __name__ == '__main__': ...@@ -123,3 +158,7 @@ if __name__ == '__main__':
spotifyBackup.run() spotifyBackup.run()
LOGGER.info('### DONE ###') LOGGER.info('### DONE ###')
if __name__ == '__main__':
start()
...@@ -18,5 +18,6 @@ ...@@ -18,5 +18,6 @@
"numberOfTracks": 10, "numberOfTracks": 10,
"redirectUrl": "http://localhost:8080", "redirectUrl": "http://localhost:8080",
"openBrowser": false, "openBrowser": false,
"cacheFilePath": ".cache" "cacheFilePath": ".cache",
"mode": "LATEST or RANDOM"
} }
\ No newline at end of file
[tool.poetry] [tool.poetry]
name = "SpotifyBackup" name = "SpotifyBackup"
version = "1.11.0" version = "1.12.0"
description = "Simple script for backing up public playlists from Spotify." description = "Simple script for backing up public playlists from Spotify."
authors = ["deadlocker8"] authors = ["deadlocker8"]
......
{ {
"version": { "version": {
"name": "v1.11.0", "name": "v1.12.0",
"code": 14, "code": 15,
"date": "09.10.23" "date": "30.08.24"
} }
} }
\ No newline at end of file