ZYSpotify is a Spotify downloader that enables users to find and download (a lot of) songs. For great plex compatibiliy, ensure that Prefer local metadata
is checked, Album Art is set to Local Files Only
, and server agents are configured for local media as described here.
This is a moderately modifed fork of ZSpotify with the goal of more robust large downloads (sqlite db instead of json archive file), eventually with the purpose to be run periodically/as a service to fetch new songs and more.
This is a work in progress, with active development. Expect breaking changes! Expect that this program will eventually crash and need to be restarted over a large download. However with my changes it should resume where it left off very quickly!
Currently only a subset of switches are supported, but eventually should be feature matched to zspotify. Only the shown switches in the usage are what have been tested, others may work (if NotImplementedError is removed).
- Use sqlite3 db instead of json archive
- Put credentials in db
- Download lyrics
- Use logging libary instead of printing
- Check for new artist songs/albums feature
- Ensure docker support works
- Add spotify playlist importer for plex <-- priority
- Automate changelog
- Ensure pip install works
- Get all other switches working
- Conform project for strict type checking
- Use code coverage/test suites
Tested with versions 3.10 <= python <= 3.12
, however slightly older versions probably work.
cd examples
Edit docker-compose.yml
with your username and password.
sudo docker compose run --rm zyspotify -lsdall
Note 🗒️: Remove username and password after running for first time.
Of course edit arguments as needed. To adjust music download dir, either
- use
-md
and edit compose file volume mounts. - (prefered) edit
./Music:/root/Music
to/your/dir:/root/Music
indocker-compose.yml
Clone the repo, use virtual enviroments, pip install the requirements and follow the usage below
Note: not yet implmemented features/switches will raise a NotImplementedError
and crash the program, as intended. This is not a bug!
usage: __main__.py [-h] [-ap] [-sp] [-ls] [-lsdall] [-pla PLAYLIST_ARTISTS] [-tr TRACK] [-al ALBUM] [-ar ARTIST] [-ep EPISODE] [-fs FULL_SHOW] [-cd CONFIG_DIR] [-ld LOG_DIR]
[-md MUSIC_DIR] [--dbdir DBDIR] [-pd EPISODES_DIR] [-v] [-af {mp3,ogg,source}] [--album-in-filename] [--antiban-time ANTIBAN_TIME]
[--antiban-album ANTIBAN_ALBUM] [--limit LIMIT] [-f] [-ns] [-flaq] [-sl] [-faq] [-rl] [-bd BULK_DOWNLOAD] [-mlsb MAX_LOG_SIZE_BYTES]
[-lfl {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}] [-sll {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}]
[search]
positional arguments:
search Searches for a track, album, artist or playlist or download by url
options:
-h, --help show this help message and exit
-ap, --all-playlists Downloads all saved playlist from your library
-sp, --select-playlists
Downloads a saved playlist from your library
-ls, --liked-songs Downloads your liked songs
-lsdall, --all-liked-all-artists
Download all songs from all (main) artists that appear in your liked songs
-pla PLAYLIST_ARTISTS, --playlist-artists PLAYLIST_ARTISTS
Download all artists in a playlist by id or url
-tr TRACK, --track TRACK
Downloads a track from their id or url
-al ALBUM, --album ALBUM
Downloads an album from their id or url
-ar ARTIST, --artist ARTIST
Downloads an artist from their id or url
-ep EPISODE, --episode EPISODE
Downloads a episode from their id or url
-fs FULL_SHOW, --full-show FULL_SHOW
Downloads all show episodes from id or url
-cd CONFIG_DIR, --config-dir CONFIG_DIR
Folder to save the config files
-ld LOG_DIR, --log-dir LOG_DIR
Folder to save the log files
-md MUSIC_DIR, --music-dir MUSIC_DIR
Folder to save the downloaded music files
--dbdir DBDIR Folder to save the database
-pd EPISODES_DIR, --episodes-dir EPISODES_DIR
Folder to save the downloaded episodes files
-v, --version Shows the current version of ZYSpotify and exit
-af {mp3,ogg,source}, --audio-format {mp3,ogg,source}
Audio format to download the tracks. Use 'source' to preserve the source format without conversion.
--album-in-filename Adds the album name to the filename
--antiban-time ANTIBAN_TIME
Time to wait between downloads to avoid Ban
--antiban-album ANTIBAN_ALBUM
Time to wait between album downloads to avoid Ban
--limit LIMIT Search limit
-f, --force-premium Force premium account
-ns, --not-skip-existing
If flag setted NOT Skip existing already downloaded tracks
-flaq, --force-liked-artist-query
Force (ignore db check) querying all liked artists on account, useful when new artists have been added since first query.
-sl, --skip-lyrics Skip downloading lyrics
-faq, --force-album-query
Force (ignore db check) query for albums for artists. Useful when artists release new songs since first query.
-rl, --repair-lyrics Download lyrics for each song if lyrics not downloaded but song was
-bd BULK_DOWNLOAD, --bulk-download BULK_DOWNLOAD
Bulk download from file with urls
-mlsb MAX_LOG_SIZE_BYTES, --max-log-size-bytes MAX_LOG_SIZE_BYTES
Maximum size of log file in bytes.
-lfl {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}, --log-file-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}
Level of logging for log file
-sll {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}, --stdout-log-level {CRITICAL,FATAL,ERROR,WARN,WARNING,INFO,DEBUG,NOTSET}
Level of logging for stdout (console)
It is recommended to use a burner account to avoid any possible account bans.
Pull requests are welcome. Please discuss any significant changes on the discussion tab before starting to save your time.
- GitHub Issues of this repository.
- DockerHub of this repository.
- Discussions of this repository.
artist_id
columns inalbums
andsongs
tables are missing featured artists (e.g. when more than one artist is on an album/song), currently only the first artist downloaded will have their artist_id take place here. The current fix is to just ignore repeated insert attempts for another artist on that item is set to be downloaded. Songs are not missed/ignored from being downloaded, rather theartist_id
will only and always be that one artist. This could be improved upon by inserting new artist compound id's like:abc123-abc123-...
for the first insertion but the rationale right now is if you require detailed metadata, just request it from spotify and take what you need. PR's are welcome to clean this up. Low priority since it does not affect any operations, just artist metadata is not as accurate as it could be.
- Footsiefat for original ZSpotify implementation
- jsavargas for the latest forked version