Commit Graph

553 Commits

Author SHA1 Message Date
c44e48a425 add debug logging to track provider identification 2026-02-07 11:21:03 -05:00
e44b46aee1 remove lyrics column from playlist table 2026-02-07 11:17:48 -05:00
a75df9328a fix: use playlist cache in view tracks endpoint 2026-02-07 11:14:36 -05:00
35c125d042 fix: skip expensive track stats query for non-Spotify playlists to prevent timeouts
Some checks failed
CI / build-and-test (push) Has been cancelled
2026-02-07 03:48:00 -05:00
b12c971968 comment 2026-02-07 03:47:15 -05:00
8f051ad413 chore: remove noisy admin controller init log 2026-02-07 03:39:07 -05:00
6c1a578b35 fix: include manual external mappings in fallback playlist stats and add live UI refresh 2026-02-07 03:36:26 -05:00
8ab2923493 fix: increase delays in refresh & match all to ensure cache clears before matching 2026-02-07 03:23:13 -05:00
42b4e0e399 feat: add tooltips, refresh & match button, and matching warning banner 2026-02-07 02:36:48 -05:00
f03aa0be35 refactor: remove lyrics prefetching UI and optimize admin endpoints 2026-02-07 01:16:03 -05:00
440ef9850f Make kept path configurable via web UI
- Added Library:KeptPath to appsettings.json (default: /app/kept)
- Added Library Settings card to web UI with DownloadPath and KeptPath
- Updated GetDownloads and DeleteDownload endpoints to use configured path
- Updated JellyfinController to use configured kept path
- Injected IConfiguration into JellyfinController
- Users can now customize where favorited tracks are stored
2026-02-07 00:35:12 -05:00
c9b44dea43 Fix delete endpoint to work with kept folder and clean up empty directories
- Changed delete endpoint from Library:DownloadPath to /app/kept
- Now properly deletes empty Album and Artist folders after file deletion
- Added debug logging for deletion operations
- Structure: Artist/Album/Track.flac
2026-02-07 00:32:22 -05:00
3a9d00dcdb Fix downloads endpoint to only show kept files with debug logging
- Downloads endpoint now ONLY shows /app/kept (favorited tracks)
- Removed cache downloads from this endpoint (separate box needed)
- Added debug logging to troubleshoot why kept files weren't showing
- Logs directory existence and file count
2026-02-06 23:55:07 -05:00
2389b80733 Fix downloads endpoint to show kept files and remove lyrics cache endpoint
- Downloads endpoint now shows both /app/downloads (cache) and /app/kept (favorited)
- Added location field to distinguish between cache and kept files
- Added cacheCount and keptCount to response
- Removed lyrics cache clear endpoint (no longer needed)
2026-02-06 23:53:36 -05:00
b99a199ef3 Fix lyrics fetching and disable prefetching
- Fix LyricsPrefetchService to use server API key for Jellyfin lyrics checks
- Remove Spotify lyrics caching (local Docker container is fast)
- Disable lyrics prefetching service (not needed - Jellyfin/Spotify are fast)
- Add POST /api/admin/cache/clear-lyrics endpoint to clear LRCLIB cache
- Only LRCLIB lyrics are cached now (external API)
2026-02-06 23:48:18 -05:00
64e2004bdc Fix syntax error in AdminController.cs - move closing brace to correct location 2026-02-06 23:26:30 -05:00
7cee0911b6 fix: progress bar external detection and download row removal
Some checks failed
CI / build-and-test (push) Has been cancelled
- Handle JsonElement when deserializing ProviderIds from cache
- Check for external provider keys (SquidWTF, Deezer, Qobuz, Tidal)
- Fix row removal selector to properly escape path
- Progress bar now correctly shows local vs external split
2026-02-06 22:33:08 -05:00
a2b1eace5f feat: add kept downloads section to admin UI
- List all downloaded files with artist/album/file info
- Download button to save files locally
- Delete button with live row removal
- Shows total file count and size
- Auto-refreshes every 30 seconds
- Security: path validation to prevent directory traversal
2026-02-06 22:29:28 -05:00
ac1fbd4b34 fix: progress bar and add missing tracks section
- Fix external track detection in progress bar (check for external provider names in ProviderIds)
- Add missing tracks section at bottom of Active Playlists tab
- Shows all unmatched tracks across all playlists
- Includes Map to Local and Map to External buttons for each missing track
- Auto-refreshes with other playlist data
2026-02-06 22:12:15 -05:00
a6ac0dfbd2 feat: aggressive track matching with optimal order
- Strip decorators FIRST (feat, remaster, explicit, etc)
- Substring matching SECOND (cheap, high-precision)
- Levenshtein distance THIRD (expensive, fuzzy)
- Greedy assignment LAST (optimal global matching)
- Lower threshold to 40 (was 50-60) for max coverage
- Accept artist priority matches (artist 70+, title 30+)
- Handles cases like 'luther' → 'luther (feat. sza)'
- Handles cases like 'a' → 'a-blah' with same artist
- Prevents duplicate assignments across tracks
2026-02-06 21:22:42 -05:00
bb3140a247 feat: add Spotify ID to local tracks for lyrics support
- Inject Spotify ID into ProviderIds for manually mapped local tracks
- Also add Spotify ID to fuzzy-matched local tracks
- Enables Spotify Lyrics API to work for local Jellyfin tracks
- Fallback to Spotify lyrics when local track has no embedded lyrics
2026-02-06 20:32:32 -05:00
791e6a69d9 feat: re-add manual local Jellyfin track mapping support
- Allow mapping Spotify tracks to local Jellyfin tracks via JellyfinId
- Supports both local (Jellyfin) and external (provider) manual mappings
- Local mappings take priority over fuzzy matching
- Helps when automatic matching fails for tracks already in Jellyfin library
2026-02-06 20:29:29 -05:00
3ffa09dcfa fix: improve fuzzy matching for tracks with special formatting
- Lower matching threshold from 60 to 50 for more lenient matching
- Add fallback to trust provider's top result when artist matches well (>=70)
- Helps match tracks with parentheses, brackets, and stylized titles like 'PiLlOwT4lK'
- Provider search already does fuzzy matching, so trust it when artist is correct
2026-02-06 20:16:36 -05:00
b366a4b771 fix: add rate limiting for Odesli/song.link API
- Implemented semaphore-based rate limiter (10 requests per minute)
- Odesli API allows 10 requests per 60 seconds
- Rate limiter ensures 1 request per 6 seconds maximum
- Prevents API rate limit violations
- Cache still used first (30 day TTL) to minimize API calls
2026-02-06 19:55:16 -05:00
960d15175e fix: remove artist deduplication and add placeholder image support
- Removed ALL artist deduplication from search results
- Show both local and external artists with same name (e.g., Taylor Swift + Taylor Swift [S])
- Users can now browse external artist albums not in local library
- Added placeholder image support for missing cover art
- Placeholder served for both Jellyfin and external providers when image is null
- Added logging to SquidWTF artist search to show actual URLs
- Removed temporary documentation files from repo
- TIDAL image URLs already correctly implemented with UUID splitting

