diff --git a/ErsatzTV.Application/Artworks/Queries/GetArtwork.cs b/ErsatzTV.Application/Artworks/Queries/GetArtwork.cs new file mode 100644 index 00000000..b59abd67 --- /dev/null +++ b/ErsatzTV.Application/Artworks/Queries/GetArtwork.cs @@ -0,0 +1,6 @@ +using ErsatzTV.Core; +using ErsatzTV.Core.Domain; + +namespace ErsatzTV.Application.Artworks; + +public record GetArtwork(int Id) : IRequest>; diff --git a/ErsatzTV.Application/Artworks/Queries/GetArtworkHandler.cs b/ErsatzTV.Application/Artworks/Queries/GetArtworkHandler.cs new file mode 100644 index 00000000..3bffd503 --- /dev/null +++ b/ErsatzTV.Application/Artworks/Queries/GetArtworkHandler.cs @@ -0,0 +1,42 @@ +using ErsatzTV.Core; +using ErsatzTV.Core.Domain; +using ErsatzTV.Infrastructure.Data; +using ErsatzTV.Infrastructure.Extensions; +using Microsoft.EntityFrameworkCore; + +namespace ErsatzTV.Application.Artworks; + +public class GetArtworkHandler(IDbContextFactory dbContextFactory) : IRequestHandler> +{ + private readonly IDbContextFactory _dbContextFactory = dbContextFactory; + + public async Task> Handle( + GetArtwork request, + CancellationToken cancellationToken) + { + try { + await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); + + Option artwork = await dbContext.Artwork + .AsNoTracking() + .SelectOneAsync(a => a.Id, a => a.Id == request.Id) + .MapT(Project); + + return artwork.ToEither(BaseError.New("Artwork not found")); + + } + catch (Exception ex) + { + return BaseError.New(ex.ToString()); + } + } + + private static Artwork Project(Artwork artwork) + { + return new Artwork { + Id = artwork.Id, + Path = artwork.Path, + ArtworkKind = artwork.ArtworkKind + }; + } +} diff --git a/ErsatzTV/Controllers/ArtworkController.cs b/ErsatzTV/Controllers/ArtworkController.cs index 8b82ec55..d22d6d6a 100644 --- a/ErsatzTV/Controllers/ArtworkController.cs +++ b/ErsatzTV/Controllers/ArtworkController.cs @@ -1,4 +1,5 @@ -using ErsatzTV.Application.Emby; +using ErsatzTV.Application.Artworks; +using ErsatzTV.Application.Emby; using ErsatzTV.Application.Images; using ErsatzTV.Application.Jellyfin; using ErsatzTV.Application.Plex; @@ -26,6 +27,27 @@ public class ArtworkController : ControllerBase _httpClientFactory = httpClientFactory; } + [HttpHead("/artwork/{id}")] + [HttpGet("/artwork/{id}")] + // This route redirect to the proper artwork from its Id + public async Task RedirectArtwork(int id, CancellationToken cancellationToken) { + Either artwork = + await _mediator.Send(new GetArtwork(id), cancellationToken); + + return artwork.Match( + Left: _ => new NotFoundResult(), + Right: r => r.ArtworkKind switch + { + ArtworkKind.Poster => new RedirectResult("/artwork/posters/" + r.Path), + ArtworkKind.Thumbnail => new RedirectResult("/artwork/thumbnails/" + r.Path), + ArtworkKind.Logo => new RedirectResult("/iptv/logos/" + r.Path), + ArtworkKind.FanArt => new RedirectResult("/artwork/fanart/" + r.Path), + ArtworkKind.Watermark => new RedirectResult("/artwork/watermarks/" + r.Path), + _ => new NotFoundResult() + } + ); + } + [HttpHead("/iptv/artwork/posters/{fileName}")] [HttpGet("/iptv/artwork/posters/{fileName}")] [HttpHead("/iptv/artwork/posters/{fileName}.jpg")]