# NaviMigrate Spotify -> Navidrome playlist transfer tool in Go. ## What it does - Authenticates with Spotify using Authorization Code + PKCE (no client secret required). - Fetches one or more Spotify playlists by URL/URI/ID. - Searches for matching tracks in Navidrome using Subsonic `search3`. - Creates matching playlists in Navidrome and adds matched tracks. - Writes a JSON transfer report with unmatched tracks and errors. ## Requirements - Go 1.22+ - Spotify app client ID with redirect URI configured (default: `http://127.0.0.1:8888/callback`) - Navidrome URL, username, and password ## Build ```bash go build ./cmd/navimigrate ``` ## Usage ```bash ./navimigrate \ --spotify-client-id "" \ --navidrome-url "https://music.lofitrek.com" \ --navidrome-username "test_user" \ --navidrome-password "test_user" \ --playlist-url "https://open.spotify.com/playlist/16DZpOTLqZvdbqxEavLmWk" ``` ### Useful flags - `--playlist-url "..."` (repeatable): Spotify playlist URL/URI/ID - `--dry-run`: resolve matches only, do not create playlists or add tracks - `--report transfer-report.json`: report output path - `--concurrency 4`: concurrent track match workers - `--spotify-manual-code=true|false`: manual callback URL/code entry or local callback server ### Navidrome self-test Quick auth/search test without Spotify: ```bash ./navimigrate \ --navidrome-url "https://music.lofitrek.com" \ --navidrome-username "test_user" \ --navidrome-password "test_user" \ --navidrome-self-test ``` Write-path self-test (creates playlist, adds one track, then deletes playlist): ```bash ./navimigrate \ --navidrome-url "https://music.lofitrek.com" \ --navidrome-username "test_user" \ --navidrome-password "test_user" \ --navidrome-self-test \ --navidrome-self-test-write ``` ### Environment variables - `SPOTIFY_CLIENT_ID` - `SPOTIFY_REDIRECT_URI` (optional) - `SPOTIFY_SCOPES` (optional) - `NAVIMIGRATE_SPOTIFY_MANUAL_CODE` (optional, defaults to true) - `NAVIDROME_URL` - `NAVIDROME_USERNAME` - `NAVIDROME_PASSWORD` - `NAVIMIGRATE_DRY_RUN` (optional) - `NAVIMIGRATE_CONCURRENCY` (optional) - `NAVIMIGRATE_REPORT` (optional) - `NAVIMIGRATE_NAVIDROME_SELF_TEST` (optional) - `NAVIMIGRATE_NAVIDROME_SELF_TEST_WRITE` (optional) - `NAVIMIGRATE_NAVIDROME_SELF_TEST_QUERY` (optional)