aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities/UserViewBuilder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Controller/Entities/UserViewBuilder.cs')
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs829
1 files changed, 785 insertions, 44 deletions
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 8efa1b6bb..bf6cac87e 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -1,9 +1,12 @@
-using MediaBrowser.Controller.Channels;
+using System.IO;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Entities;
@@ -27,8 +30,9 @@ namespace MediaBrowser.Controller.Entities
private readonly ILogger _logger;
private readonly IUserDataManager _userDataManager;
private readonly ITVSeriesManager _tvSeriesManager;
+ private readonly ICollectionManager _collectionManager;
- public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager)
+ public UserViewBuilder(IUserViewManager userViewManager, ILiveTvManager liveTvManager, IChannelManager channelManager, ILibraryManager libraryManager, ILogger logger, IUserDataManager userDataManager, ITVSeriesManager tvSeriesManager, ICollectionManager collectionManager)
{
_userViewManager = userViewManager;
_liveTvManager = liveTvManager;
@@ -37,6 +41,7 @@ namespace MediaBrowser.Controller.Entities
_logger = logger;
_userDataManager = userDataManager;
_tvSeriesManager = tvSeriesManager;
+ _collectionManager = collectionManager;
}
public async Task<QueryResult<BaseItem>> GetUserItems(Folder parent, string viewType, InternalItemsQuery query)
@@ -102,17 +107,17 @@ namespace MediaBrowser.Controller.Entities
{
var result = await GetLiveTvFolders(user).ConfigureAwait(false);
- return GetResult(result, query);
+ return GetResult(result, parent, query);
}
case CollectionType.Folders:
- return GetResult(user.RootFolder.GetChildren(user, true), query);
+ return GetResult(user.RootFolder.GetChildren(user, true), parent, query);
case CollectionType.Games:
return await GetGameView(user, parent, query).ConfigureAwait(false);
case CollectionType.BoxSets:
- return GetResult(GetMediaFolders(user).SelectMany(i => i.GetRecursiveChildren(user)).OfType<BoxSet>(), query);
+ return GetResult(GetMediaFolders(user).SelectMany(i => i.GetRecursiveChildren(user)).OfType<BoxSet>(), parent, query);
case CollectionType.TvShows:
return await GetTvView(parent, user, query).ConfigureAwait(false);
@@ -205,7 +210,7 @@ namespace MediaBrowser.Controller.Entities
return GetFavoriteSongs(parent, user, query);
default:
- return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), query);
+ return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), parent, query);
}
}
@@ -218,7 +223,7 @@ namespace MediaBrowser.Controller.Entities
{
if (query.Recursive)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }), parent, query);
}
var list = new List<BaseItem>();
@@ -233,7 +238,7 @@ namespace MediaBrowser.Controller.Entities
//list.Add(await GetUserView(CollectionType.MusicGenres, user, "5", parent).ConfigureAwait(false));
list.Add(await GetUserView(category, CollectionType.MusicFavorites, user, "6", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
private async Task<QueryResult<BaseItem>> GetMusicFavorites(Folder parent, User user, InternalItemsQuery query)
@@ -246,7 +251,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(category, CollectionType.MusicFavoriteArtists, user, "1", parent).ConfigureAwait(false));
list.Add(await GetUserView(category, CollectionType.MusicFavoriteSongs, user, "2", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
@@ -270,7 +275,7 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null);
- return GetResult(artists, query);
+ return GetResult(artists, parent, query);
}
private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
@@ -294,7 +299,7 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null);
- return GetResult(artists, query);
+ return GetResult(artists, parent, query);
}
private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
@@ -318,17 +323,17 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null && _userDataManager.GetUserData(user.Id, i.GetUserDataKey()).IsFavorite);
- return GetResult(artists, query);
+ return GetResult(artists, parent, query);
}
private QueryResult<BaseItem> GetMusicAlbums(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is MusicAlbum), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is MusicAlbum), parent, query);
}
private QueryResult<BaseItem> GetMusicSongs(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is Audio.Audio), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is Audio.Audio), parent, query);
}
private QueryResult<BaseItem> GetMusicLatest(Folder parent, User user, InternalItemsQuery query)
@@ -336,14 +341,14 @@ namespace MediaBrowser.Controller.Entities
query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
query.SortOrder = SortOrder.Descending;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is MusicVideo || i is Audio.Audio), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }).Where(i => i is MusicVideo || i is Audio.Audio), parent, GetSpecialItemsLimit(), query);
}
private async Task<QueryResult<BaseItem>> GetMovieFolders(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie || i is BoxSet), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie || i is BoxSet), parent, query);
}
var list = new List<BaseItem>();
@@ -357,52 +362,52 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(category, CollectionType.MovieFavorites, user, "4", parent).ConfigureAwait(false));
//list.Add(await GetUserView(CollectionType.MovieGenres, user, "5", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
private QueryResult<BaseItem> GetFavoriteMovies(Folder parent, User user, InternalItemsQuery query)
{
query.IsFavorite = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, query);
}
private QueryResult<BaseItem> GetFavoriteSeries(Folder parent, User user, InternalItemsQuery query)
{
query.IsFavorite = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Series), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Series), parent, query);
}
private QueryResult<BaseItem> GetFavoriteEpisodes(Folder parent, User user, InternalItemsQuery query)
{
query.IsFavorite = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Episode), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Episode), parent, query);
}
private QueryResult<BaseItem> GetFavoriteSongs(Folder parent, User user, InternalItemsQuery query)
{
query.IsFavorite = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).Where(i => i is Audio.Audio), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).Where(i => i is Audio.Audio), parent, query);
}
private QueryResult<BaseItem> GetFavoriteAlbums(Folder parent, User user, InternalItemsQuery query)
{
query.IsFavorite = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).Where(i => i is MusicAlbum), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).Where(i => i is MusicAlbum), parent, query);
}
private QueryResult<BaseItem> GetMovieMovies(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, query);
}
private QueryResult<BaseItem> GetMovieCollections(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is BoxSet), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is BoxSet), parent, query);
}
private QueryResult<BaseItem> GetMovieLatest(Folder parent, User user, InternalItemsQuery query)
@@ -410,7 +415,7 @@ namespace MediaBrowser.Controller.Entities
query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
query.SortOrder = SortOrder.Descending;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, GetSpecialItemsLimit(), query);
}
private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
@@ -419,7 +424,7 @@ namespace MediaBrowser.Controller.Entities
query.SortOrder = SortOrder.Descending;
query.IsResumable = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }).Where(i => i is Movie), parent, GetSpecialItemsLimit(), query);
}
private QueryResult<BaseItem> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
@@ -444,14 +449,14 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null);
- return GetResult(genres, query);
+ return GetResult(genres, parent, query);
}
private async Task<QueryResult<BaseItem>> GetTvView(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Series || i is Season || i is Episode), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).Where(i => i is Series || i is Season || i is Episode), parent, query);
}
var list = new List<BaseItem>();
@@ -466,14 +471,14 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(category, CollectionType.TvFavoriteEpisodes, user, "5", parent).ConfigureAwait(false));
//list.Add(await GetUserView(CollectionType.TvGenres, user, "5", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
private async Task<QueryResult<BaseItem>> GetGameView(User user, Folder parent, InternalItemsQuery query)
{
if (query.Recursive)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }), parent, query);
}
var list = new List<BaseItem>();
@@ -486,7 +491,7 @@ namespace MediaBrowser.Controller.Entities
list.Add(await GetUserView(category, CollectionType.GameSystems, user, "3", parent).ConfigureAwait(false));
//list.Add(await GetUserView(CollectionType.GameGenres, user, "4", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
private QueryResult<BaseItem> GetLatestGames(Folder parent, User user, InternalItemsQuery query)
@@ -494,7 +499,7 @@ namespace MediaBrowser.Controller.Entities
query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
query.SortOrder = SortOrder.Descending;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<Game>(), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<Game>(), parent, GetSpecialItemsLimit(), query);
}
private QueryResult<BaseItem> GetRecentlyPlayedGames(Folder parent, User user, InternalItemsQuery query)
@@ -503,14 +508,14 @@ namespace MediaBrowser.Controller.Entities
query.SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName };
query.SortOrder = SortOrder.Descending;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<Game>(), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<Game>(), parent, GetSpecialItemsLimit(), query);
}
private QueryResult<BaseItem> GetFavoriteGames(Folder parent, User user, InternalItemsQuery query)
{
query.IsFavorite = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<Game>(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<Game>(), parent, query);
}
private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
@@ -518,7 +523,7 @@ namespace MediaBrowser.Controller.Entities
query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
query.SortOrder = SortOrder.Descending;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Episode>(), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Episode>(), parent, GetSpecialItemsLimit(), query);
}
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
@@ -542,12 +547,12 @@ namespace MediaBrowser.Controller.Entities
query.SortOrder = SortOrder.Descending;
query.IsResumable = true;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Episode>(), GetSpecialItemsLimit(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Episode>(), parent, GetSpecialItemsLimit(), query);
}
private QueryResult<BaseItem> GetTvSeries(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Series>(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Series>(), parent, query);
}
private QueryResult<BaseItem> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
@@ -572,12 +577,12 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null);
- return GetResult(genres, query);
+ return GetResult(genres, parent, query);
}
private QueryResult<BaseItem> GetGameSystems(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<GameSystem>(), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Games }).OfType<GameSystem>(), parent, query);
}
private QueryResult<BaseItem> GetGameGenres(Folder parent, User user, InternalItemsQuery query)
@@ -602,7 +607,7 @@ namespace MediaBrowser.Controller.Entities
})
.Where(i => i != null);
- return GetResult(genres, query);
+ return GetResult(genres, parent, query);
}
private QueryResult<BaseItem> GetResult<T>(QueryResult<T> result)
@@ -616,21 +621,24 @@ namespace MediaBrowser.Controller.Entities
}
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
+ BaseItem parentItem,
InternalItemsQuery query)
where T : BaseItem
{
- return GetResult(items, null, query);
+ return GetResult(items, parentItem, null, query);
}
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
+ BaseItem parentItem,
int? totalRecordLimit,
InternalItemsQuery query)
where T : BaseItem
{
- return SortAndFilter(items, totalRecordLimit, query, _libraryManager, _userDataManager);
+ return SortAndFilter(items, parentItem, totalRecordLimit, query, _libraryManager, _userDataManager);
}
public static QueryResult<BaseItem> SortAndFilter(IEnumerable<BaseItem> items,
+ BaseItem parentItem,
int? totalRecordLimit,
InternalItemsQuery query,
ILibraryManager libraryManager,
@@ -640,9 +648,361 @@ namespace MediaBrowser.Controller.Entities
items = items.Where(i => Filter(i, user, query, userDataManager));
+ items = FilterVirtualEpisodes(items,
+ query.IsMissing,
+ query.IsVirtualUnaired,
+ query.IsUnaired);
+
+ items = CollapseBoxSetItemsIfNeeded(items, query, parentItem, user);
+
+ // This must be the last filter
+ if (!string.IsNullOrEmpty(query.AdjacentTo))
+ {
+ items = FilterForAdjacency(items, query.AdjacentTo);
+ }
+
return Sort(items, totalRecordLimit, query, libraryManager);
}
+ public static IEnumerable<BaseItem> CollapseBoxSetItemsIfNeeded(IEnumerable<BaseItem> items,
+ InternalItemsQuery query,
+ BaseItem parentItem,
+ User user)
+ {
+ if (CollapseBoxSetItems(query, parentItem, user))
+ {
+ items = BaseItem.CollectionManager.CollapseItemsWithinBoxSets(items, user);
+ }
+
+ items = ApplyPostCollectionCollapseFilters(query, items, user);
+
+ return items;
+ }
+
+ private static IEnumerable<BaseItem> ApplyPostCollectionCollapseFilters(InternalItemsQuery request,
+ IEnumerable<BaseItem> items,
+ User user)
+ {
+ if (!string.IsNullOrEmpty(request.NameStartsWithOrGreater))
+ {
+ items = items.Where(i => string.Compare(request.NameStartsWithOrGreater, i.SortName, StringComparison.CurrentCultureIgnoreCase) < 1);
+ }
+ if (!string.IsNullOrEmpty(request.NameStartsWith))
+ {
+ items = items.Where(i => string.Compare(request.NameStartsWith, i.SortName.Substring(0, 1), StringComparison.CurrentCultureIgnoreCase) == 0);
+ }
+
+ if (!string.IsNullOrEmpty(request.NameLessThan))
+ {
+ items = items.Where(i => string.Compare(request.NameLessThan, i.SortName, StringComparison.CurrentCultureIgnoreCase) == 1);
+ }
+
+ return items;
+ }
+
+ private static bool CollapseBoxSetItems(InternalItemsQuery query,
+ BaseItem parentItem,
+ User user)
+ {
+ // Could end up stuck in a loop like this
+ if (parentItem is BoxSet)
+ {
+ return false;
+ }
+
+ var param = query.CollapseBoxSetItems;
+
+ if (!param.HasValue)
+ {
+ if (user != null && !user.Configuration.GroupMoviesIntoBoxSets)
+ {
+ return false;
+ }
+
+ if (query.IncludeItemTypes.Contains("Movie", StringComparer.OrdinalIgnoreCase))
+ {
+ param = true;
+ }
+ }
+
+ return param.HasValue && param.Value && AllowBoxSetCollapsing(query);
+ }
+
+ private static bool AllowBoxSetCollapsing(InternalItemsQuery request)
+ {
+ if (request.IsFavorite.HasValue)
+ {
+ return false;
+ }
+ if (request.IsFavoriteOrLiked.HasValue)
+ {
+ return false;
+ }
+ if (request.IsLiked.HasValue)
+ {
+ return false;
+ }
+ if (request.IsPlayed.HasValue)
+ {
+ return false;
+ }
+ if (request.IsResumable.HasValue)
+ {
+ return false;
+ }
+ if (request.IsFolder.HasValue)
+ {
+ return false;
+ }
+
+ if (request.AllGenres.Length > 0)
+ {
+ return false;
+ }
+
+ if (request.Genres.Length > 0)
+ {
+ return false;
+ }
+
+ if (request.HasImdbId.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasOfficialRating.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasOverview.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasParentalRating.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasSpecialFeature.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasSubtitles.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasThemeSong.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasThemeVideo.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasTmdbId.HasValue)
+ {
+ return false;
+ }
+
+ if (request.HasTrailer.HasValue)
+ {
+ return false;
+ }
+
+ if (request.ImageTypes.Length > 0)
+ {
+ return false;
+ }
+
+ if (request.Is3D.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsHD.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsInBoxSet.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsLocked.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsPlaceHolder.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsPlayed.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsUnidentified.HasValue)
+ {
+ return false;
+ }
+
+ if (request.IsYearMismatched.HasValue)
+ {
+ return false;
+ }
+
+ if (!string.IsNullOrWhiteSpace(request.Person))
+ {
+ return false;
+ }
+
+ if (request.Studios.Length > 0)
+ {
+ return false;
+ }
+
+ if (request.VideoTypes.Length > 0)
+ {
+ return false;
+ }
+
+ if (request.Years.Length > 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static IEnumerable<BaseItem> FilterVirtualEpisodes(
+ IEnumerable<BaseItem> items,
+ bool? isMissing,
+ bool? isVirtualUnaired,
+ bool? isUnaired)
+ {
+ items = FilterVirtualSeasons(items, isMissing, isVirtualUnaired, isUnaired);
+
+ if (isMissing.HasValue)
+ {
+ var val = isMissing.Value;
+ items = items.Where(i =>
+ {
+ var e = i as Episode;
+ if (e != null)
+ {
+ return e.IsMissingEpisode == val;
+ }
+ return true;
+ });
+ }
+
+ if (isUnaired.HasValue)
+ {
+ var val = isUnaired.Value;
+ items = items.Where(i =>
+ {
+ var e = i as Episode;
+ if (e != null)
+ {
+ return e.IsUnaired == val;
+ }
+ return true;
+ });
+ }
+
+ if (isVirtualUnaired.HasValue)
+ {
+ var val = isVirtualUnaired.Value;
+ items = items.Where(i =>
+ {
+ var e = i as Episode;
+ if (e != null)
+ {
+ return e.IsVirtualUnaired == val;
+ }
+ return true;
+ });
+ }
+
+ return items;
+ }
+
+ private static IEnumerable<BaseItem> FilterVirtualSeasons(
+ IEnumerable<BaseItem> items,
+ bool? isMissing,
+ bool? isVirtualUnaired,
+ bool? isUnaired)
+ {
+ if (isMissing.HasValue && isVirtualUnaired.HasValue)
+ {
+ if (!isMissing.Value && !isVirtualUnaired.Value)
+ {
+ return items.Where(i =>
+ {
+ var e = i as Season;
+ if (e != null)
+ {
+ return !e.IsMissingOrVirtualUnaired;
+ }
+ return true;
+ });
+ }
+ }
+
+ if (isMissing.HasValue)
+ {
+ var val = isMissing.Value;
+ items = items.Where(i =>
+ {
+ var e = i as Season;
+ if (e != null)
+ {
+ return e.IsMissingSeason == val;
+ }
+ return true;
+ });
+ }
+
+ if (isUnaired.HasValue)
+ {
+ var val = isUnaired.Value;
+ items = items.Where(i =>
+ {
+ var e = i as Season;
+ if (e != null)
+ {
+ return e.IsUnaired == val;
+ }
+ return true;
+ });
+ }
+
+ if (isVirtualUnaired.HasValue)
+ {
+ var val = isVirtualUnaired.Value;
+ items = items.Where(i =>
+ {
+ var e = i as Season;
+ if (e != null)
+ {
+ return e.IsVirtualUnaired == val;
+ }
+ return true;
+ });
+ }
+
+ return items;
+ }
+
public static QueryResult<BaseItem> Sort(IEnumerable<BaseItem> items,
int? totalRecordLimit,
InternalItemsQuery query,
@@ -692,7 +1052,7 @@ namespace MediaBrowser.Controller.Entities
{
return false;
}
-
+
if (query.IsFolder.HasValue && query.IsFolder.Value != item.IsFolder)
{
return false;
@@ -755,6 +1115,334 @@ namespace MediaBrowser.Controller.Entities
}
}
+ if (query.IsInBoxSet.HasValue)
+ {
+ var val = query.IsInBoxSet.Value;
+ if (item.Parents.OfType<BoxSet>().Any() != val)
+ {
+ return false;
+ }
+ }
+
+ // Filter by Video3DFormat
+ if (query.Is3D.HasValue)
+ {
+ var val = query.Is3D.Value;
+ var video = item as Video;
+
+ if (video == null || val != video.Video3DFormat.HasValue)
+ {
+ return false;
+ }
+ }
+
+ if (query.IsHD.HasValue)
+ {
+ var val = query.IsHD.Value;
+ var video = item as Video;
+
+ if (video == null || val != video.IsHD)
+ {
+ return false;
+ }
+ }
+
+ if (query.IsUnidentified.HasValue)
+ {
+ var val = query.IsUnidentified.Value;
+ if (item.IsUnidentified != val)
+ {
+ 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;
+
+ var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Imdb));
+
+ if (hasValue != filterValue)
+ {
+ return false;
+ }
+ }
+
+ if (query.HasTmdbId.HasValue)
+ {
+ var filterValue = query.HasTmdbId.Value;
+
+ var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tmdb));
+
+ if (hasValue != filterValue)
+ {
+ return false;
+ }
+ }
+
+ if (query.HasTvdbId.HasValue)
+ {
+ var filterValue = query.HasTvdbId.Value;
+
+ var hasValue = !string.IsNullOrEmpty(item.GetProviderId(MetadataProviders.Tvdb));
+
+ if (hasValue != filterValue)
+ {
+ return false;
+ }
+ }
+
+ if (query.IsYearMismatched.HasValue)
+ {
+ var filterValue = query.IsYearMismatched.Value;
+
+ if (IsYearMismatched(item) != 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;
+
+ var hasPlaceHolder = item as ISupportsPlaceHolders;
+
+ if (hasPlaceHolder != null)
+ {
+ isPlaceHolder = hasPlaceHolder.IsPlaceHolder;
+ }
+
+ if (isPlaceHolder != filterValue)
+ {
+ return false;
+ }
+ }
+
+ if (query.HasSpecialFeature.HasValue)
+ {
+ var filterValue = query.HasSpecialFeature.Value;
+
+ var movie = item as IHasSpecialFeatures;
+
+ if (movie != null)
+ {
+ var ok = filterValue
+ ? movie.SpecialFeatureIds.Count > 0
+ : movie.SpecialFeatureIds.Count == 0;
+
+ if (!ok)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (query.HasSubtitles.HasValue)
+ {
+ var val = query.HasSubtitles.Value;
+
+ var video = item as Video;
+
+ if (video == null || val != video.HasSubtitles)
+ {
+ 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;
+
+ var hasTrailers = item as IHasTrailers;
+ if (hasTrailers != null)
+ {
+ trailerCount = hasTrailers.LocalTrailerIds.Count;
+ }
+
+ var ok = val ? trailerCount > 0 : trailerCount == 0;
+
+ if (!ok)
+ {
+ return false;
+ }
+ }
+
+ if (query.HasThemeSong.HasValue)
+ {
+ var filterValue = query.HasThemeSong.Value;
+
+ var themeCount = 0;
+ var iHasThemeMedia = item as IHasThemeMedia;
+
+ if (iHasThemeMedia != null)
+ {
+ themeCount = iHasThemeMedia.ThemeSongIds.Count;
+ }
+ var ok = filterValue ? themeCount > 0 : themeCount == 0;
+
+ if (!ok)
+ {
+ return false;
+ }
+ }
+
+ if (query.HasThemeVideo.HasValue)
+ {
+ var filterValue = query.HasThemeVideo.Value;
+
+ var themeCount = 0;
+ var iHasThemeMedia = item as IHasThemeMedia;
+
+ if (iHasThemeMedia != null)
+ {
+ themeCount = iHasThemeMedia.ThemeVideoIds.Count;
+ }
+ var ok = filterValue ? themeCount > 0 : themeCount == 0;
+
+ if (!ok)
+ {
+ return false;
+ }
+ }
+
+ // Apply genre filter
+ if (query.Genres.Length > 0 && !(query.Genres.Any(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase))))
+ {
+ return false;
+ }
+
+ // Apply genre filter
+ if (query.AllGenres.Length > 0 && !query.AllGenres.All(v => item.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ // Filter by VideoType
+ if (query.VideoTypes.Length > 0)
+ {
+ var video = item as Video;
+ if (video == null || !query.VideoTypes.Contains(video.VideoType))
+ {
+ return false;
+ }
+ }
+
+ if (query.ImageTypes.Length > 0 && !query.ImageTypes.Any(item.HasImage))
+ {
+ return false;
+ }
+
+ // Apply studio filter
+ if (query.Studios.Length > 0 && !query.Studios.Any(v => item.Studios.Contains(v, StringComparer.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ // Apply year filter
+ if (query.Years.Length > 0)
+ {
+ if (!(item.ProductionYear.HasValue && query.Years.Contains(item.ProductionYear.Value)))
+ {
+ return false;
+ }
+ }
+
+ // Apply person filter
+ if (!string.IsNullOrEmpty(query.Person))
+ {
+ var personTypes = query.PersonTypes;
+
+ if (personTypes.Length == 0)
+ {
+ if (!(item.People.Any(p => string.Equals(p.Name, query.Person, StringComparison.OrdinalIgnoreCase))))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ var types = personTypes;
+
+ var ok = new[] { item }.Any(i =>
+ i.People != null &&
+ i.People.Any(p =>
+ p.Name.Equals(query.Person, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase))));
+
+ if (!ok)
+ {
+ return false;
+ }
+ }
+ }
+
return true;
}
@@ -768,7 +1456,7 @@ namespace MediaBrowser.Controller.Entities
.Where(i => !excludeFolderIds.Contains(i.Id) && !UserView.IsExcludedFromGrouping(i));
}
- private IEnumerable<Folder> GetMediaFolders(User user, string[] viewTypes)
+ private IEnumerable<Folder> GetMediaFolders(User user, IEnumerable<string> viewTypes)
{
return GetMediaFolders(user)
.Where(i =>
@@ -824,5 +1512,58 @@ namespace MediaBrowser.Controller.Entities
return view;
}
+
+ public static bool IsYearMismatched(BaseItem item)
+ {
+ if (item.ProductionYear.HasValue)
+ {
+ var path = item.Path;
+
+ if (!string.IsNullOrEmpty(path))
+ {
+ int? yearInName;
+ string name;
+ NameParser.ParseName(Path.GetFileName(path), out name, out yearInName);
+
+ // Go up a level if we didn't get a year
+ if (!yearInName.HasValue)
+ {
+ NameParser.ParseName(Path.GetFileName(Path.GetDirectoryName(path)), out name, out yearInName);
+ }
+
+ if (yearInName.HasValue)
+ {
+ return yearInName.Value != item.ProductionYear.Value;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static IEnumerable<BaseItem> FilterForAdjacency(IEnumerable<BaseItem> items, string adjacentToId)
+ {
+ var list = items.ToList();
+
+ var adjacentToIdGuid = new Guid(adjacentToId);
+ var adjacentToItem = list.FirstOrDefault(i => i.Id == adjacentToIdGuid);
+
+ 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;
+ }
+
+ return list.Where(i => i.Id == previousId || i.Id == nextId || i.Id == adjacentToIdGuid);
+ }
}
}