Commit 6d9e5f9ea5bb

Vincent Demeester <vincent@sbr.pm>
2025-12-01 21:55:40
feat: Improve dry-run mode for manual artist addition in Lidarr sync
- Enable complete artist list output instead of truncated view - Add --all-playlists flag to skip interactive selection - Provide copyable artist names for manual Lidarr addition 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5bf232c
Changed files (2)
tools/arr/commands/lidarr_sync_spotify.py
@@ -98,6 +98,7 @@ def run(
     request_delay: float,
     dry_run: bool,
     no_confirm: bool,
+    all_playlists: bool,
 ):
     """Execute the lidarr sync-spotify command."""
     # Create clients and context
@@ -130,22 +131,29 @@ def run(
             return
 
         print(f"Found {len(user_playlists)} public playlists\n")
-        print(
-            "Use fzf to select playlists (TAB to select, "
-            "ENTER to confirm, ESC to cancel)"
-        )
 
-        # Use fzf for selection
-        selected_ids = select_with_fzf(
-            user_playlists, "{name} (by {owner}, {tracks_total} tracks)"
-        )
+        if all_playlists:
+            # Select all playlists automatically
+            selected_ids = [p["id"] for p in user_playlists]
+            print(f"Selecting all {len(selected_ids)} playlists\n")
+        else:
+            # Interactive selection with fzf
+            print(
+                "Use fzf to select playlists (TAB to select, "
+                "ENTER to confirm, ESC to cancel)"
+            )
 
-        if not selected_ids:
-            print("\nNo playlists selected. Exiting.")
-            return
+            selected_ids = select_with_fzf(
+                user_playlists, "{name} (by {owner}, {tracks_total} tracks)"
+            )
+
+            if not selected_ids:
+                print("\nNo playlists selected. Exiting.")
+                return
+
+            print(f"\nSelected {len(selected_ids)} playlist(s)\n")
 
         playlist_ids = selected_ids
-        print(f"\nSelected {len(playlist_ids)} playlist(s)\n")
     elif not playlist_ids:
         print(
             "\nError: No playlist IDs provided and no Spotify username set."
@@ -235,10 +243,16 @@ def run(
 
     if artists_to_add:
         print(f"\n→ Artists to add: {len(artists_to_add)}")
-        for artist_name, _ in artists_to_add[:10]:
-            print(f"  - {artist_name}")
-        if len(artists_to_add) > 10:
-            print(f"  ... and {len(artists_to_add) - 10} more")
+        if dry_run:
+            # In dry-run mode, show all artists for manual addition
+            for artist_name, _ in artists_to_add:
+                print(f"  - {artist_name}")
+        else:
+            # In normal mode, show first 10 to avoid clutter
+            for artist_name, _ in artists_to_add[:10]:
+                print(f"  - {artist_name}")
+            if len(artists_to_add) > 10:
+                print(f"  ... and {len(artists_to_add) - 10} more")
     else:
         print("\nAll artists from the playlists are already in Lidarr!")
         return
@@ -260,6 +274,7 @@ def run(
 
     added_count = 0
     failed_count = 0
+    dry_run_artists = []  # Track artists for dry-run output
 
     for idx, (artist_name, artist_data) in enumerate(artists_to_add, 1):
         print(f"\n[{idx}/{len(artists_to_add)}] Searching for: {artist_name}")
@@ -307,6 +322,13 @@ def run(
                     failed_count += 1
             else:
                 print("  [DRY RUN] Would add this artist")
+                dry_run_artists.append(
+                    {
+                        "spotify_name": artist_name,
+                        "lidarr_name": artist_mb_name,
+                        "albums": artist_data["albums"],
+                    }
+                )
                 added_count += 1
 
             # Add a delay between requests to avoid overwhelming Lidarr
@@ -335,6 +357,22 @@ def run(
             "\n[DRY RUN] No changes were made. "
             "Remove --dry-run to add artists."
         )
+        if dry_run_artists:
+            print_section_header("ARTISTS TO ADD MANUALLY")
+            print(
+                "\nCopy the artist names below to search and add them "
+                "manually in Lidarr:\n"
+            )
+            for artist in dry_run_artists:
+                print(f"• {artist['lidarr_name']}")
+                if artist["spotify_name"] != artist["lidarr_name"]:
+                    print(f"  (Spotify: {artist['spotify_name']})")
+                if artist["albums"]:
+                    album_count = len(artist["albums"])
+                    print(f"  Albums in playlists: {album_count}")
+            print(
+                f"\n\nTotal: {len(dry_run_artists)} artists to add manually"
+            )
     elif added_count > 0:
         print(
             f"\nMonitoring mode: {monitor}\n"
tools/arr/arr
@@ -134,9 +134,10 @@ def lidarr_update_paths(url, api_key, music_folder, dry_run):
 @click.option("--root-folder", default="/music", help="Root folder for music in Lidarr")
 @click.option("--monitor", default="all", type=click.Choice(["all", "future", "missing", "existing", "none"]), help="Album monitoring mode")
 @click.option("--request-delay", default=1.5, type=float, help="Delay between Lidarr API requests (seconds)")
+@click.option("--all-playlists", is_flag=True, help="Select all playlists (skip fzf selection)")
 @click.option("--dry-run", is_flag=True, help="Show what would be added without making changes")
 @click.option("--no-confirm", "--yolo", is_flag=True, help="Skip interactive confirmation (use with caution)")
-def lidarr_sync_spotify(url, api_key, spotify_client_id, spotify_client_secret, spotify_username, playlist_ids, root_folder, monitor, request_delay, dry_run, no_confirm):
+def lidarr_sync_spotify(url, api_key, spotify_client_id, spotify_client_secret, spotify_username, playlist_ids, root_folder, monitor, request_delay, all_playlists, dry_run, no_confirm):
     """Sync Spotify playlists to Lidarr.
 
     Fetches tracks from Spotify playlists and adds missing artists to Lidarr.
@@ -164,11 +165,14 @@ def lidarr_sync_spotify(url, api_key, spotify_client_id, spotify_client_secret,
         export SPOTIFY_USERNAME=your-username
         arr lidarr sync-spotify http://localhost:8686
 
+        # Select all playlists automatically
+        arr lidarr sync-spotify http://localhost:8686 -u username --all-playlists
+
         # Sync specific playlists (no username needed)
         arr lidarr sync-spotify http://localhost:8686 \\
             37i9dQZF1DXcBWIGoYBM5M 37i9dQZF1DX0XUsuxWHRQd
 
-        # Dry run
+        # Dry run to see artist list for manual addition
         arr lidarr sync-spotify http://localhost:8686 -u username --dry-run
 
         # Monitor only future albums
@@ -187,7 +191,8 @@ def lidarr_sync_spotify(url, api_key, spotify_client_id, spotify_client_secret,
         monitor,
         request_delay,
         dry_run,
-        no_confirm
+        no_confirm,
+        all_playlists
     )