diff --git a/DysonNetwork.Sphere/Sticker/StickerController.cs b/DysonNetwork.Sphere/Sticker/StickerController.cs index f9d58b5..cfe2a34 100644 --- a/DysonNetwork.Sphere/Sticker/StickerController.cs +++ b/DysonNetwork.Sphere/Sticker/StickerController.cs @@ -165,17 +165,20 @@ public class StickerController(AppDatabase db, StickerService st) : ControllerBa [HttpGet("lookup/{identifier}")] public async Task> GetStickerByIdentifier(string identifier) { - IQueryable query = db.Stickers - .Include(e => e.Pack) - .Include(e => e.Image); - query = Guid.TryParse(identifier, out var guid) - ? query.Where(e => e.Id == guid) - : query.Where(e => e.Pack.Prefix + e.Slug == identifier); - var sticker = await query.FirstOrDefaultAsync(); - + var sticker = await st.LookupStickerByIdentifierAsync(identifier); + if (sticker is null) return NotFound(); return Ok(sticker); } + + [HttpGet("lookup/{identifier}/open")] + public async Task> OpenStickerByIdentifier(string identifier) + { + var sticker = await st.LookupStickerByIdentifierAsync(identifier); + + if (sticker is null) return NotFound(); + return Redirect($"/files/{sticker.ImageId}"); + } [HttpGet("{packId:guid}/content/{id:guid}")] public async Task> GetSticker(Guid packId, Guid id) diff --git a/DysonNetwork.Sphere/Sticker/StickerService.cs b/DysonNetwork.Sphere/Sticker/StickerService.cs index e1d4af5..dcf6167 100644 --- a/DysonNetwork.Sphere/Sticker/StickerService.cs +++ b/DysonNetwork.Sphere/Sticker/StickerService.cs @@ -1,10 +1,17 @@ using DysonNetwork.Sphere.Storage; using Microsoft.EntityFrameworkCore; -namespace DysonNetwork.Sphere.Sticker; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using System; +using System.Linq; +using System.Threading.Tasks; -public class StickerService(AppDatabase db, FileService fs) +namespace DysonNetwork.Sphere.Sticker; +public class StickerService(AppDatabase db, FileService fs, IMemoryCache cache) { + private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(15); + public async Task CreateStickerAsync(Sticker sticker) { db.Stickers.Add(sticker); @@ -14,7 +21,6 @@ public class StickerService(AppDatabase db, FileService fs) return sticker; } - public async Task UpdateStickerAsync(Sticker sticker, CloudFile? newImage) { if (newImage != null) @@ -26,17 +32,21 @@ public class StickerService(AppDatabase db, FileService fs) db.Stickers.Update(sticker); await db.SaveChangesAsync(); + + // Invalidate cache for this sticker + InvalidateStickerCache(sticker); return sticker; } - public async Task DeleteStickerAsync(Sticker sticker) { db.Stickers.Remove(sticker); await db.SaveChangesAsync(); await fs.MarkUsageAsync(sticker.Image, -1); + + // Invalidate cache for this sticker + InvalidateStickerCache(sticker); } - public async Task DeleteStickerPackAsync(StickerPack pack) { var stickers = await db.Stickers @@ -51,5 +61,47 @@ public class StickerService(AppDatabase db, FileService fs) await db.SaveChangesAsync(); await fs.MarkUsageRangeAsync(images, -1); + + // Invalidate cache for all stickers in this pack + foreach (var sticker in stickers) + { + InvalidateStickerCache(sticker); + } + } + + public async Task LookupStickerByIdentifierAsync(string identifier) + { + // Try to get from cache first + string cacheKey = $"StickerLookup_{identifier}"; + if (cache.TryGetValue(cacheKey, out Sticker? cachedSticker)) + { + return cachedSticker; + } + + // If not in cache, fetch from database + IQueryable query = db.Stickers + .Include(e => e.Pack) + .Include(e => e.Image); + + query = Guid.TryParse(identifier, out var guid) + ? query.Where(e => e.Id == guid) + : query.Where(e => e.Pack.Prefix + e.Slug == identifier); + + var sticker = await query.FirstOrDefaultAsync(); + + // Store in cache if found + if (sticker != null) + { + cache.Set(cacheKey, sticker, CacheDuration); + } + + return sticker; + } + + private void InvalidateStickerCache(Sticker sticker) + { + // Remove both possible cache entries + cache.Remove($"StickerLookup_{sticker.Id}"); + cache.Remove($"StickerLookup_{sticker.Pack.Prefix}{sticker.Slug}"); } } \ No newline at end of file