mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Rework thumbnail manager to use images id
This commit is contained in:
parent
e1c04bef51
commit
d46e6eda64
@ -23,56 +23,17 @@ using Kyoo.Abstractions.Models;
|
||||
|
||||
namespace Kyoo.Abstractions.Controllers;
|
||||
|
||||
/// <summary>
|
||||
/// Download images and retrieve the path of those images for a resource.
|
||||
/// </summary>
|
||||
public interface IThumbnailsManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Download images of a specified item.
|
||||
/// If no images is available to download, do nothing and silently return.
|
||||
/// </summary>
|
||||
/// <param name="item">
|
||||
/// The item to cache images.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of the item</typeparam>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task DownloadImages<T>(T item)
|
||||
where T : IThumbnails;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the local path of an image of the given item.
|
||||
/// </summary>
|
||||
/// <param name="item">The item to retrieve the poster from.</param>
|
||||
/// <param name="image">The ID of the image.</param>
|
||||
/// <param name="quality">The quality of the image</param>
|
||||
/// <typeparam name="T">The type of the item</typeparam>
|
||||
/// <returns>The path of the image for the given resource or null if it does not exists.</returns>
|
||||
string GetImagePath<T>(T item, string image, ImageQuality quality)
|
||||
where T : IThumbnails;
|
||||
string GetImagePath(Guid imageId, ImageQuality quality);
|
||||
|
||||
/// <summary>
|
||||
/// Delete images associated with the item.
|
||||
/// </summary>
|
||||
/// <param name="item">
|
||||
/// The item with cached images.
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of the item</typeparam>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
Task DeleteImages<T>(T item)
|
||||
where T : IThumbnails;
|
||||
|
||||
/// <summary>
|
||||
/// Set the user's profile picture
|
||||
/// </summary>
|
||||
/// <param name="userId">The id of the user. </param>
|
||||
/// <returns>The byte stream of the image. Null if no image exist.</returns>
|
||||
Task<Stream> GetUserImage(Guid userId);
|
||||
|
||||
/// <summary>
|
||||
/// Set the user's profile picture
|
||||
/// </summary>
|
||||
/// <param name="userId">The id of the user. </param>
|
||||
/// <param name="image">The byte stream of the image. Null to delete the image.</param>
|
||||
Task SetUserImage(Guid userId, Stream? image);
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
using Kyoo.Postgresql;
|
||||
|
@ -42,8 +42,6 @@ public class ThumbnailsManager(
|
||||
Lazy<IRepository<User>> users
|
||||
) : IThumbnailsManager
|
||||
{
|
||||
private static readonly Dictionary<string, TaskCompletionSource<object>> _downloading = [];
|
||||
|
||||
private static async Task _WriteTo(SKBitmap bitmap, string path, int quality)
|
||||
{
|
||||
SKData data = bitmap.Encode(SKEncodedImageFormat.Webp, quality);
|
||||
@ -52,12 +50,16 @@ public class ThumbnailsManager(
|
||||
await reader.CopyToAsync(file);
|
||||
}
|
||||
|
||||
private async Task _DownloadImage(Image? image, string localPath, string what)
|
||||
private async Task _DownloadImage(Image? image, string what)
|
||||
{
|
||||
if (image == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
if (image.Id == Guid.Empty)
|
||||
image.Id = new Guid();
|
||||
string localPath = $"/metadata/{image.Id}";
|
||||
|
||||
logger.LogInformation("Downloading image {What}", what);
|
||||
|
||||
HttpClient client = clientFactory.CreateClient();
|
||||
@ -119,86 +121,24 @@ public class ThumbnailsManager(
|
||||
{
|
||||
string name = item is IResource res ? res.Slug : "???";
|
||||
|
||||
string posterPath =
|
||||
$"{_GetBaseImagePath(item, "poster")}.{ImageQuality.High.ToString().ToLowerInvariant()}.webp";
|
||||
bool duplicated = false;
|
||||
TaskCompletionSource<object>? sync = null;
|
||||
try
|
||||
{
|
||||
lock (_downloading)
|
||||
{
|
||||
if (_downloading.ContainsKey(posterPath))
|
||||
{
|
||||
duplicated = true;
|
||||
sync = _downloading.GetValueOrDefault(posterPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
sync = new();
|
||||
_downloading.Add(posterPath, sync);
|
||||
}
|
||||
}
|
||||
if (duplicated)
|
||||
{
|
||||
object? dup = sync != null ? await sync.Task : null;
|
||||
if (dup != null)
|
||||
throw new DuplicatedItemException(dup);
|
||||
}
|
||||
|
||||
await _DownloadImage(
|
||||
item.Poster,
|
||||
_GetBaseImagePath(item, "poster"),
|
||||
$"The poster of {name}"
|
||||
);
|
||||
await _DownloadImage(
|
||||
item.Thumbnail,
|
||||
_GetBaseImagePath(item, "thumbnail"),
|
||||
$"The poster of {name}"
|
||||
);
|
||||
await _DownloadImage(
|
||||
item.Logo,
|
||||
_GetBaseImagePath(item, "logo"),
|
||||
$"The poster of {name}"
|
||||
);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!duplicated)
|
||||
{
|
||||
lock (_downloading)
|
||||
{
|
||||
_downloading.Remove(posterPath);
|
||||
sync!.SetResult(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string _GetBaseImagePath<T>(T item, string image)
|
||||
{
|
||||
string directory = item switch
|
||||
{
|
||||
IResource res
|
||||
=> Path.Combine("/metadata", item.GetType().Name.ToLowerInvariant(), res.Slug),
|
||||
_ => Path.Combine("/metadata", typeof(T).Name.ToLowerInvariant())
|
||||
};
|
||||
Directory.CreateDirectory(directory);
|
||||
return Path.Combine(directory, image);
|
||||
await _DownloadImage(item.Poster, $"The poster of {name}");
|
||||
await _DownloadImage(item.Thumbnail, $"The thumbnail of {name}");
|
||||
await _DownloadImage(item.Logo, $"The logo of {name}");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetImagePath<T>(T item, string image, ImageQuality quality)
|
||||
where T : IThumbnails
|
||||
public string GetImagePath(Guid imageId, ImageQuality quality)
|
||||
{
|
||||
return $"{_GetBaseImagePath(item, image)}.{quality.ToString().ToLowerInvariant()}.webp";
|
||||
return $"/metadata/{imageId}.{quality.ToString().ToLowerInvariant()}.webp";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task DeleteImages<T>(T item)
|
||||
where T : IThumbnails
|
||||
{
|
||||
IEnumerable<string> images = new[] { "poster", "thumbnail", "logo" }
|
||||
.SelectMany(x => _GetBaseImagePath(item, x))
|
||||
IEnumerable<string> images = new[] {item.Poster?.Id, item.Thumbnail?.Id, item.Logo?.Id}
|
||||
.Where(x => x is not null)
|
||||
.SelectMany(x => $"/metadata/{x}")
|
||||
.SelectMany(x =>
|
||||
new[]
|
||||
{
|
||||
|
59
back/src/Kyoo.Core/Views/Content/ThumbnailsApi.cs
Normal file
59
back/src/Kyoo.Core/Views/Content/ThumbnailsApi.cs
Normal file
@ -0,0 +1,59 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Kyoo.Core.Api;
|
||||
|
||||
[ApiController]
|
||||
public class ThumbnailsApi(IThumbnailsManager thumbs) : BaseApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Get Image
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Get an image from it's id. You can select a specefic quality.
|
||||
/// </remarks>
|
||||
/// <param name="id">The ID of the image to retrive.</param>
|
||||
/// <param name="quality">The quality of the image to retrieve.</param>
|
||||
/// <returns>The image asked.</returns>
|
||||
/// <response code="404">
|
||||
/// The image does not exists on kyoo.
|
||||
/// </response>
|
||||
[HttpGet("{identifier:id}/poster")]
|
||||
[PartialPermission(Kind.Read)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public IActionResult GetPoster(Guid id, [FromQuery] ImageQuality? quality)
|
||||
{
|
||||
string path = thumbs.GetImagePath(id, quality ?? ImageQuality.High);
|
||||
if (!System.IO.File.Exists(path))
|
||||
return NotFound();
|
||||
|
||||
// Allow clients to cache the image for 6 month.
|
||||
Response.Headers.CacheControl = $"public, max-age={60 * 60 * 24 * 31 * 6}";
|
||||
return PhysicalFile(Path.GetFullPath(path), "image/webp", true);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
@ -28,14 +28,8 @@ using static Kyoo.Abstractions.Models.Utils.Constants;
|
||||
|
||||
namespace Kyoo.Core.Api;
|
||||
|
||||
/// <summary>
|
||||
/// A base class to handle CRUD operations and services thumbnails for
|
||||
/// a specific resource type <typeparamref name="T"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of resource to make CRUD and thumbnails apis for.</typeparam>
|
||||
[ApiController]
|
||||
public class CrudThumbsApi<T>(IRepository<T> repository, IThumbnailsManager thumbs)
|
||||
: CrudApi<T>(repository)
|
||||
public class CrudThumbsApi<T>(IRepository<T> repository) : CrudApi<T>(repository)
|
||||
where T : class, IResource, IThumbnails, IQuery
|
||||
{
|
||||
private async Task<IActionResult> _GetImage(
|
||||
@ -50,18 +44,18 @@ public class CrudThumbsApi<T>(IRepository<T> repository, IThumbnailsManager thum
|
||||
);
|
||||
if (resource == null)
|
||||
return NotFound();
|
||||
string path = thumbs.GetImagePath(resource, image, quality ?? ImageQuality.High);
|
||||
if (!System.IO.File.Exists(path))
|
||||
|
||||
Image? img = image switch
|
||||
{
|
||||
"poster" => resource.Poster,
|
||||
"thumbnail" => resource.Thumbnail,
|
||||
"logo" => resource.Logo,
|
||||
_ => throw new ArgumentException(nameof(image)),
|
||||
};
|
||||
if (img is null)
|
||||
return NotFound();
|
||||
|
||||
if (!identifier.Match(id => false, slug => slug == "random"))
|
||||
{
|
||||
// Allow clients to cache the image for 6 month.
|
||||
Response.Headers.CacheControl = $"public, max-age={60 * 60 * 24 * 31 * 6}";
|
||||
}
|
||||
else
|
||||
Response.Headers.CacheControl = $"public, no-store";
|
||||
return PhysicalFile(Path.GetFullPath(path), "image/webp", true);
|
||||
return Redirect($"/thumbnails/{img.Id}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -78,7 +72,7 @@ public class CrudThumbsApi<T>(IRepository<T> repository, IThumbnailsManager thum
|
||||
/// </response>
|
||||
[HttpGet("{identifier:id}/poster")]
|
||||
[PartialPermission(Kind.Read)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status302Found)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public Task<IActionResult> GetPoster(Identifier identifier, [FromQuery] ImageQuality? quality)
|
||||
{
|
||||
@ -99,7 +93,7 @@ public class CrudThumbsApi<T>(IRepository<T> repository, IThumbnailsManager thum
|
||||
/// </response>
|
||||
[HttpGet("{identifier:id}/logo")]
|
||||
[PartialPermission(Kind.Read)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status302Found)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public Task<IActionResult> GetLogo(Identifier identifier, [FromQuery] ImageQuality? quality)
|
||||
{
|
||||
@ -120,6 +114,8 @@ public class CrudThumbsApi<T>(IRepository<T> repository, IThumbnailsManager thum
|
||||
/// </response>
|
||||
[HttpGet("{identifier:id}/thumbnail")]
|
||||
[HttpGet("{identifier:id}/backdrop", Order = AlternativeRoute)]
|
||||
[ProducesResponseType(StatusCodes.Status302Found)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public Task<IActionResult> GetBackdrop(Identifier identifier, [FromQuery] ImageQuality? quality)
|
||||
{
|
||||
return _GetImage(identifier, "thumbnail", quality);
|
||||
|
@ -35,8 +35,7 @@ public static class Transcoder
|
||||
Environment.GetEnvironmentVariable("TRANSCODER_URL") ?? "http://transcoder:7666";
|
||||
}
|
||||
|
||||
public abstract class TranscoderApi<T>(IRepository<T> repository, IThumbnailsManager thumbs)
|
||||
: CrudThumbsApi<T>(repository, thumbs)
|
||||
public abstract class TranscoderApi<T>(IRepository<T> repository) : CrudThumbsApi<T>(repository)
|
||||
where T : class, IResource, IThumbnails, IQuery
|
||||
{
|
||||
private Task _Proxy(string route, (string path, string route) info)
|
||||
|
@ -40,25 +40,13 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission(nameof(Collection))]
|
||||
[ApiDefinition("Collections", Group = ResourcesGroup)]
|
||||
public class CollectionApi : CrudThumbsApi<Collection>
|
||||
public class CollectionApi(
|
||||
IRepository<Movie> movies,
|
||||
IRepository<Show> shows,
|
||||
CollectionRepository collections,
|
||||
LibraryItemRepository items
|
||||
) : CrudThumbsApi<Collection>(collections)
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly CollectionRepository _collections;
|
||||
private readonly LibraryItemRepository _items;
|
||||
|
||||
public CollectionApi(
|
||||
ILibraryManager libraryManager,
|
||||
CollectionRepository collections,
|
||||
LibraryItemRepository items,
|
||||
IThumbnailsManager thumbs
|
||||
)
|
||||
: base(libraryManager.Collections, thumbs)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_collections = collections;
|
||||
_items = items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a movie
|
||||
/// </summary>
|
||||
@ -79,14 +67,14 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
public async Task<ActionResult> AddMovie(Identifier identifier, Identifier movie)
|
||||
{
|
||||
Guid collectionId = await identifier.Match(
|
||||
async id => (await _libraryManager.Collections.Get(id)).Id,
|
||||
async slug => (await _libraryManager.Collections.Get(slug)).Id
|
||||
async id => (await collections.Get(id)).Id,
|
||||
async slug => (await collections.Get(slug)).Id
|
||||
);
|
||||
Guid movieId = await movie.Match(
|
||||
async id => (await _libraryManager.Movies.Get(id)).Id,
|
||||
async slug => (await _libraryManager.Movies.Get(slug)).Id
|
||||
async id => (await movies.Get(id)).Id,
|
||||
async slug => (await movies.Get(slug)).Id
|
||||
);
|
||||
await _collections.AddMovie(collectionId, movieId);
|
||||
await collections.AddMovie(collectionId, movieId);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@ -110,14 +98,14 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
public async Task<ActionResult> AddShow(Identifier identifier, Identifier show)
|
||||
{
|
||||
Guid collectionId = await identifier.Match(
|
||||
async id => (await _libraryManager.Collections.Get(id)).Id,
|
||||
async slug => (await _libraryManager.Collections.Get(slug)).Id
|
||||
async id => (await collections.Get(id)).Id,
|
||||
async slug => (await collections.Get(slug)).Id
|
||||
);
|
||||
Guid showId = await show.Match(
|
||||
async id => (await _libraryManager.Shows.Get(id)).Id,
|
||||
async slug => (await _libraryManager.Shows.Get(slug)).Id
|
||||
async id => (await shows.Get(id)).Id,
|
||||
async slug => (await shows.Get(slug)).Id
|
||||
);
|
||||
await _collections.AddShow(collectionId, showId);
|
||||
await collections.AddShow(collectionId, showId);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@ -151,9 +139,9 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
{
|
||||
Guid collectionId = await identifier.Match(
|
||||
id => Task.FromResult(id),
|
||||
async slug => (await _libraryManager.Collections.Get(slug)).Id
|
||||
async slug => (await collections.Get(slug)).Id
|
||||
);
|
||||
ICollection<ILibraryItem> resources = await _items.GetAllOfCollection(
|
||||
ICollection<ILibraryItem> resources = await items.GetAllOfCollection(
|
||||
collectionId,
|
||||
filter,
|
||||
sortBy == new Sort<ILibraryItem>.Default()
|
||||
@ -165,8 +153,7 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Collections.GetOrDefault(identifier.IsSame<Collection>())
|
||||
== null
|
||||
&& await collections.GetOrDefault(identifier.IsSame<Collection>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
@ -200,7 +187,7 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
[FromQuery] Include<Show>? fields
|
||||
)
|
||||
{
|
||||
ICollection<Show> resources = await _libraryManager.Shows.GetAll(
|
||||
ICollection<Show> resources = await shows.GetAll(
|
||||
Filter.And(filter, identifier.IsContainedIn<Show, Collection>(x => x.Collections)),
|
||||
sortBy == new Sort<Show>.Default() ? new Sort<Show>.By(x => x.AirDate) : sortBy,
|
||||
fields,
|
||||
@ -209,8 +196,7 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Collections.GetOrDefault(identifier.IsSame<Collection>())
|
||||
== null
|
||||
&& await collections.GetOrDefault(identifier.IsSame<Collection>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
@ -244,7 +230,7 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
[FromQuery] Include<Movie>? fields
|
||||
)
|
||||
{
|
||||
ICollection<Movie> resources = await _libraryManager.Movies.GetAll(
|
||||
ICollection<Movie> resources = await movies.GetAll(
|
||||
Filter.And(filter, identifier.IsContainedIn<Movie, Collection>(x => x.Collections)),
|
||||
sortBy == new Sort<Movie>.Default() ? new Sort<Movie>.By(x => x.AirDate) : sortBy,
|
||||
fields,
|
||||
@ -253,8 +239,7 @@ public class CollectionApi : CrudThumbsApi<Collection>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Collections.GetOrDefault(identifier.IsSame<Collection>())
|
||||
== null
|
||||
&& await collections.GetOrDefault(identifier.IsSame<Collection>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
|
@ -38,8 +38,8 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission(nameof(Episode))]
|
||||
[ApiDefinition("Episodes", Group = ResourcesGroup)]
|
||||
public class EpisodeApi(ILibraryManager libraryManager, IThumbnailsManager thumbnails)
|
||||
: TranscoderApi<Episode>(libraryManager.Episodes, thumbnails)
|
||||
public class EpisodeApi(ILibraryManager libraryManager)
|
||||
: TranscoderApi<Episode>(libraryManager.Episodes)
|
||||
{
|
||||
/// <summary>
|
||||
/// Get episode's show
|
||||
|
@ -34,23 +34,5 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission("LibraryItem")]
|
||||
[ApiDefinition("Items", Group = ResourcesGroup)]
|
||||
public class LibraryItemApi : CrudThumbsApi<ILibraryItem>
|
||||
{
|
||||
/// <summary>
|
||||
/// The library item repository used to modify or retrieve information in the data store.
|
||||
/// </summary>
|
||||
private readonly IRepository<ILibraryItem> _libraryItems;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="LibraryItemApi"/>.
|
||||
/// </summary>
|
||||
/// <param name="libraryItems">
|
||||
/// The library item repository used to modify or retrieve information in the data store.
|
||||
/// </param>
|
||||
/// <param name="thumbs">Thumbnail manager to retrieve images.</param>
|
||||
public LibraryItemApi(IRepository<ILibraryItem> libraryItems, IThumbnailsManager thumbs)
|
||||
: base(libraryItems, thumbs)
|
||||
{
|
||||
_libraryItems = libraryItems;
|
||||
}
|
||||
}
|
||||
public class LibraryItemApi(IRepository<ILibraryItem> libraryItems)
|
||||
: CrudThumbsApi<ILibraryItem>(libraryItems) { }
|
||||
|
@ -40,8 +40,8 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission(nameof(Show))]
|
||||
[ApiDefinition("Shows", Group = ResourcesGroup)]
|
||||
public class MovieApi(ILibraryManager libraryManager, IThumbnailsManager thumbs)
|
||||
: TranscoderApi<Movie>(libraryManager.Movies, thumbs)
|
||||
public class MovieApi(ILibraryManager libraryManager)
|
||||
: TranscoderApi<Movie>(libraryManager.Movies)
|
||||
{
|
||||
/// <summary>
|
||||
/// Get studio that made the show
|
||||
|
@ -33,8 +33,4 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission("LibraryItem")]
|
||||
[ApiDefinition("News", Group = ResourcesGroup)]
|
||||
public class NewsApi : CrudThumbsApi<INews>
|
||||
{
|
||||
public NewsApi(IRepository<INews> news, IThumbnailsManager thumbs)
|
||||
: base(news, thumbs) { }
|
||||
}
|
||||
public class NewsApi(IRepository<INews> news) : CrudThumbsApi<INews>(news) { }
|
||||
|
@ -38,26 +38,9 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission(nameof(Season))]
|
||||
[ApiDefinition("Seasons", Group = ResourcesGroup)]
|
||||
public class SeasonApi : CrudThumbsApi<Season>
|
||||
public class SeasonApi(ILibraryManager libraryManager)
|
||||
: CrudThumbsApi<Season>(libraryManager.Seasons)
|
||||
{
|
||||
/// <summary>
|
||||
/// The library manager used to modify or retrieve information in the data store.
|
||||
/// </summary>
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="SeasonApi"/>.
|
||||
/// </summary>
|
||||
/// <param name="libraryManager">
|
||||
/// The library manager used to modify or retrieve information in the data store.
|
||||
/// </param>
|
||||
/// <param name="thumbs">The thumbnail manager used to retrieve images paths.</param>
|
||||
public SeasonApi(ILibraryManager libraryManager, IThumbnailsManager thumbs)
|
||||
: base(libraryManager.Seasons, thumbs)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get episodes in the season
|
||||
/// </summary>
|
||||
@ -86,7 +69,7 @@ public class SeasonApi : CrudThumbsApi<Season>
|
||||
[FromQuery] Include<Episode> fields
|
||||
)
|
||||
{
|
||||
ICollection<Episode> resources = await _libraryManager.Episodes.GetAll(
|
||||
ICollection<Episode> resources = await libraryManager.Episodes.GetAll(
|
||||
Filter.And(filter, identifier.Matcher<Episode>(x => x.SeasonId, x => x.Season!.Slug)),
|
||||
sortBy,
|
||||
fields,
|
||||
@ -95,7 +78,7 @@ public class SeasonApi : CrudThumbsApi<Season>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Seasons.GetOrDefault(identifier.IsSame<Season>()) == null
|
||||
&& await libraryManager.Seasons.GetOrDefault(identifier.IsSame<Season>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
@ -120,7 +103,7 @@ public class SeasonApi : CrudThumbsApi<Season>
|
||||
[FromQuery] Include<Show> fields
|
||||
)
|
||||
{
|
||||
Show? ret = await _libraryManager.Shows.GetOrDefault(
|
||||
Show? ret = await libraryManager.Shows.GetOrDefault(
|
||||
identifier.IsContainedIn<Show, Season>(x => x.Seasons!),
|
||||
fields
|
||||
);
|
||||
|
@ -40,26 +40,8 @@ namespace Kyoo.Core.Api;
|
||||
[ApiController]
|
||||
[PartialPermission(nameof(Show))]
|
||||
[ApiDefinition("Shows", Group = ResourcesGroup)]
|
||||
public class ShowApi : CrudThumbsApi<Show>
|
||||
public class ShowApi(ILibraryManager libraryManager) : CrudThumbsApi<Show>(libraryManager.Shows)
|
||||
{
|
||||
/// <summary>
|
||||
/// The library manager used to modify or retrieve information in the data store.
|
||||
/// </summary>
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ShowApi"/>.
|
||||
/// </summary>
|
||||
/// <param name="libraryManager">
|
||||
/// The library manager used to modify or retrieve information about the data store.
|
||||
/// </param>
|
||||
/// <param name="thumbs">The thumbnail manager used to retrieve images paths.</param>
|
||||
public ShowApi(ILibraryManager libraryManager, IThumbnailsManager thumbs)
|
||||
: base(libraryManager.Shows, thumbs)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get seasons of this show
|
||||
/// </summary>
|
||||
@ -88,7 +70,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
[FromQuery] Include<Season> fields
|
||||
)
|
||||
{
|
||||
ICollection<Season> resources = await _libraryManager.Seasons.GetAll(
|
||||
ICollection<Season> resources = await libraryManager.Seasons.GetAll(
|
||||
Filter.And(filter, identifier.Matcher<Season>(x => x.ShowId, x => x.Show!.Slug)),
|
||||
sortBy,
|
||||
fields,
|
||||
@ -97,7 +79,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Shows.GetOrDefault(identifier.IsSame<Show>()) == null
|
||||
&& await libraryManager.Shows.GetOrDefault(identifier.IsSame<Show>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
@ -131,7 +113,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
[FromQuery] Include<Episode> fields
|
||||
)
|
||||
{
|
||||
ICollection<Episode> resources = await _libraryManager.Episodes.GetAll(
|
||||
ICollection<Episode> resources = await libraryManager.Episodes.GetAll(
|
||||
Filter.And(filter, identifier.Matcher<Episode>(x => x.ShowId, x => x.Show!.Slug)),
|
||||
sortBy,
|
||||
fields,
|
||||
@ -140,7 +122,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Shows.GetOrDefault(identifier.IsSame<Show>()) == null
|
||||
&& await libraryManager.Shows.GetOrDefault(identifier.IsSame<Show>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
@ -165,7 +147,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
[FromQuery] Include<Studio> fields
|
||||
)
|
||||
{
|
||||
return await _libraryManager.Studios.Get(
|
||||
return await libraryManager.Studios.Get(
|
||||
identifier.IsContainedIn<Studio, Show>(x => x.Shows!),
|
||||
fields
|
||||
);
|
||||
@ -199,7 +181,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
[FromQuery] Include<Collection> fields
|
||||
)
|
||||
{
|
||||
ICollection<Collection> resources = await _libraryManager.Collections.GetAll(
|
||||
ICollection<Collection> resources = await libraryManager.Collections.GetAll(
|
||||
Filter.And(filter, identifier.IsContainedIn<Collection, Show>(x => x.Shows!)),
|
||||
sortBy,
|
||||
fields,
|
||||
@ -208,7 +190,7 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
|
||||
if (
|
||||
!resources.Any()
|
||||
&& await _libraryManager.Shows.GetOrDefault(identifier.IsSame<Show>()) == null
|
||||
&& await libraryManager.Shows.GetOrDefault(identifier.IsSame<Show>()) == null
|
||||
)
|
||||
return NotFound();
|
||||
return Page(resources, pagination.Limit);
|
||||
@ -233,9 +215,9 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
{
|
||||
Guid id = await identifier.Match(
|
||||
id => Task.FromResult(id),
|
||||
async slug => (await _libraryManager.Shows.Get(slug)).Id
|
||||
async slug => (await libraryManager.Shows.Get(slug)).Id
|
||||
);
|
||||
return await _libraryManager.WatchStatus.GetShowStatus(id, User.GetIdOrThrow());
|
||||
return await libraryManager.WatchStatus.GetShowStatus(id, User.GetIdOrThrow());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -260,9 +242,9 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
{
|
||||
Guid id = await identifier.Match(
|
||||
id => Task.FromResult(id),
|
||||
async slug => (await _libraryManager.Shows.Get(slug)).Id
|
||||
async slug => (await libraryManager.Shows.Get(slug)).Id
|
||||
);
|
||||
return await _libraryManager.WatchStatus.SetShowStatus(id, User.GetIdOrThrow(), status);
|
||||
return await libraryManager.WatchStatus.SetShowStatus(id, User.GetIdOrThrow(), status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -283,8 +265,8 @@ public class ShowApi : CrudThumbsApi<Show>
|
||||
{
|
||||
Guid id = await identifier.Match(
|
||||
id => Task.FromResult(id),
|
||||
async slug => (await _libraryManager.Shows.Get(slug)).Id
|
||||
async slug => (await libraryManager.Shows.Get(slug)).Id
|
||||
);
|
||||
await _libraryManager.WatchStatus.DeleteShowStatus(id, User.GetIdOrThrow());
|
||||
await libraryManager.WatchStatus.DeleteShowStatus(id, User.GetIdOrThrow());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user