Add lyrics completion bar per playlist showing percentage of tracks with cached lyrics
Some checks failed
CI / build-and-test (push) Has been cancelled

This commit is contained in:
2026-02-05 12:44:11 -05:00
parent 9abb53de1a
commit 328a6a0eea
2 changed files with 60 additions and 1 deletions

View File

@@ -486,6 +486,54 @@ public class AdminController : ControllerBase
_logger.LogWarning("Playlist {Name} has no JellyfinId configured", config.Name); _logger.LogWarning("Playlist {Name} has no JellyfinId configured", config.Name);
} }
// Get lyrics completion status
try
{
var tracks = await _playlistFetcher.GetPlaylistTracksAsync(config.Name);
if (tracks.Count > 0)
{
var lyricsWithCount = 0;
var lyricsWithoutCount = 0;
foreach (var track in tracks)
{
var cacheKey = $"lyrics:{track.PrimaryArtist}:{track.Title}:{track.Album}:{track.DurationMs / 1000}";
var existingLyrics = await _cache.GetStringAsync(cacheKey);
if (!string.IsNullOrEmpty(existingLyrics))
{
lyricsWithCount++;
}
else
{
lyricsWithoutCount++;
}
}
playlistInfo["lyricsTotal"] = tracks.Count;
playlistInfo["lyricsCached"] = lyricsWithCount;
playlistInfo["lyricsMissing"] = lyricsWithoutCount;
playlistInfo["lyricsPercentage"] = tracks.Count > 0
? (int)Math.Round((double)lyricsWithCount / tracks.Count * 100)
: 0;
}
else
{
playlistInfo["lyricsTotal"] = 0;
playlistInfo["lyricsCached"] = 0;
playlistInfo["lyricsMissing"] = 0;
playlistInfo["lyricsPercentage"] = 0;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to get lyrics completion for playlist {Name}", config.Name);
playlistInfo["lyricsTotal"] = 0;
playlistInfo["lyricsCached"] = 0;
playlistInfo["lyricsMissing"] = 0;
playlistInfo["lyricsPercentage"] = 0;
}
playlists.Add(playlistInfo); playlists.Add(playlistInfo);
} }

View File

@@ -662,13 +662,14 @@
<th>Spotify ID</th> <th>Spotify ID</th>
<th>Tracks</th> <th>Tracks</th>
<th>Completion</th> <th>Completion</th>
<th>Lyrics</th>
<th>Cache Age</th> <th>Cache Age</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
</thead> </thead>
<tbody id="playlist-table-body"> <tbody id="playlist-table-body">
<tr> <tr>
<td colspan="6" class="loading"> <td colspan="7" class="loading">
<span class="spinner"></span> Loading playlists... <span class="spinner"></span> Loading playlists...
</td> </td>
</tr> </tr>
@@ -1271,6 +1272,16 @@
<span style="font-size:0.85rem;color:${completionColor};font-weight:500;min-width:40px;">${completionPct}%</span> <span style="font-size:0.85rem;color:${completionColor};font-weight:500;min-width:40px;">${completionPct}%</span>
</div> </div>
</td> </td>
<td>
${p.lyricsTotal > 0 ? `
<div style="display:flex;align-items:center;gap:8px;">
<div style="flex:1;background:var(--bg-tertiary);height:12px;border-radius:6px;overflow:hidden;">
<div style="width:${p.lyricsPercentage}%;height:100%;background:${p.lyricsPercentage === 100 ? '#10b981' : '#3b82f6'};transition:width 0.3s;" title="${p.lyricsCached} lyrics cached"></div>
</div>
<span style="font-size:0.85rem;color:var(--text-secondary);font-weight:500;min-width:40px;">${p.lyricsPercentage}%</span>
</div>
` : '<span style="color:var(--text-secondary);font-size:0.85rem;">-</span>'}
</td>
<td class="cache-age">${p.cacheAge || '-'}</td> <td class="cache-age">${p.cacheAge || '-'}</td>
<td> <td>
<button onclick="matchPlaylistTracks('${escapeJs(p.name)}')">Match Tracks</button> <button onclick="matchPlaylistTracks('${escapeJs(p.name)}')">Match Tracks</button>