using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Configuration;
namespace Emby.Server.Implementations.Library.SimilarItems;
///
/// Provides similar items for movies and trailers.
///
public sealed class MovieSimilarItemsProvider : ILocalSimilarItemsProvider, ILocalSimilarItemsProvider
{
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
///
/// Initializes a new instance of the class.
///
/// The library manager.
/// The server configuration manager.
public MovieSimilarItemsProvider(
ILibraryManager libraryManager,
IServerConfigurationManager serverConfigurationManager)
{
_libraryManager = libraryManager;
_serverConfigurationManager = serverConfigurationManager;
}
///
public string Name => "Local Genre/Tag";
///
public MetadataPluginType Type => MetadataPluginType.LocalSimilarityProvider;
///
public Task> GetSimilarItemsAsync(Movie item, SimilarItemsQuery query, CancellationToken cancellationToken)
{
return Task.FromResult(GetSimilarMovieItems(item, query));
}
///
public Task> GetSimilarItemsAsync(Trailer item, SimilarItemsQuery query, CancellationToken cancellationToken)
{
return Task.FromResult(GetSimilarMovieItems(item, query));
}
bool ILocalSimilarItemsProvider.Supports(Type itemType)
=> typeof(Movie).IsAssignableFrom(itemType) || typeof(Trailer).IsAssignableFrom(itemType);
Task> ILocalSimilarItemsProvider.GetSimilarItemsAsync(BaseItem item, SimilarItemsQuery query, CancellationToken cancellationToken)
=> item switch
{
Movie movie => GetSimilarItemsAsync(movie, query, cancellationToken),
Trailer trailer => GetSimilarItemsAsync(trailer, query, cancellationToken),
_ => throw new ArgumentException($"Unsupported item type {item.GetType()}", nameof(item))
};
private IReadOnlyList GetSimilarMovieItems(BaseItem item, SimilarItemsQuery query)
{
var includeItemTypes = new List { BaseItemKind.Movie };
if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
{
includeItemTypes.Add(BaseItemKind.Trailer);
includeItemTypes.Add(BaseItemKind.LiveTvProgram);
}
var internalQuery = new InternalItemsQuery(query.User)
{
Genres = item.Genres,
Tags = item.Tags,
Limit = query.Limit,
DtoOptions = query.DtoOptions ?? new DtoOptions(),
ExcludeItemIds = [.. query.ExcludeItemIds],
IncludeItemTypes = [.. includeItemTypes],
EnableGroupByMetadataKey = true,
EnableTotalRecordCount = false,
OrderBy = [(ItemSortBy.Random, SortOrder.Ascending)]
};
return _libraryManager.GetItemList(internalQuery);
}
}