jellyfin/MediaBrowser.Controller/Entities/UserViewBuilder.cs

1011 lines
33 KiB
C#
Raw Normal View History

#nullable disable
2020-08-19 16:02:34 +00:00
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
2020-05-20 17:07:53 +00:00
using Jellyfin.Data.Entities;
2020-07-01 01:44:41 +00:00
using Jellyfin.Data.Enums;
2021-12-20 12:31:07 +00:00
using Jellyfin.Extensions;
2018-12-27 23:27:57 +00:00
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
2020-05-20 17:07:53 +00:00
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
2020-06-11 22:28:49 +00:00
using MetadataProvider = MediaBrowser.Model.Entities.MetadataProvider;
2020-05-20 17:07:53 +00:00
using Series = MediaBrowser.Controller.Entities.TV.Series;
2018-12-27 23:27:57 +00:00
namespace MediaBrowser.Controller.Entities
{
public class UserViewBuilder
{
private readonly IUserViewManager _userViewManager;
private readonly ILibraryManager _libraryManager;
private readonly ILogger<BaseItem> _logger;
2018-12-27 23:27:57 +00:00
private readonly IUserDataManager _userDataManager;
private readonly ITVSeriesManager _tvSeriesManager;
public UserViewBuilder(
IUserViewManager userViewManager,
ILibraryManager libraryManager,
ILogger<BaseItem> logger,
IUserDataManager userDataManager,
2021-11-16 11:24:17 +00:00
ITVSeriesManager tvSeriesManager)
2018-12-27 23:27:57 +00:00
{
_userViewManager = userViewManager;
_libraryManager = libraryManager;
_logger = logger;
_userDataManager = userDataManager;
_tvSeriesManager = tvSeriesManager;
}
public QueryResult<BaseItem> GetUserItems(Folder queryParent, Folder displayParent, CollectionType? viewType, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
var user = query.User;
2022-12-05 14:01:13 +00:00
// if (query.IncludeItemTypes is not null &&
2018-12-27 23:27:57 +00:00
// query.IncludeItemTypes.Length == 1 &&
// string.Equals(query.IncludeItemTypes[0], "Playlist", StringComparison.OrdinalIgnoreCase))
// {
2018-12-27 23:27:57 +00:00
// if (!string.Equals(viewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
// {
// return await FindPlaylists(queryParent, user, query).ConfigureAwait(false);
// }
// }
2018-12-27 23:27:57 +00:00
switch (viewType)
{
case CollectionType.folders:
return GetResult(_libraryManager.GetUserRootFolder().GetChildren(user, true), query);
2018-12-27 23:27:57 +00:00
case CollectionType.tvshows:
2018-12-27 23:27:57 +00:00
return GetTvView(queryParent, user, query);
case CollectionType.movies:
2018-12-27 23:27:57 +00:00
return GetMovieFolders(queryParent, user, query);
case CollectionType.tvshowseries:
2018-12-27 23:27:57 +00:00
return GetTvSeries(queryParent, user, query);
case CollectionType.tvgenres:
2018-12-27 23:27:57 +00:00
return GetTvGenres(queryParent, user, query);
case CollectionType.tvgenre:
2018-12-27 23:27:57 +00:00
return GetTvGenreItems(queryParent, displayParent, user, query);
case CollectionType.tvresume:
2018-12-27 23:27:57 +00:00
return GetTvResume(queryParent, user, query);
case CollectionType.tvnextup:
2018-12-27 23:27:57 +00:00
return GetTvNextUp(queryParent, query);
case CollectionType.tvlatest:
2018-12-27 23:27:57 +00:00
return GetTvLatest(queryParent, user, query);
case CollectionType.moviefavorites:
2018-12-27 23:27:57 +00:00
return GetFavoriteMovies(queryParent, user, query);
case CollectionType.movielatest:
2018-12-27 23:27:57 +00:00
return GetMovieLatest(queryParent, user, query);
case CollectionType.moviegenres:
2018-12-27 23:27:57 +00:00
return GetMovieGenres(queryParent, user, query);
case CollectionType.moviegenre:
2018-12-27 23:27:57 +00:00
return GetMovieGenreItems(queryParent, displayParent, user, query);
case CollectionType.movieresume:
2018-12-27 23:27:57 +00:00
return GetMovieResume(queryParent, user, query);
case CollectionType.moviemovies:
2018-12-27 23:27:57 +00:00
return GetMovieMovies(queryParent, user, query);
case CollectionType.moviecollection:
return GetMovieCollections(user, query);
2018-12-27 23:27:57 +00:00
case CollectionType.tvfavoriteepisodes:
2018-12-27 23:27:57 +00:00
return GetFavoriteEpisodes(queryParent, user, query);
case CollectionType.tvfavoriteseries:
2018-12-27 23:27:57 +00:00
return GetFavoriteSeries(queryParent, user, query);
default:
{
if (queryParent is UserView)
{
return GetResult(GetMediaFolders(user).OfType<Folder>().SelectMany(i => i.GetChildren(user, true)), query);
2018-12-27 23:27:57 +00:00
}
2018-12-27 23:27:57 +00:00
return queryParent.GetItems(query);
}
}
}
private int GetSpecialItemsLimit()
{
return 50;
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetMovieFolders(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
if (query.Recursive)
{
query.Recursive = true;
query.SetUser(user);
if (query.IncludeItemTypes.Length == 0)
{
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Movie };
2018-12-27 23:27:57 +00:00
}
return parent.QueryRecursive(query);
}
2020-05-13 02:10:35 +00:00
var list = new List<BaseItem>
{
GetUserView(CollectionType.movieresume, "HeaderContinueWatching", "0", parent),
GetUserView(CollectionType.movielatest, "Latest", "1", parent),
GetUserView(CollectionType.moviemovies, "Movies", "2", parent),
GetUserView(CollectionType.moviecollection, "Collections", "3", parent),
GetUserView(CollectionType.moviefavorites, "Favorites", "4", parent),
GetUserView(CollectionType.moviegenres, "Genres", "5", parent)
2020-05-13 02:10:35 +00:00
};
2018-12-27 23:27:57 +00:00
return GetResult(list, query);
2018-12-27 23:27:57 +00:00
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetFavoriteMovies(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Movie };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetFavoriteSeries(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Series };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetFavoriteEpisodes(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.IsFavorite = true;
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Episode };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetMovieMovies(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Movie };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
private QueryResult<BaseItem> GetMovieCollections(User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Parent = null;
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.BoxSet };
2018-12-27 23:27:57 +00:00
query.SetUser(user);
query.Recursive = true;
return _libraryManager.GetItemsResult(query);
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetMovieLatest(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
2021-04-21 20:25:08 +00:00
query.OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
2018-12-27 23:27:57 +00:00
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Movie };
2018-12-27 23:27:57 +00:00
return ConvertToResult(_libraryManager.GetItemList(query));
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
2021-04-21 20:25:08 +00:00
query.OrderBy = new[] { (ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
2018-12-27 23:27:57 +00:00
query.IsResumable = true;
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Movie };
2018-12-27 23:27:57 +00:00
return ConvertToResult(_libraryManager.GetItemList(query));
}
private QueryResult<BaseItem> ConvertToResult(List<BaseItem> items)
{
2022-01-20 15:46:17 +00:00
return new QueryResult<BaseItem>(items);
2018-12-27 23:27:57 +00:00
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
2021-12-12 02:31:30 +00:00
IncludeItemTypes = new[] { BaseItemKind.Movie },
2018-12-27 23:27:57 +00:00
Recursive = true,
EnableTotalRecordCount = false
}).Items
.SelectMany(i => i.Genres)
.DistinctNames()
.Select(i =>
{
try
{
return _libraryManager.GetGenre(i);
}
2018-12-20 12:11:26 +00:00
catch (Exception ex)
2018-12-27 23:27:57 +00:00
{
2018-12-20 12:11:26 +00:00
_logger.LogError(ex, "Error getting genre");
2018-12-27 23:27:57 +00:00
return null;
}
})
2022-12-05 14:01:13 +00:00
.Where(i => i is not null)
.Select(i => GetUserViewWithName(CollectionType.moviegenre, i.SortName, parent));
2018-12-27 23:27:57 +00:00
return GetResult(genres, query);
2018-12-27 23:27:57 +00:00
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = queryParent;
query.GenreIds = new[] { displayParent.Id };
query.SetUser(user);
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Movie };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetTvView(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
if (query.Recursive)
{
query.Recursive = true;
query.SetUser(user);
if (query.IncludeItemTypes.Length == 0)
{
2020-05-13 02:10:35 +00:00
query.IncludeItemTypes = new[]
{
2021-12-12 02:31:30 +00:00
BaseItemKind.Series,
BaseItemKind.Season,
BaseItemKind.Episode
2020-05-13 02:10:35 +00:00
};
2018-12-27 23:27:57 +00:00
}
return parent.QueryRecursive(query);
}
2020-05-13 02:10:35 +00:00
var list = new List<BaseItem>
{
GetUserView(CollectionType.tvresume, "HeaderContinueWatching", "0", parent),
GetUserView(CollectionType.tvnextup, "HeaderNextUp", "1", parent),
GetUserView(CollectionType.tvlatest, "Latest", "2", parent),
GetUserView(CollectionType.tvshowseries, "Shows", "3", parent),
GetUserView(CollectionType.tvfavoriteseries, "HeaderFavoriteShows", "4", parent),
GetUserView(CollectionType.tvfavoriteepisodes, "HeaderFavoriteEpisodes", "5", parent),
GetUserView(CollectionType.tvgenres, "Genres", "6", parent)
2020-05-13 02:10:35 +00:00
};
2018-12-27 23:27:57 +00:00
return GetResult(list, query);
2018-12-27 23:27:57 +00:00
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
2021-04-21 20:25:08 +00:00
query.OrderBy = new[] { (ItemSortBy.DateCreated, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
2018-12-27 23:27:57 +00:00
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Episode };
2018-12-27 23:27:57 +00:00
query.IsVirtualItem = false;
return ConvertToResult(_libraryManager.GetItemList(query));
}
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
{
var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.tvshows });
2018-12-27 23:27:57 +00:00
2020-10-12 18:05:11 +00:00
var result = _tvSeriesManager.GetNextUp(
new NextUpQuery
{
Limit = query.Limit,
StartIndex = query.StartIndex,
UserId = query.User.Id
},
parentFolders,
query.DtoOptions);
2018-12-27 23:27:57 +00:00
return result;
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetTvResume(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
2021-04-21 20:25:08 +00:00
query.OrderBy = new[] { (ItemSortBy.DatePlayed, SortOrder.Descending), (ItemSortBy.SortName, SortOrder.Descending) };
2018-12-27 23:27:57 +00:00
query.IsResumable = true;
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
query.Limit = GetSpecialItemsLimit();
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Episode };
2018-12-27 23:27:57 +00:00
return ConvertToResult(_libraryManager.GetItemList(query));
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetTvSeries(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = parent;
query.SetUser(user);
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Series };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
var genres = parent.QueryRecursive(new InternalItemsQuery(user)
{
2021-12-12 02:31:30 +00:00
IncludeItemTypes = new[] { BaseItemKind.Series },
2018-12-27 23:27:57 +00:00
Recursive = true,
EnableTotalRecordCount = false
}).Items
.SelectMany(i => i.Genres)
.DistinctNames()
.Select(i =>
{
try
{
return _libraryManager.GetGenre(i);
}
2018-12-20 12:11:26 +00:00
catch (Exception ex)
2018-12-27 23:27:57 +00:00
{
2018-12-20 12:11:26 +00:00
_logger.LogError(ex, "Error getting genre");
2018-12-27 23:27:57 +00:00
return null;
}
})
2022-12-05 14:01:13 +00:00
.Where(i => i is not null)
.Select(i => GetUserViewWithName(CollectionType.tvgenre, i.SortName, parent));
2018-12-27 23:27:57 +00:00
return GetResult(genres, query);
2018-12-27 23:27:57 +00:00
}
2020-05-20 17:07:53 +00:00
private QueryResult<BaseItem> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
2018-12-27 23:27:57 +00:00
{
query.Recursive = true;
query.Parent = queryParent;
query.GenreIds = new[] { displayParent.Id };
query.SetUser(user);
2021-12-12 02:31:30 +00:00
query.IncludeItemTypes = new[] { BaseItemKind.Series };
2018-12-27 23:27:57 +00:00
return _libraryManager.GetItemsResult(query);
}
2020-05-13 02:10:35 +00:00
private QueryResult<BaseItem> GetResult<T>(
IEnumerable<T> items,
2018-12-27 23:27:57 +00:00
InternalItemsQuery query)
where T : BaseItem
{
items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager));
return PostFilterAndSort(items, null, query, _libraryManager);
2018-12-27 23:27:57 +00:00
}
public static bool FilterItem(BaseItem item, InternalItemsQuery query)
{
return Filter(item, query.User, query, BaseItem.UserDataManager, BaseItem.LibraryManager);
}
2020-10-12 18:05:11 +00:00
public static QueryResult<BaseItem> PostFilterAndSort(
IEnumerable<BaseItem> items,
2018-12-27 23:27:57 +00:00
int? totalRecordLimit,
InternalItemsQuery query,
ILibraryManager libraryManager)
2018-12-27 23:27:57 +00:00
{
var user = query.User;
// This must be the last filter
if (!query.AdjacentTo.IsNullOrEmpty())
2018-12-27 23:27:57 +00:00
{
2022-08-14 10:47:25 +00:00
items = FilterForAdjacency(items.ToList(), query.AdjacentTo.Value);
2018-12-27 23:27:57 +00:00
}
return SortAndPage(items, totalRecordLimit, query, libraryManager, true);
}
2019-10-20 14:08:40 +00:00
public static QueryResult<BaseItem> SortAndPage(
IEnumerable<BaseItem> items,
2018-12-27 23:27:57 +00:00
int? totalRecordLimit,
InternalItemsQuery query,
2019-10-20 14:08:40 +00:00
ILibraryManager libraryManager,
bool enableSorting)
2018-12-27 23:27:57 +00:00
{
if (enableSorting)
{
2019-10-20 14:08:40 +00:00
if (query.OrderBy.Count > 0)
2018-12-27 23:27:57 +00:00
{
items = libraryManager.Sort(items, query.User, query.OrderBy);
}
}
var itemsArray = totalRecordLimit.HasValue ? items.Take(totalRecordLimit.Value).ToArray() : items.ToArray();
var totalCount = itemsArray.Length;
if (query.Limit.HasValue)
{
itemsArray = itemsArray.Skip(query.StartIndex ?? 0).Take(query.Limit.Value).ToArray();
}
else if (query.StartIndex.HasValue)
{
itemsArray = itemsArray.Skip(query.StartIndex.Value).ToArray();
}
2022-01-20 15:46:17 +00:00
return new QueryResult<BaseItem>(
query.StartIndex,
totalCount,
itemsArray);
2018-12-27 23:27:57 +00:00
}
2020-05-20 17:07:53 +00:00
public static bool Filter(BaseItem item, User user, InternalItemsQuery query, IUserDataManager userDataManager, ILibraryManager libraryManager)
2018-12-27 23:27:57 +00:00
{
if (query.MediaTypes.Length > 0 && !query.MediaTypes.Contains(item.MediaType))
2018-12-27 23:27:57 +00:00
{
return false;
}
2021-12-12 02:31:30 +00:00
if (query.IncludeItemTypes.Length > 0 && !query.IncludeItemTypes.Contains(item.GetBaseItemKind()))
2018-12-27 23:27:57 +00:00
{
return false;
}
2021-12-12 02:31:30 +00:00
if (query.ExcludeItemTypes.Length > 0 && query.ExcludeItemTypes.Contains(item.GetBaseItemKind()))
2018-12-27 23:27:57 +00:00
{
return false;
}
if (query.IsVirtualItem.HasValue && item.IsVirtualItem != query.IsVirtualItem.Value)
{
return false;
}
if (query.IsFolder.HasValue && query.IsFolder.Value != item.IsFolder)
{
return false;
}
UserItemData userData = null;
if (query.IsLiked.HasValue)
{
2019-01-25 20:52:10 +00:00
userData = userDataManager.GetUserData(user, item);
2018-12-27 23:27:57 +00:00
if (!userData.Likes.HasValue || userData.Likes != query.IsLiked.Value)
{
return false;
}
}
if (query.IsFavoriteOrLiked.HasValue)
{
userData = userData ?? userDataManager.GetUserData(user, item);
var isFavoriteOrLiked = userData.IsFavorite || (userData.Likes ?? false);
if (isFavoriteOrLiked != query.IsFavoriteOrLiked.Value)
{
return false;
}
}
if (query.IsFavorite.HasValue)
{
userData = userData ?? userDataManager.GetUserData(user, item);
if (userData.IsFavorite != query.IsFavorite.Value)
{
return false;
}
}
if (query.IsResumable.HasValue)
{
userData = userData ?? userDataManager.GetUserData(user, item);
var isResumable = userData.PlaybackPositionTicks > 0;
if (isResumable != query.IsResumable.Value)
{
return false;
}
}
if (query.IsPlayed.HasValue)
{
if (item.IsPlayed(user) != query.IsPlayed.Value)
{
return false;
}
}
// Filter by Video3DFormat
if (query.Is3D.HasValue)
{
var val = query.Is3D.Value;
var video = item as Video;
2022-12-05 14:00:20 +00:00
if (video is null || val != video.Video3DFormat.HasValue)
2018-12-27 23:27:57 +00:00
{
return false;
}
}
/*
* fuck - fix this
if (query.IsHD.HasValue)
{
if (item.IsHD != query.IsHD.Value)
{
return false;
}
}
*/
if (query.IsLocked.HasValue)
{
var val = query.IsLocked.Value;
if (item.IsLocked != val)
{
return false;
}
}
if (query.HasOverview.HasValue)
{
var filterValue = query.HasOverview.Value;
var hasValue = !string.IsNullOrEmpty(item.Overview);
if (hasValue != filterValue)
{
return false;
}
}
if (query.HasImdbId.HasValue)
{
var filterValue = query.HasImdbId.Value;
2020-06-06 19:17:49 +00:00
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Imdb));
2018-12-27 23:27:57 +00:00
if (hasValue != filterValue)
{
return false;
}
}
if (query.HasTmdbId.HasValue)
{
var filterValue = query.HasTmdbId.Value;
2020-06-06 19:17:49 +00:00
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Tmdb));
2018-12-27 23:27:57 +00:00
if (hasValue != filterValue)
{
return false;
}
}
if (query.HasTvdbId.HasValue)
{
var filterValue = query.HasTvdbId.Value;
2020-06-06 19:17:49 +00:00
var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProvider.Tvdb));
2018-12-27 23:27:57 +00:00
if (hasValue != filterValue)
{
return false;
}
}
if (query.HasOfficialRating.HasValue)
{
var filterValue = query.HasOfficialRating.Value;
var hasValue = !string.IsNullOrEmpty(item.OfficialRating);
if (hasValue != filterValue)
{
return false;
}
}
if (query.IsPlaceHolder.HasValue)
{
var filterValue = query.IsPlaceHolder.Value;
var isPlaceHolder = false;
2020-08-19 16:02:34 +00:00
if (item is ISupportsPlaceHolders hasPlaceHolder)
2018-12-27 23:27:57 +00:00
{
isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
}
if (isPlaceHolder != filterValue)
{
return false;
}
}
if (query.HasSpecialFeature.HasValue)
{
var filterValue = query.HasSpecialFeature.Value;
2020-08-19 16:02:34 +00:00
if (item is IHasSpecialFeatures movie)
2018-12-27 23:27:57 +00:00
{
var ok = filterValue
2020-08-19 16:02:34 +00:00
? movie.SpecialFeatureIds.Count > 0
: movie.SpecialFeatureIds.Count == 0;
2018-12-27 23:27:57 +00:00
if (!ok)
{
return false;
}
}
else
{
return false;
}
}
if (query.HasSubtitles.HasValue)
{
var val = query.HasSubtitles.Value;
var video = item as Video;
2022-12-05 14:00:20 +00:00
if (video is null || val != video.HasSubtitles)
2018-12-27 23:27:57 +00:00
{
return false;
}
}
if (query.HasParentalRating.HasValue)
{
var val = query.HasParentalRating.Value;
var rating = item.CustomRating;
if (string.IsNullOrEmpty(rating))
{
rating = item.OfficialRating;
}
if (val)
{
if (string.IsNullOrEmpty(rating))
{
return false;
}
}
else
{
if (!string.IsNullOrEmpty(rating))
{
return false;
}
}
}
if (query.HasTrailer.HasValue)
{
var val = query.HasTrailer.Value;
var trailerCount = 0;
2021-12-07 14:18:17 +00:00
if (item is IHasTrailers hasTrailers)
2018-12-27 23:27:57 +00:00
{
2021-12-07 14:18:17 +00:00
trailerCount = hasTrailers.GetTrailerCount();
2018-12-27 23:27:57 +00:00
}
var ok = val ? trailerCount > 0 : trailerCount == 0;
if (!ok)
{
return false;
}
}
if (query.HasThemeSong.HasValue)
{
var filterValue = query.HasThemeSong.Value;
var themeCount = item.GetThemeSongs(user).Count;
2018-12-27 23:27:57 +00:00
var ok = filterValue ? themeCount > 0 : themeCount == 0;
if (!ok)
{
return false;
}
}
if (query.HasThemeVideo.HasValue)
{
var filterValue = query.HasThemeVideo.Value;
var themeCount = item.GetThemeVideos(user).Count;
2018-12-27 23:27:57 +00:00
var ok = filterValue ? themeCount > 0 : themeCount == 0;
if (!ok)
{
return false;
}
}
// Apply genre filter
2021-12-20 12:31:07 +00:00
if (query.Genres.Count > 0 && !query.Genres.Any(v => item.Genres.Contains(v, StringComparison.OrdinalIgnoreCase)))
2018-12-27 23:27:57 +00:00
{
return false;
}
// Filter by VideoType
if (query.VideoTypes.Length > 0)
{
var video = item as Video;
2022-12-05 14:00:20 +00:00
if (video is null || !query.VideoTypes.Contains(video.VideoType))
2018-12-27 23:27:57 +00:00
{
return false;
}
}
if (query.ImageTypes.Length > 0 && !query.ImageTypes.Any(item.HasImage))
{
return false;
}
// Apply studio filter
if (query.StudioIds.Length > 0 && !query.StudioIds.Any(id =>
{
var studioItem = libraryManager.GetItemById(id);
2022-12-05 14:01:13 +00:00
return studioItem is not null && item.Studios.Contains(studioItem.Name, StringComparison.OrdinalIgnoreCase);
2018-12-27 23:27:57 +00:00
}))
{
return false;
}
// Apply genre filter
if (query.GenreIds.Count > 0 && !query.GenreIds.Any(id =>
2018-12-27 23:27:57 +00:00
{
var genreItem = libraryManager.GetItemById(id);
2022-12-05 14:01:13 +00:00
return genreItem is not null && item.Genres.Contains(genreItem.Name, StringComparison.OrdinalIgnoreCase);
2018-12-27 23:27:57 +00:00
}))
{
return false;
}
// Apply year filter
if (query.Years.Length > 0)
{
if (!(item.ProductionYear.HasValue && query.Years.Contains(item.ProductionYear.Value)))
{
return false;
}
}
// Apply official rating filter
if (query.OfficialRatings.Length > 0 && !query.OfficialRatings.Contains(item.OfficialRating ?? string.Empty))
{
return false;
}
if (query.ItemIds.Length > 0)
{
if (!query.ItemIds.Contains(item.Id))
{
return false;
}
}
// Apply tag filter
var tags = query.Tags;
if (tags.Length > 0)
{
2021-12-20 12:31:07 +00:00
if (!tags.Any(v => item.Tags.Contains(v, StringComparison.OrdinalIgnoreCase)))
2018-12-27 23:27:57 +00:00
{
return false;
}
}
if (query.MinCommunityRating.HasValue)
{
var val = query.MinCommunityRating.Value;
if (!(item.CommunityRating.HasValue && item.CommunityRating >= val))
{
return false;
}
}
if (query.MinCriticRating.HasValue)
{
var val = query.MinCriticRating.Value;
if (!(item.CriticRating.HasValue && item.CriticRating >= val))
{
return false;
}
}
if (query.MinIndexNumber.HasValue)
{
var val = query.MinIndexNumber.Value;
if (!(item.IndexNumber.HasValue && item.IndexNumber.Value >= val))
{
return false;
}
}
if (query.MinPremiereDate.HasValue)
{
var val = query.MinPremiereDate.Value;
if (!(item.PremiereDate.HasValue && item.PremiereDate.Value >= val))
{
return false;
}
}
if (query.MaxPremiereDate.HasValue)
{
var val = query.MaxPremiereDate.Value;
if (!(item.PremiereDate.HasValue && item.PremiereDate.Value <= val))
{
return false;
}
}
if (query.ParentIndexNumber.HasValue)
{
var filterValue = query.ParentIndexNumber.Value;
if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value != filterValue)
{
return false;
}
}
if (query.SeriesStatuses.Length > 0)
{
var ok = new[] { item }.OfType<Series>().Any(p => p.Status.HasValue && query.SeriesStatuses.Contains(p.Status.Value));
if (!ok)
{
return false;
}
}
if (query.AiredDuringSeason.HasValue)
{
var episode = item as Episode;
2022-12-05 14:00:20 +00:00
if (episode is null)
2018-12-27 23:27:57 +00:00
{
return false;
}
if (!Series.FilterEpisodesBySeason(new[] { episode }, query.AiredDuringSeason.Value, true).Any())
{
return false;
}
}
return true;
}
2020-05-20 17:07:53 +00:00
private IEnumerable<BaseItem> GetMediaFolders(User user)
2018-12-27 23:27:57 +00:00
{
2022-12-05 14:00:20 +00:00
if (user is null)
2018-12-27 23:27:57 +00:00
{
return _libraryManager.RootFolder
.Children
.OfType<Folder>()
.Where(UserView.IsEligibleForGrouping);
}
2020-06-15 21:43:52 +00:00
2018-12-27 23:27:57 +00:00
return _libraryManager.GetUserRootFolder()
.GetChildren(user, true)
.OfType<Folder>()
.Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i));
}
private BaseItem[] GetMediaFolders(User user, IEnumerable<CollectionType> viewTypes)
2018-12-27 23:27:57 +00:00
{
2022-12-05 14:00:20 +00:00
if (user is null)
2018-12-27 23:27:57 +00:00
{
return GetMediaFolders(null)
.Where(i =>
{
var folder = i as ICollectionFolder;
return folder?.CollectionType is not null && viewTypes.Contains(folder.CollectionType.Value);
2018-12-27 23:27:57 +00:00
}).ToArray();
}
2020-06-15 21:43:52 +00:00
2018-12-27 23:27:57 +00:00
return GetMediaFolders(user)
.Where(i =>
{
var folder = i as ICollectionFolder;
return folder?.CollectionType is not null && viewTypes.Contains(folder.CollectionType.Value);
2018-12-27 23:27:57 +00:00
}).ToArray();
}
private BaseItem[] GetMediaFolders(Folder parent, User user, IEnumerable<CollectionType> viewTypes)
2018-12-27 23:27:57 +00:00
{
2022-12-05 14:00:20 +00:00
if (parent is null || parent is UserView)
2018-12-27 23:27:57 +00:00
{
return GetMediaFolders(user, viewTypes);
}
return new BaseItem[] { parent };
}
private UserView GetUserViewWithName(CollectionType? type, string sortName, BaseItem parent)
2018-12-27 23:27:57 +00:00
{
return _userViewManager.GetUserSubView(parent.Id, type, parent.Id.ToString("N", CultureInfo.InvariantCulture), sortName);
2018-12-27 23:27:57 +00:00
}
private UserView GetUserView(CollectionType? type, string localizationKey, string sortName, BaseItem parent)
2018-12-27 23:27:57 +00:00
{
return _userViewManager.GetUserSubView(parent.Id, type, localizationKey, sortName);
}
2022-08-14 10:47:25 +00:00
public static IEnumerable<BaseItem> FilterForAdjacency(List<BaseItem> list, Guid adjacentTo)
2018-12-27 23:27:57 +00:00
{
2022-08-14 10:47:25 +00:00
var adjacentToItem = list.FirstOrDefault(i => i.Id.Equals(adjacentTo));
2018-12-27 23:27:57 +00:00
var index = list.IndexOf(adjacentToItem);
var previousId = Guid.Empty;
var nextId = Guid.Empty;
if (index > 0)
{
previousId = list[index - 1].Id;
}
if (index < list.Count - 1)
{
nextId = list[index + 1].Id;
}
2022-08-14 10:47:25 +00:00
return list.Where(i => i.Id.Equals(previousId) || i.Id.Equals(nextId) || i.Id.Equals(adjacentTo));
2018-12-27 23:27:57 +00:00
}
}
}