diff --git a/Jellyfin.Plugin.Jellypod/Channels/JellypodChannel.cs b/Jellyfin.Plugin.Jellypod/Channels/JellypodChannel.cs
index eff9018..5ab64b2 100644
--- a/Jellyfin.Plugin.Jellypod/Channels/JellypodChannel.cs
+++ b/Jellyfin.Plugin.Jellypod/Channels/JellypodChannel.cs
@@ -387,10 +387,9 @@ public class JellypodChannel : IChannel, IHasCacheKey, IRequiresMediaInfoCallbac
///
public string? GetCacheKey(string? userId)
{
- // Use 5-minute time buckets for cache key
- var now = DateTime.Now;
- var timeBucket = new DateTime(now.Year, now.Month, now.Day, now.Hour, (now.Minute / 5) * 5, 0);
- return timeBucket.ToString("yyyy-MM-dd-HH-mm", CultureInfo.InvariantCulture);
+ // Include database modification time so cache invalidates when podcasts/episodes change
+ var lastModified = _storageService.LastModified;
+ return lastModified.ToString("O", CultureInfo.InvariantCulture);
}
///
diff --git a/Jellyfin.Plugin.Jellypod/Services/IPodcastStorageService.cs b/Jellyfin.Plugin.Jellypod/Services/IPodcastStorageService.cs
index cb01e09..ac3af64 100644
--- a/Jellyfin.Plugin.Jellypod/Services/IPodcastStorageService.cs
+++ b/Jellyfin.Plugin.Jellypod/Services/IPodcastStorageService.cs
@@ -10,6 +10,12 @@ namespace Jellyfin.Plugin.Jellypod.Services;
///
public interface IPodcastStorageService
{
+ ///
+ /// Gets the cached last modification time (synchronous, for cache key generation).
+ /// Returns default if database hasn't been loaded yet.
+ ///
+ DateTime LastModified { get; }
+
///
/// Gets all subscribed podcasts.
///
@@ -57,4 +63,10 @@ public interface IPodcastStorageService
///
/// The base path for podcast storage.
string GetStoragePath();
+
+ ///
+ /// Gets the last time the database was modified.
+ ///
+ /// The last modification time, or null if unknown.
+ Task GetLastModifiedAsync();
}
diff --git a/Jellyfin.Plugin.Jellypod/Services/PodcastStorageService.cs b/Jellyfin.Plugin.Jellypod/Services/PodcastStorageService.cs
index 249f2c4..129db9d 100644
--- a/Jellyfin.Plugin.Jellypod/Services/PodcastStorageService.cs
+++ b/Jellyfin.Plugin.Jellypod/Services/PodcastStorageService.cs
@@ -28,6 +28,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
private readonly IApplicationPaths _applicationPaths;
private readonly SemaphoreSlim _dbLock = new(1, 1);
private PodcastDatabase? _cache;
+ private DateTime _lastModified;
///
/// Initializes a new instance of the class.
@@ -47,6 +48,9 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
"Jellypod",
"podcasts.json");
+ ///
+ public DateTime LastModified => _lastModified;
+
///
public async Task> GetAllPodcastsAsync()
{
@@ -180,6 +184,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
{
_logger.LogWarning("Database file does not exist at {Path}", DatabasePath);
_cache = new PodcastDatabase();
+ _lastModified = DateTime.UtcNow;
return _cache;
}
@@ -189,6 +194,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
var json = await File.ReadAllTextAsync(DatabasePath).ConfigureAwait(false);
_logger.LogInformation("Read {Length} characters from database file", json.Length);
_cache = JsonSerializer.Deserialize(json, JsonOptions) ?? new PodcastDatabase();
+ _lastModified = _cache.LastSaved;
_logger.LogInformation("Loaded {Count} podcasts from database", _cache.Podcasts.Count);
return _cache;
}
@@ -196,6 +202,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
{
_logger.LogError(ex, "Failed to load podcast database, starting fresh");
_cache = new PodcastDatabase();
+ _lastModified = DateTime.UtcNow;
return _cache;
}
}
@@ -211,6 +218,7 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
}
db.LastSaved = DateTime.UtcNow;
+ _lastModified = db.LastSaved;
var json = JsonSerializer.Serialize(db, JsonOptions);
await File.WriteAllTextAsync(DatabasePath, json).ConfigureAwait(false);
_cache = db;
@@ -261,6 +269,13 @@ public sealed class PodcastStorageService : IPodcastStorageService, IDisposable
return ".mp3";
}
+ ///
+ public async Task GetLastModifiedAsync()
+ {
+ var db = await LoadDatabaseAsync().ConfigureAwait(false);
+ return db.LastSaved;
+ }
+
///
public void Dispose()
{