aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Controllers
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Controllers')
-rw-r--r--Jellyfin.Api/Controllers/AlbumsController.cs135
-rw-r--r--Jellyfin.Api/Controllers/LibraryController.cs156
2 files changed, 63 insertions, 228 deletions
diff --git a/Jellyfin.Api/Controllers/AlbumsController.cs b/Jellyfin.Api/Controllers/AlbumsController.cs
deleted file mode 100644
index 357f646a2..000000000
--- a/Jellyfin.Api/Controllers/AlbumsController.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using Jellyfin.Api.Extensions;
-using Jellyfin.Api.Helpers;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.Audio;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Querying;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-
-namespace Jellyfin.Api.Controllers
-{
- /// <summary>
- /// The albums controller.
- /// </summary>
- [Route("")]
- public class AlbumsController : BaseJellyfinApiController
- {
- private readonly IUserManager _userManager;
- private readonly ILibraryManager _libraryManager;
- private readonly IDtoService _dtoService;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="AlbumsController"/> class.
- /// </summary>
- /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
- /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
- /// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
- public AlbumsController(
- IUserManager userManager,
- ILibraryManager libraryManager,
- IDtoService dtoService)
- {
- _userManager = userManager;
- _libraryManager = libraryManager;
- _dtoService = dtoService;
- }
-
- /// <summary>
- /// Finds albums similar to a given album.
- /// </summary>
- /// <param name="albumId">The album id.</param>
- /// <param name="userId">Optional. Filter by user id, and attach user data.</param>
- /// <param name="excludeArtistIds">Optional. Ids of artists to exclude.</param>
- /// <param name="limit">Optional. The maximum number of records to return.</param>
- /// <response code="200">Similar albums returned.</response>
- /// <returns>A <see cref="QueryResult{BaseItemDto}"/> with similar albums.</returns>
- [HttpGet("Albums/{albumId}/Similar")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<QueryResult<BaseItemDto>> GetSimilarAlbums(
- [FromRoute, Required] string albumId,
- [FromQuery] Guid? userId,
- [FromQuery] string? excludeArtistIds,
- [FromQuery] int? limit)
- {
- var dtoOptions = new DtoOptions().AddClientFields(Request);
-
- return SimilarItemsHelper.GetSimilarItemsResult(
- dtoOptions,
- _userManager,
- _libraryManager,
- _dtoService,
- userId,
- albumId,
- excludeArtistIds,
- limit,
- new[] { typeof(MusicAlbum) },
- GetAlbumSimilarityScore);
- }
-
- /// <summary>
- /// Finds artists similar to a given artist.
- /// </summary>
- /// <param name="artistId">The artist id.</param>
- /// <param name="userId">Optional. Filter by user id, and attach user data.</param>
- /// <param name="excludeArtistIds">Optional. Ids of artists to exclude.</param>
- /// <param name="limit">Optional. The maximum number of records to return.</param>
- /// <response code="200">Similar artists returned.</response>
- /// <returns>A <see cref="QueryResult{BaseItemDto}"/> with similar artists.</returns>
- [HttpGet("Artists/{artistId}/Similar")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<QueryResult<BaseItemDto>> GetSimilarArtists(
- [FromRoute, Required] string artistId,
- [FromQuery] Guid? userId,
- [FromQuery] string? excludeArtistIds,
- [FromQuery] int? limit)
- {
- var dtoOptions = new DtoOptions().AddClientFields(Request);
-
- return SimilarItemsHelper.GetSimilarItemsResult(
- dtoOptions,
- _userManager,
- _libraryManager,
- _dtoService,
- userId,
- artistId,
- excludeArtistIds,
- limit,
- new[] { typeof(MusicArtist) },
- SimilarItemsHelper.GetSimiliarityScore);
- }
-
- /// <summary>
- /// Gets a similairty score of two albums.
- /// </summary>
- /// <param name="item1">The first item.</param>
- /// <param name="item1People">The item1 people.</param>
- /// <param name="allPeople">All people.</param>
- /// <param name="item2">The second item.</param>
- /// <returns>System.Int32.</returns>
- private int GetAlbumSimilarityScore(BaseItem item1, List<PersonInfo> item1People, List<PersonInfo> allPeople, BaseItem item2)
- {
- var points = SimilarItemsHelper.GetSimiliarityScore(item1, item1People, allPeople, item2);
-
- var album1 = (MusicAlbum)item1;
- var album2 = (MusicAlbum)item2;
-
- var artists1 = album1
- .GetAllArtists()
- .DistinctNames()
- .ToList();
-
- var artists2 = new HashSet<string>(
- album2.GetAllArtists().DistinctNames(),
- StringComparer.OrdinalIgnoreCase);
-
- return points + artists1.Where(artists2.Contains).Sum(i => 5);
- }
- }
-}
diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs
index 2eb8363d7..0d5c1d278 100644
--- a/Jellyfin.Api/Controllers/LibraryController.cs
+++ b/Jellyfin.Api/Controllers/LibraryController.cs
@@ -681,12 +681,12 @@ namespace Jellyfin.Api.Controllers
/// <param name="fields">Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimited. Options: Budget, Chapters, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls.</param>
/// <response code="200">Similar items returned.</response>
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> containing the similar items.</returns>
- [HttpGet("Artists/{itemId}/Similar", Name = "GetSimilarArtists2")]
+ [HttpGet("Artists/{itemId}/Similar")]
[HttpGet("Items/{itemId}/Similar")]
- [HttpGet("Albums/{itemId}/Similar", Name = "GetSimilarAlbums2")]
- [HttpGet("Shows/{itemId}/Similar", Name = "GetSimilarShows2")]
- [HttpGet("Movies/{itemId}/Similar", Name = "GetSimilarMovies2")]
- [HttpGet("Trailers/{itemId}/Similar", Name = "GetSimilarTrailers2")]
+ [HttpGet("Albums/{itemId}/Similar")]
+ [HttpGet("Shows/{itemId}/Similar")]
+ [HttpGet("Movies/{itemId}/Similar")]
+ [HttpGet("Trailers/{itemId}/Similar")]
[Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<QueryResult<BaseItemDto>> GetSimilarItems(
@@ -702,33 +702,71 @@ namespace Jellyfin.Api.Controllers
: _libraryManager.RootFolder)
: _libraryManager.GetItemById(itemId);
+ if (item is Episode || (item is IItemByName && !(item is MusicArtist)))
+ {
+ return new QueryResult<BaseItemDto>();
+ }
+
+ var user = userId.HasValue && !userId.Equals(Guid.Empty)
+ ? _userManager.GetUserById(userId.Value)
+ : null;
+ var dtoOptions = new DtoOptions { Fields = fields }
+ .AddClientFields(Request);
+
var program = item as IHasProgramAttributes;
- var isMovie = item is MediaBrowser.Controller.Entities.Movies.Movie || (program != null && program.IsMovie) || item is Trailer;
- if (program != null && program.IsSeries)
+ bool? isMovie = item is Movie || (program != null && program.IsMovie) || item is Trailer;
+ bool? isSeries = item is Series || (program != null && program.IsSeries);
+
+ var includeItemTypes = new List<string>();
+ if (isMovie.Value)
{
- return GetSimilarItemsResult(
- item,
- excludeArtistIds,
- userId,
- limit,
- fields,
- new[] { nameof(Series) },
- false);
+ includeItemTypes.Add(nameof(Movie));
+ if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
+ {
+ includeItemTypes.Add(nameof(Trailer));
+ includeItemTypes.Add(nameof(LiveTvProgram));
+ }
+ }
+ else if (isSeries.Value)
+ {
+ includeItemTypes.Add(nameof(Series));
+ }
+ else
+ {
+ // For non series and movie types these columns are typically null
+ isSeries = null;
+ isMovie = null;
+ includeItemTypes.Add(item.GetType().Name);
}
- if (item is MediaBrowser.Controller.Entities.TV.Episode || (item is IItemByName && !(item is MusicArtist)))
+ var query = new InternalItemsQuery(user)
{
- return new QueryResult<BaseItemDto>();
+ Limit = limit,
+ IncludeItemTypes = includeItemTypes.ToArray(),
+ IsMovie = isMovie,
+ IsSeries = isSeries,
+ SimilarTo = item,
+ DtoOptions = dtoOptions,
+ EnableTotalRecordCount = !isMovie ?? true,
+ EnableGroupByMetadataKey = isMovie ?? false,
+ MinSimilarityScore = 2 // A remnant from album/artist scoring
+ };
+
+ // ExcludeArtistIds
+ if (!string.IsNullOrEmpty(excludeArtistIds))
+ {
+ query.ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds);
}
- return GetSimilarItemsResult(
- item,
- excludeArtistIds,
- userId,
- limit,
- fields,
- new[] { item.GetType().Name },
- isMovie);
+ List<BaseItem> itemsResult = _libraryManager.GetItemList(query);
+
+ var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
+
+ return new QueryResult<BaseItemDto>
+ {
+ Items = returnList,
+ TotalRecordCount = itemsResult.Count
+ };
}
/// <summary>
@@ -881,74 +919,6 @@ namespace Jellyfin.Api.Controllers
}
}
- private QueryResult<BaseItemDto> GetSimilarItemsResult(
- BaseItem item,
- string? excludeArtistIds,
- Guid? userId,
- int? limit,
- ItemFields[] fields,
- string[] includeItemTypes,
- bool isMovie)
- {
- var user = userId.HasValue && !userId.Equals(Guid.Empty)
- ? _userManager.GetUserById(userId.Value)
- : null;
- var dtoOptions = new DtoOptions { Fields = fields }
- .AddClientFields(Request);
-
- var query = new InternalItemsQuery(user)
- {
- Limit = limit,
- IncludeItemTypes = includeItemTypes,
- IsMovie = isMovie,
- SimilarTo = item,
- DtoOptions = dtoOptions,
- EnableTotalRecordCount = !isMovie,
- EnableGroupByMetadataKey = isMovie
- };
-
- // ExcludeArtistIds
- if (!string.IsNullOrEmpty(excludeArtistIds))
- {
- query.ExcludeArtistIds = RequestHelpers.GetGuids(excludeArtistIds);
- }
-
- List<BaseItem> itemsResult;
-
- if (isMovie)
- {
- var itemTypes = new List<string> { nameof(MediaBrowser.Controller.Entities.Movies.Movie) };
- if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
- {
- itemTypes.Add(nameof(Trailer));
- itemTypes.Add(nameof(LiveTvProgram));
- }
-
- query.IncludeItemTypes = itemTypes.ToArray();
- itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
- }
- else if (item is MusicArtist)
- {
- query.IncludeItemTypes = Array.Empty<string>();
-
- itemsResult = _libraryManager.GetArtists(query).Items.Select(i => i.Item1).ToList();
- }
- else
- {
- itemsResult = _libraryManager.GetItemList(query);
- }
-
- var returnList = _dtoService.GetBaseItemDtos(itemsResult, dtoOptions, user);
-
- var result = new QueryResult<BaseItemDto>
- {
- Items = returnList,
- TotalRecordCount = itemsResult.Count
- };
-
- return result;
- }
-
private static string[] GetRepresentativeItemTypes(string? contentType)
{
return contentType switch