mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-10 07:58:39 -05:00
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
This commit is contained in:
@@ -935,6 +935,77 @@ public class AdminController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear cache and rebuild for a specific playlist
|
||||
/// </summary>
|
||||
[HttpPost("playlists/{name}/clear-cache")]
|
||||
public async Task<IActionResult> ClearPlaylistCache(string name)
|
||||
{
|
||||
var decodedName = Uri.UnescapeDataString(name);
|
||||
_logger.LogInformation("Clear cache & rebuild triggered for playlist: {Name}", decodedName);
|
||||
|
||||
if (_matchingService == null)
|
||||
{
|
||||
return BadRequest(new { error = "Track matching service is not available" });
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Clear all cache keys for this playlist
|
||||
var cacheKeys = new[]
|
||||
{
|
||||
$"spotify:playlist:items:{decodedName}", // Pre-built items cache
|
||||
$"spotify:matched:ordered:{decodedName}", // Ordered matched tracks
|
||||
$"spotify:matched:{decodedName}", // Legacy matched tracks
|
||||
$"spotify:missing:{decodedName}" // Missing tracks
|
||||
};
|
||||
|
||||
foreach (var key in cacheKeys)
|
||||
{
|
||||
await _cache.DeleteAsync(key);
|
||||
_logger.LogDebug("Cleared cache key: {Key}", key);
|
||||
}
|
||||
|
||||
// Delete file caches
|
||||
var safeName = string.Join("_", decodedName.Split(Path.GetInvalidFileNameChars()));
|
||||
var filesToDelete = new[]
|
||||
{
|
||||
Path.Combine(CacheDirectory, $"{safeName}_items.json"),
|
||||
Path.Combine(CacheDirectory, $"{safeName}_matched.json")
|
||||
};
|
||||
|
||||
foreach (var file in filesToDelete)
|
||||
{
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
System.IO.File.Delete(file);
|
||||
_logger.LogDebug("Deleted cache file: {File}", file);
|
||||
}
|
||||
}
|
||||
|
||||
_logger.LogInformation("✓ Cleared all caches for playlist: {Name}", decodedName);
|
||||
|
||||
// Trigger rebuild
|
||||
await _matchingService.TriggerMatchingForPlaylistAsync(decodedName);
|
||||
|
||||
// Invalidate playlist summary cache
|
||||
InvalidatePlaylistSummaryCache();
|
||||
|
||||
return Ok(new
|
||||
{
|
||||
message = $"Cache cleared and rebuild triggered for {decodedName}",
|
||||
timestamp = DateTime.UtcNow,
|
||||
clearedKeys = cacheKeys.Length,
|
||||
clearedFiles = filesToDelete.Count(System.IO.File.Exists)
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clear cache for {Name}", decodedName);
|
||||
return StatusCode(500, new { error = "Failed to clear cache", details = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Search Jellyfin library for tracks (for manual mapping)
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user