Skip to content

feat: add move_tracks script for playlist track migration#45

Draft
jmlrt wants to merge 3 commits into
mainfrom
feat/move-tracks-between-playlists
Draft

feat: add move_tracks script for playlist track migration#45
jmlrt wants to merge 3 commits into
mainfrom
feat/move-tracks-between-playlists

Conversation

@jmlrt
Copy link
Copy Markdown
Owner

@jmlrt jmlrt commented May 20, 2026

Summary

Add hacks/move_tracks.py script to move tracks between Spotify playlists with flexible sorting. This is a one-off hack designed to be migrated into the CLI later.

Changes

  • hacks/move_tracks.py (157 lines)

    • parse_playlist_identifier() — Extract 22-char ID from Spotify URLs
    • resolve_identifier() — Resolve URLs/names to playlist IDs using existing utilities
    • move_tracks() — Core logic: sort by artist/album, add tracks, remove from source
    • Supports dry-run mode and verbose logging
  • tests/test_move_tracks.py (475 lines)

    • 18 unit tests covering URL parsing, playlist resolution, sorting, dry-run behavior, edge cases
    • 100% code coverage for both files

Key Features

  • Playlist identification: Accepts Spotify URLs, 22-char IDs, or playlist names
  • Sorting: Alphabetically by first artist name, then album name (case-insensitive)
  • Dry-run mode: Preview changes without modifying Spotify or DB
  • Safe operations: Pre-flight + post-operation updates ensure DB consistency
  • Edge case handling: Gracefully handles missing artist/album metadata
  • CLI-ready: Function signature designed for future migration to main CLI

Testing

  • ✅ 18/18 new tests pass
  • ✅ All 333 existing tests still pass (no regressions)
  • ✅ Code style passes ruff checks
  • ✅ No secrets or artifacts in staged files

Example Usage

# Dry-run: see what would be moved
uv run python hacks/move_tracks.py \
  -s "https://open.spotify.com/playlist/4V8O33t0hSCnK4ABozG6xc?si=..." \
  -d "08h4c8EqOH2F8TsWXLIczV" \
  -n 22 --dry-run

# Live: move 22 tracks (sorted by artist, then album)
uv run python hacks/move_tracks.py \
  -s "Source Playlist Name" \
  -d "Destination Playlist ID" \
  -n 22

Future Migration

When ready to integrate into the CLI:

  1. Move move_tracks() function to spotfm/spotify/misc.py
  2. Add "move-tracks" command to spotfm/cli.py spotify command choices
  3. Add CLI flags: --source-playlist, --dest-playlist, --count, --dry-run
  4. Delete or repurpose hacks/move_tracks.py

The function signature is already CLI-compatible.

jmlrt and others added 3 commits May 20, 2026 09:52
- Implement hacks/move_tracks.py with URL/ID/name resolution
- Sort tracks by artist name then album name (case-insensitive)
- Support dry-run mode to preview changes without modifying Spotify
- Pre-flight and post-operation playlist updates ensure DB stays in sync
- Add 18 comprehensive unit tests (100% coverage)
- Code follows ruff style and codebase conventions

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- When using --dry-run without -v/--verbose, output is minimal (just track list)
- Verbose mode shows detailed logging of each operation
- Better UX for quick previews vs. debugging
- Non-verbose mode now suppresses all INFO/DEBUG logging
- Only warnings and errors are shown (cleaner output)
- Verbose mode (-v) still shows full DEBUG logging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant