mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-10 07:58:39 -05:00
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
This commit is contained in:
@@ -211,8 +211,40 @@ public class AdminController : ControllerBase
|
||||
/// Get list of configured playlists with their current data
|
||||
/// </summary>
|
||||
[HttpGet("playlists")]
|
||||
public async Task<IActionResult> GetPlaylists()
|
||||
public async Task<IActionResult> GetPlaylists([FromQuery] bool refresh = false)
|
||||
{
|
||||
var playlistCacheFile = "/app/cache/admin_playlists_summary.json";
|
||||
|
||||
// Check file cache first (5 minute TTL) unless refresh is requested
|
||||
if (!refresh && System.IO.File.Exists(playlistCacheFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileInfo = new FileInfo(playlistCacheFile);
|
||||
var age = DateTime.UtcNow - fileInfo.LastWriteTimeUtc;
|
||||
|
||||
if (age.TotalMinutes < 5)
|
||||
{
|
||||
var cachedJson = await System.IO.File.ReadAllTextAsync(playlistCacheFile);
|
||||
var cachedData = JsonSerializer.Deserialize<Dictionary<string, object>>(cachedJson);
|
||||
_logger.LogDebug("📦 Returning cached playlist summary (age: {Age:F1}m)", age.TotalMinutes);
|
||||
return Ok(cachedData);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug("🔄 Cache expired (age: {Age:F1}m), refreshing...", age.TotalMinutes);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to read cached playlist summary");
|
||||
}
|
||||
}
|
||||
else if (refresh)
|
||||
{
|
||||
_logger.LogInformation("🔄 Force refresh requested for playlist summary");
|
||||
}
|
||||
|
||||
var playlists = new List<object>();
|
||||
|
||||
// Read playlists directly from .env file to get the latest configuration
|
||||
@@ -541,6 +573,24 @@ public class AdminController : ControllerBase
|
||||
playlists.Add(playlistInfo);
|
||||
}
|
||||
|
||||
// Save to file cache
|
||||
try
|
||||
{
|
||||
var cacheDir = "/app/cache";
|
||||
Directory.CreateDirectory(cacheDir);
|
||||
var cacheFile = Path.Combine(cacheDir, "admin_playlists_summary.json");
|
||||
|
||||
var response = new { playlists };
|
||||
var json = JsonSerializer.Serialize(response, new JsonSerializerOptions { WriteIndented = false });
|
||||
await System.IO.File.WriteAllTextAsync(cacheFile, json);
|
||||
|
||||
_logger.LogDebug("💾 Saved playlist summary to cache");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to save playlist summary cache");
|
||||
}
|
||||
|
||||
return Ok(new { playlists });
|
||||
}
|
||||
|
||||
@@ -872,6 +922,10 @@ public class AdminController : ControllerBase
|
||||
{
|
||||
_logger.LogInformation("Manual playlist refresh triggered from admin UI");
|
||||
await _playlistFetcher.TriggerFetchAsync();
|
||||
|
||||
// Invalidate playlist summary cache
|
||||
InvalidatePlaylistSummaryCache();
|
||||
|
||||
return Ok(new { message = "Playlist refresh triggered", timestamp = DateTime.UtcNow });
|
||||
}
|
||||
|
||||
@@ -892,6 +946,10 @@ public class AdminController : ControllerBase
|
||||
try
|
||||
{
|
||||
await _matchingService.TriggerMatchingForPlaylistAsync(decodedName);
|
||||
|
||||
// Invalidate playlist summary cache
|
||||
InvalidatePlaylistSummaryCache();
|
||||
|
||||
return Ok(new { message = $"Track matching triggered for {decodedName}", timestamp = DateTime.UtcNow });
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -3126,6 +3184,30 @@ public class AdminController : ControllerBase
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper Methods
|
||||
|
||||
/// <summary>
|
||||
/// Invalidates the cached playlist summary so it will be regenerated on next request
|
||||
/// </summary>
|
||||
private void InvalidatePlaylistSummaryCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cacheFile = "/app/cache/admin_playlists_summary.json";
|
||||
if (System.IO.File.Exists(cacheFile))
|
||||
{
|
||||
System.IO.File.Delete(cacheFile);
|
||||
_logger.LogDebug("🗑️ Invalidated playlist summary cache");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to invalidate playlist summary cache");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class ManualMappingRequest
|
||||
|
||||
Reference in New Issue
Block a user