Changes:
- SearchItems: No deduplication, sort by relevance score
- SearchHints: No deduplication, show all matches
- GetArtists: No deduplication, show all matches
- GetImage: Returns placeholder.png when image unavailable
- Added GetPlaceholderImageAsync() helper method
2026-02-06 19:49:26 -05:00
1d774111e7 fix: show both local and external artists with same name
- Artists with same name now appear separately (local + external [S])
- Fixed deduplication to keep one local AND one external per name
- Added logging to SquidWTF artist search to show actual URLs
- External artists get [S] suffix to distinguish from local
- Allows users to browse external artist albums not in local library
- TIDAL image URLs already correctly implemented with UUID splitting
2026-02-06 19:41:06 -05:00
99d701a355 docs: add session management fix documentation and update TODO 2026-02-06 16:37:26 -05:00
73509eb80b feat: create sessions and WebSocket connections for external track playback
- External tracks now create Jellyfin sessions on playback start
- Sessions maintained via WebSocket connections to Jellyfin
- Session activity updated during progress reports
- Sessions auto-cleanup after 50s grace period when playback stops
- Clients playing external tracks now appear in Jellyfin dashboard
- Added comprehensive testing documentation
2026-02-06 16:36:23 -05:00
eb8e3196da feat: Odesli/song.link conversion for Spotify lyrics on external tracks 2026-02-06 16:30:13 -05:00
401d0b4008 feat: add Clear Cache & Rebuild button for playlists in Admin UI
- New endpoint: POST /api/admin/playlists/{name}/clear-cache
- Clears Redis cache keys (items, matched tracks, missing tracks)
- Deletes file caches
- Triggers automatic rebuild with latest code (includes Spotify IDs)
- Added prominent button in Admin UI playlist table
- Shows confirmation dialog with details of what will be cleared
2026-02-06 14:57:07 -05:00
6ccc6a4a0d debug: add logging to verify Spotify IDs in cached playlist items
Some checks failed
CI / build-and-test (push) Has been cancelled
2026-02-06 14:15:49 -05:00
c54503f486 fix: Spotify lyrics validation and proactive prefetching
- Only attempt Spotify lyrics for tracks with valid Spotify IDs (22 chars, no 'local' or ':')
- Add Spotify IDs to external matched tracks in playlists for lyrics support
- Proactively fetch and cache lyrics when playback starts (background task)
- Fix pre-existing SubSonicController bug (missing _cache field)
- Lyrics now ready instantly when requested by client
2026-02-06 13:04:40 -05:00
fbac81df64 feat: add 1-hour cache for playlist cover images 2026-02-06 12:31:56 -05:00
3a433e276c refactor: reorganize apis folder into steering and api-calls 2026-02-06 12:20:54 -05:00
0c14f4a760 chore: explicitly ignore documentation files in apis folder 2026-02-06 12:16:39 -05:00
28c4f8f5df Remove local Jellyfin manual mapping, keep only external mappings 2026-02-06 12:05:26 -05:00
a3830c54c4 Use Jellyfin item IDs for lyrics check instead of searching
- Lyrics prefetch now uses playlist items cache which has Jellyfin item IDs
- Directly queries /Audio/{itemId}/Lyrics endpoint (no search needed)
- Eliminates all 401 errors and 'no client headers' warnings
- Priority order: 1) Local Jellyfin lyrics, 2) Spotify lyrics API, 3) LRCLib
- Much more efficient - no fuzzy searching required
- Only searches by artist/title as fallback if item ID not available
- All 225 tests passing
2026-02-06 11:53:35 -05:00
4226ead53a Add file-based caching for admin UI and fix Jellyfin API usage
- Added 5-minute file cache for playlist summary to speed up admin UI loads
- Added refresh parameter to force cache bypass
- Invalidate cache when playlists are refreshed or tracks are matched
- Fixed incorrect use of anyProviderIdEquals (Emby API) in Jellyfin
- Now searches Jellyfin by artist and title instead of provider ID
- Fixes 401 errors and 'no client headers' warnings in lyrics prefetch
- All 225 tests passing
2026-02-06 11:48:01 -05:00
2155c4a9d5 Fix delete button for manual track mappings
- Use data attributes instead of inline onclick to avoid quote escaping issues
- Add event listeners after rendering the table
- Fixes issue where Remove button didn't work due to escaped quotes in onclick attribute
2026-02-06 11:42:01 -05:00
a56b2c3ea3 Add delete button for manual track mappings
- Added DELETE /api/admin/mappings/tracks endpoint
- Removes mapping from JSON file and Redis cache
- Deletes file if it becomes empty after removal
- Added 'Remove' button to each mapping in web UI
- Enhanced confirm dialog explaining consequences for both local and external mappings
- Supports removing both Jellyfin (local) and external provider mappings
- Allows phasing out local mappings in favor of Spotify Import plugin
2026-02-06 11:36:51 -05:00
810247ba8c Add manual track mappings display to web UI
- Shows all manual mappings in Active Playlists tab
- Displays summary counts (total, jellyfin, external)
- Table shows playlist, Spotify ID, type, target, and creation date
- Color-coded badges for jellyfin vs external mappings
- Auto-refreshes every 30 seconds
- Helps review mappings before phasing out local ones
2026-02-06 11:18:48 -05:00
96814aa91b Add endpoint to view all manual track mappings
- GET /api/admin/mappings/tracks returns all manual mappings
- Shows both Jellyfin (local) and external provider mappings
- Groups by playlist and includes creation timestamps
- Returns counts for jellyfin vs external mappings
2026-02-06 11:16:09 -05:00
d52c0fc938 Add Spotify ID lookup for external tracks to enable Spotify lyrics
- External tracks from playlists now look up their Spotify ID from matched tracks cache
- Enables Spotify lyrics API to work for SquidWTF/Deezer/Qobuz tracks
- Searches through all playlist matched tracks to find the Spotify ID
- Falls back to LRCLIB if no Spotify ID found or lyrics unavailable
2026-02-06 11:14:55 -05:00
64eff088fa Remove incorrect healthcheck from spotify-lyrics service 2026-02-06 11:02:00 -05:00
ff6dfede87 Change Spotify lyrics API external port to 8365 2026-02-06 10:54:43 -05:00
d8696e254f Expose Spotify lyrics API on port 8080 for testing 2026-02-06 10:52:44 -05:00
261f20f378 Add Spotify lyrics test endpoint
- Add GET /api/admin/lyrics/spotify/test endpoint
- Accepts trackId query parameter (Spotify track ID)
- Returns lyrics in both JSON and LRC format
- Useful for testing Spotify lyrics API integration
2026-02-06 10:51:16 -05:00
ad5fea7d8e Fix LRCLib and SquidWTF error handling
Some checks failed
CI / build-and-test (push) Has been cancelled
- Handle nullable duration in LRCLib API responses
- Validate input parameters before making LRCLib requests
- Change SquidWTF artist warning to debug level (expected behavior)
- Prevent JSON deserialization errors when duration is null
- Prevent 400 Bad Request errors from empty track names
2026-02-06 02:07:45 -05:00
8a3abdcbf7 Fix LyricsStartupValidator build errors
- Remove duplicate _httpClient field (use inherited one)
- Replace ValidationResult.Warning with ValidationResult.Failure
- Use PARTIAL status for partial failures
2026-02-06 01:54:32 -05:00
f103dac6c8 Add comprehensive lyrics startup validation with '22' test
- Revert album endpoint back to ?id= (correct parameter)
- Update SquidWTF validator to test '22' by Taylor Swift
- Create LyricsStartupValidator testing all lyrics services:
  * LRCLib API
  * Spotify Lyrics Sidecar (docker container)
  * Spotify API configuration
- Test song: '22' by Taylor Swift (Spotify ID: 3yII7UwgLF6K5zW3xad3MP)
- Register lyrics validator in startup orchestrator
2026-02-06 01:48:12 -05:00