Merge e24f115f42
into 0ccf12c9c7
commit
a9d7b29e42
11
README.md
11
README.md
|
@ -7,16 +7,21 @@ To run the script, [save it from here](https://raw.githubusercontent.com/caseych
|
|||
|
||||
You can run the script from the command line:
|
||||
|
||||
python spotify-backup.py playlists.txt
|
||||
python spotify-backup.py --file playlists.txt
|
||||
|
||||
or, to get a JSON dump, use:
|
||||
|
||||
python spotify-backup.py playlists.json --format=json
|
||||
python spotify-backup.py --file playlists.json --format json
|
||||
|
||||
By default, it includes your playlists. To include your Liked Songs, you can use:
|
||||
|
||||
python spotify-backup.py playlists.txt --dump=liked,playlists
|
||||
python spotify-backup.py --file liked_songs_and_playlists.txt --dump liked playlists
|
||||
|
||||
By default, it includes all your playlists. To include and/or exclude some, you can use:
|
||||
|
||||
python spotify-backup.py --file no_autogenerated_playlists.txt --exclude-playlists "Discover Weekly" "Release Radar"
|
||||
|
||||
python spotify-backup.py --file best_of_playlists_without_1980s.txt --include-playlists "Best of year *" --exclude-playlists "Best of year 198?"
|
||||
|
||||
If for some reason the browser-based authorization flow doesn't work, you can also [generate an OAuth token](https://developer.spotify.com/web-api/console/get-playlists/) on the developer site (with the `playlist-read-private` permission) and pass it with the `--token` option.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import argparse
|
||||
import codecs
|
||||
import fnmatch
|
||||
import http.client
|
||||
import http.server
|
||||
import json
|
||||
|
@ -131,12 +132,16 @@ def main():
|
|||
parser = argparse.ArgumentParser(description='Exports your Spotify playlists. By default, opens a browser window '
|
||||
+ 'to authorize the Spotify Web API, but you can also manually specify'
|
||||
+ ' an OAuth token with the --token option.')
|
||||
parser.add_argument('--token', metavar='OAUTH_TOKEN', help='use a Spotify OAuth token (requires the '
|
||||
+ '`playlist-read-private` permission)')
|
||||
parser.add_argument('--dump', default='playlists', choices=['liked,playlists', 'playlists,liked', 'playlists', 'liked'],
|
||||
parser.add_argument('--token', metavar='OAUTH_TOKEN',
|
||||
help='use a Spotify OAuth token (requires the `playlist-read-private` permission)')
|
||||
parser.add_argument('--dump', default=['playlists'], nargs='+', choices=['liked', 'playlists'],
|
||||
help='dump playlists or liked songs, or both (default: playlists)')
|
||||
parser.add_argument('--format', default='txt', choices=['json', 'txt'], help='output format (default: txt)')
|
||||
parser.add_argument('file', help='output filename', nargs='?')
|
||||
parser.add_argument('--include-playlists', metavar='NAME_PATTERN', default=['*'], nargs='*',
|
||||
help='playlist name(s) to be included (default: all) if dumping playlists; ? and * wildcards may be used')
|
||||
parser.add_argument('--exclude-playlists', metavar='NAME_PATTERN', default=[], nargs='*',
|
||||
help='playlist name(s) to be excluded (default: none) if dumping playlists; ? and * wildcards may be used')
|
||||
parser.add_argument('--file', help='output filename')
|
||||
args = parser.parse_args()
|
||||
|
||||
# If they didn't give a filename, then just prompt them. (They probably just double-clicked.)
|
||||
|
@ -166,17 +171,23 @@ def main():
|
|||
liked_albums = spotify.list('me/albums', {'limit': 50})
|
||||
playlists += [{'name': 'Liked Songs', 'tracks': liked_tracks}]
|
||||
|
||||
# List all playlists and the tracks in each playlist
|
||||
# List all playlists and the tracks in each requested playlist
|
||||
if 'playlists' in args.dump:
|
||||
logging.info('Loading playlists...')
|
||||
playlist_data = spotify.list('users/{user_id}/playlists'.format(user_id=me['id']), {'limit': 50})
|
||||
logging.info(f'Found {len(playlist_data)} playlists')
|
||||
|
||||
# List all tracks in each playlist
|
||||
# List all tracks in each requested playlist
|
||||
for playlist in playlist_data:
|
||||
is_included = any([fnmatch.fnmatch(playlist['name'], pattern) for pattern in args.include_playlists])
|
||||
is_excluded = any([fnmatch.fnmatch(playlist['name'], pattern) for pattern in args.exclude_playlists])
|
||||
|
||||
if is_included and not is_excluded:
|
||||
logging.info('Loading playlist: {name} ({tracks[total]} songs)'.format(**playlist))
|
||||
playlist['tracks'] = spotify.list(playlist['tracks']['href'], {'limit': 100})
|
||||
playlists += playlist_data
|
||||
playlists.append(playlist)
|
||||
else:
|
||||
logging.info('Skipped playlist: {name}'.format(**playlist))
|
||||
|
||||
# Write the file.
|
||||
logging.info('Writing files...')
|
||||
|
|
Loading…
Reference in New Issue