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.cs1298
1 files changed, 1099 insertions, 199 deletions
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 587cfae95..166d56c51 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -1,9 +1,11 @@
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;
@@ -12,6 +14,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -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,9 +41,10 @@ namespace MediaBrowser.Controller.Entities
_logger = logger;
_userDataManager = userDataManager;
_tvSeriesManager = tvSeriesManager;
+ _collectionManager = collectionManager;
}
- public async Task<QueryResult<BaseItem>> GetUserItems(Folder parent, string viewType, UserItemsQuery query)
+ public async Task<QueryResult<BaseItem>> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query)
{
var user = query.User;
@@ -58,7 +63,7 @@ namespace MediaBrowser.Controller.Entities
return GetResult(result);
}
- case CollectionType.LiveTvChannels:
+ case SpecialFolder.LiveTvChannels:
{
var result = await _liveTvManager.GetInternalChannels(new LiveTvChannelQuery
{
@@ -71,7 +76,7 @@ namespace MediaBrowser.Controller.Entities
return GetResult(result);
}
- case CollectionType.LiveTvNowPlaying:
+ case SpecialFolder.LiveTvNowPlaying:
{
var result = await _liveTvManager.GetRecommendedProgramsInternal(new RecommendedProgramQuery
{
@@ -84,7 +89,7 @@ namespace MediaBrowser.Controller.Entities
return GetResult(result);
}
- case CollectionType.LiveTvRecordingGroups:
+ case SpecialFolder.LiveTvRecordingGroups:
{
var result = await _liveTvManager.GetInternalRecordings(new RecordingQuery
{
@@ -102,110 +107,125 @@ namespace MediaBrowser.Controller.Entities
{
var result = await GetLiveTvFolders(user).ConfigureAwait(false);
- return GetResult(result, query);
+ return GetResult(result, queryParent, query);
}
case CollectionType.Folders:
- return GetResult(user.RootFolder.GetChildren(user, true), query);
+ return GetResult(user.RootFolder.GetChildren(user, true), queryParent, query);
case CollectionType.Games:
- return await GetGameView(user, parent, query).ConfigureAwait(false);
+ return await GetGameView(user, queryParent, 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>(), queryParent, query);
case CollectionType.TvShows:
- return await GetTvView(parent, user, query).ConfigureAwait(false);
+ return await GetTvView(queryParent, user, query).ConfigureAwait(false);
case CollectionType.Music:
- return await GetMusicFolders(parent, user, query).ConfigureAwait(false);
+ return await GetMusicFolders(queryParent, user, query).ConfigureAwait(false);
case CollectionType.Movies:
- return await GetMovieFolders(parent, user, query).ConfigureAwait(false);
+ return await GetMovieFolders(queryParent, user, query).ConfigureAwait(false);
- case CollectionType.GameGenres:
- return GetGameGenres(parent, user, query);
+ case SpecialFolder.MusicGenres:
+ return await GetMusicGenres(queryParent, user, query).ConfigureAwait(false);
- case CollectionType.GameSystems:
- return GetGameSystems(parent, user, query);
+ case SpecialFolder.MusicGenre:
+ return await GetMusicGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
- case CollectionType.LatestGames:
- return GetLatestGames(parent, user, query);
+ case SpecialFolder.GameGenres:
+ return await GetGameGenres(queryParent, user, query).ConfigureAwait(false);
- case CollectionType.RecentlyPlayedGames:
- return GetRecentlyPlayedGames(parent, user, query);
+ case SpecialFolder.GameGenre:
+ return await GetGameGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
- case CollectionType.GameFavorites:
- return GetFavoriteGames(parent, user, query);
+ case SpecialFolder.GameSystems:
+ return GetGameSystems(queryParent, user, query);
- case CollectionType.TvShowSeries:
- return GetTvSeries(parent, user, query);
+ case SpecialFolder.LatestGames:
+ return GetLatestGames(queryParent, user, query);
- case CollectionType.TvGenres:
- return GetTvGenres(parent, user, query);
+ case SpecialFolder.RecentlyPlayedGames:
+ return GetRecentlyPlayedGames(queryParent, user, query);
- case CollectionType.TvResume:
- return GetTvResume(parent, user, query);
+ case SpecialFolder.GameFavorites:
+ return GetFavoriteGames(queryParent, user, query);
- case CollectionType.TvNextUp:
- return GetTvNextUp(parent, query);
+ case SpecialFolder.TvShowSeries:
+ return GetTvSeries(queryParent, user, query);
- case CollectionType.TvLatest:
- return GetTvLatest(parent, user, query);
+ case SpecialFolder.TvGenres:
+ return await GetTvGenres(queryParent, user, query).ConfigureAwait(false);
- case CollectionType.MovieFavorites:
- return GetFavoriteMovies(parent, user, query);
+ case SpecialFolder.TvGenre:
+ return await GetTvGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
- case CollectionType.MovieLatest:
- return GetMovieLatest(parent, user, query);
+ case SpecialFolder.TvResume:
+ return GetTvResume(queryParent, user, query);
- case CollectionType.MovieGenres:
- return GetMovieGenres(parent, user, query);
+ case SpecialFolder.TvNextUp:
+ return GetTvNextUp(queryParent, query);
- case CollectionType.MovieResume:
- return GetMovieResume(parent, user, query);
+ case SpecialFolder.TvLatest:
+ return GetTvLatest(queryParent, user, query);
- case CollectionType.MovieMovies:
- return GetMovieMovies(parent, user, query);
+ case SpecialFolder.MovieFavorites:
+ return GetFavoriteMovies(queryParent, user, query);
- case CollectionType.MovieCollections:
- return GetMovieCollections(parent, user, query);
+ case SpecialFolder.MovieLatest:
+ return GetMovieLatest(queryParent, user, query);
- case CollectionType.MusicLatest:
- return GetMusicLatest(parent, user, query);
+ case SpecialFolder.MovieGenres:
+ return await GetMovieGenres(queryParent, user, query).ConfigureAwait(false);
- case CollectionType.MusicAlbums:
- return GetMusicAlbums(parent, user, query);
+ case SpecialFolder.MovieGenre:
+ return await GetMovieGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
- case CollectionType.MusicAlbumArtists:
- return GetMusicAlbumArtists(parent, user, query);
+ case SpecialFolder.MovieResume:
+ return GetMovieResume(queryParent, user, query);
- case CollectionType.MusicArtists:
- return GetMusicArtists(parent, user, query);
+ case SpecialFolder.MovieMovies:
+ return GetMovieMovies(queryParent, user, query);
- case CollectionType.MusicSongs:
- return GetMusicSongs(parent, user, query);
+ case SpecialFolder.MovieCollections:
+ return GetMovieCollections(queryParent, user, query);
- case CollectionType.TvFavoriteEpisodes:
- return GetFavoriteEpisodes(parent, user, query);
+ case SpecialFolder.MusicLatest:
+ return GetMusicLatest(queryParent, user, query);
- case CollectionType.TvFavoriteSeries:
- return GetFavoriteSeries(parent, user, query);
+ case SpecialFolder.MusicAlbums:
+ return GetMusicAlbums(queryParent, user, query);
- case CollectionType.MusicFavorites:
- return await GetMusicFavorites(parent, user, query).ConfigureAwait(false);
+ case SpecialFolder.MusicAlbumArtists:
+ return GetMusicAlbumArtists(queryParent, user, query);
- case CollectionType.MusicFavoriteAlbums:
- return GetFavoriteAlbums(parent, user, query);
+ case SpecialFolder.MusicArtists:
+ return GetMusicArtists(queryParent, user, query);
- case CollectionType.MusicFavoriteArtists:
- return GetFavoriteArtists(parent, user, query);
+ case SpecialFolder.MusicSongs:
+ return GetMusicSongs(queryParent, user, query);
- case CollectionType.MusicFavoriteSongs:
- return GetFavoriteSongs(parent, user, query);
+ case SpecialFolder.TvFavoriteEpisodes:
+ return GetFavoriteEpisodes(queryParent, user, query);
+
+ case SpecialFolder.TvFavoriteSeries:
+ return GetFavoriteSeries(queryParent, user, query);
+
+ case SpecialFolder.MusicFavorites:
+ return await GetMusicFavorites(queryParent, user, query).ConfigureAwait(false);
+
+ case SpecialFolder.MusicFavoriteAlbums:
+ return GetFavoriteAlbums(queryParent, user, query);
+
+ case SpecialFolder.MusicFavoriteArtists:
+ return GetFavoriteArtists(queryParent, user, query);
+
+ case SpecialFolder.MusicFavoriteSongs:
+ return GetFavoriteSongs(queryParent, user, query);
default:
- return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), query);
+ return GetResult(GetMediaFolders(user).SelectMany(i => i.GetChildren(user, true)), queryParent, query);
}
}
@@ -214,44 +234,93 @@ namespace MediaBrowser.Controller.Entities
return 50;
}
- private async Task<QueryResult<BaseItem>> GetMusicFolders(Folder parent, User user, UserItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetMusicFolders(Folder parent, User user, InternalItemsQuery query)
{
if (query.Recursive)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }), query);
+ return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }), parent, query);
}
var list = new List<BaseItem>();
- var category = "music";
+ list.Add(await GetUserView(SpecialFolder.MusicLatest, user, "0", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicAlbums, user, "1", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicAlbumArtists, user, "2", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicArtists, user, "3", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicSongs, user, "4", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicGenres, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicFavorites, user, "6", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MusicLatest, user, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MusicAlbums, user, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MusicAlbumArtists, user, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MusicSongs, user, "3", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(CollectionType.MusicArtists, user, "3", parent).ConfigureAwait(false));
- //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, UserItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetMusicFavorites(Folder parent, User user, InternalItemsQuery query)
{
var list = new List<BaseItem>();
- var category = "music";
+ list.Add(await GetUserView(SpecialFolder.MusicFavoriteAlbums, user, "0", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicFavoriteArtists, user, "1", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MusicFavoriteSongs, user, "2", parent).ConfigureAwait(false));
+
+ return GetResult(list, parent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetMusicGenres(Folder parent, User user, InternalItemsQuery query)
+ {
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
+ .Where(i => !i.IsFolder)
+ .SelectMany(i => i.Genres)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .Select(i =>
+ {
+ try
+ {
+ return _libraryManager.GetMusicGenre(i);
+ }
+ catch
+ {
+ // Full exception logged at lower levels
+ _logger.Error("Error getting genre");
+ return null;
+ }
+
+ })
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
- list.Add(await GetUserView(category, CollectionType.MusicFavoriteAlbums, user, "0", parent).ConfigureAwait(false));
- 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(genres, parent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetMusicGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
+ .Where(i => !i.IsFolder)
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase))
+ .OfType<IHasAlbumArtist>()
+ .SelectMany(i => i.AlbumArtists)
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .Select(i =>
+ {
+ try
+ {
+ return _libraryManager.GetArtist(i);
+ }
+ catch
+ {
+ // Already logged at lower levels
+ return null;
+ }
+ })
+ .Where(i => i != null);
- return GetResult(list, query);
+ return GetResult(items, queryParent, query);
}
- private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
{
- var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music })
+ var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
.Where(i => !i.IsFolder)
.OfType<IHasAlbumArtist>()
.SelectMany(i => i.AlbumArtists)
@@ -270,12 +339,12 @@ 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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
{
- var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music })
+ var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
.Where(i => !i.IsFolder)
.OfType<IHasArtist>()
.SelectMany(i => i.Artists)
@@ -294,12 +363,12 @@ 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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
{
- var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music })
+ var artists = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
.Where(i => !i.IsFolder)
.OfType<IHasAlbumArtist>()
.SelectMany(i => i.AlbumArtists)
@@ -318,113 +387,111 @@ 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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMusicAlbums(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMusicSongs(Folder parent, User user, InternalItemsQuery query)
{
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMusicLatest(Folder parent, User user, InternalItemsQuery query)
{
query.SortBy = new[] { ItemSortBy.DateCreated, ItemSortBy.SortName };
query.SortOrder = SortOrder.Descending;
- return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.Music }).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, UserItemsQuery 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>();
- var category = "movies";
-
- list.Add(await GetUserView(category, CollectionType.MovieResume, user, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MovieLatest, user, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MovieMovies, user, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MovieCollections, user, "3", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.MovieFavorites, user, "4", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(CollectionType.MovieGenres, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieResume, user, "0", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieLatest, user, "1", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieMovies, user, "2", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieCollections, user, "3", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieFavorites, user, "4", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.MovieGenres, user, "5", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
- private QueryResult<BaseItem> GetFavoriteMovies(Folder parent, User user, UserItemsQuery 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, UserItemsQuery 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, UserItemsQuery 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, UserItemsQuery 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, UserItemsQuery 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, UserItemsQuery 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, UserItemsQuery 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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMovieLatest(Folder parent, User user, InternalItemsQuery query)
{
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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query)
{
query.SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName };
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, UserItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
{
- var genres = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty })
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty })
.Where(i => i is Movie)
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -442,86 +509,94 @@ namespace MediaBrowser.Controller.Entities
}
})
- .Where(i => i != null);
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ return GetResult(genres, parent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty })
+ .Where(i => i is Movie)
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase));
- return GetResult(genres, query);
+ return GetResult(items, queryParent, query);
}
- private async Task<QueryResult<BaseItem>> GetTvView(Folder parent, User user, UserItemsQuery 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>();
- var category = "tvshows";
-
- list.Add(await GetUserView(category, CollectionType.TvResume, user, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.TvNextUp, user, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.TvLatest, user, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.TvShowSeries, user, "3", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.TvFavoriteSeries, user, "4", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.TvFavoriteEpisodes, user, "5", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(CollectionType.TvGenres, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvResume, user, "0", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvNextUp, user, "1", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvLatest, user, "2", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvShowSeries, user, "3", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvFavoriteSeries, user, "4", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvFavoriteEpisodes, user, "5", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.TvGenres, user, "6", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
- private async Task<QueryResult<BaseItem>> GetGameView(User user, Folder parent, UserItemsQuery 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>();
- var category = "games";
-
- list.Add(await GetUserView(category, CollectionType.LatestGames, user, "0", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.RecentlyPlayedGames, user, "1", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.GameFavorites, user, "2", parent).ConfigureAwait(false));
- list.Add(await GetUserView(category, CollectionType.GameSystems, user, "3", parent).ConfigureAwait(false));
- //list.Add(await GetUserView(CollectionType.GameGenres, user, "4", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.LatestGames, user, "0", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.RecentlyPlayedGames, user, "1", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.GameFavorites, user, "2", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.GameSystems, user, "3", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.GameGenres, user, "4", parent).ConfigureAwait(false));
- return GetResult(list, query);
+ return GetResult(list, parent, query);
}
- private QueryResult<BaseItem> GetLatestGames(Folder parent, User user, UserItemsQuery query)
+ private QueryResult<BaseItem> GetLatestGames(Folder parent, User user, InternalItemsQuery query)
{
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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetRecentlyPlayedGames(Folder parent, User user, InternalItemsQuery query)
{
query.IsPlayed = true;
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, UserItemsQuery 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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetTvLatest(Folder parent, User user, InternalItemsQuery query)
{
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, UserItemsQuery query)
+ private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
{
var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows, string.Empty });
@@ -536,23 +611,23 @@ namespace MediaBrowser.Controller.Entities
return result;
}
- private QueryResult<BaseItem> GetTvResume(Folder parent, User user, UserItemsQuery query)
+ private QueryResult<BaseItem> GetTvResume(Folder parent, User user, InternalItemsQuery query)
{
query.SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.SortName };
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, UserItemsQuery 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, UserItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
{
- var genres = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty })
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty })
.OfType<Series>()
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -570,19 +645,40 @@ namespace MediaBrowser.Controller.Entities
}
})
- .Where(i => i != null);
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ return GetResult(genres, parent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
+ {
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.TvShows, string.Empty })
+ .Where(i => i is Series)
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase));
- return GetResult(genres, query);
+ return GetResult(items, queryParent, query);
}
- private QueryResult<BaseItem> GetGameSystems(Folder parent, User user, UserItemsQuery 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, UserItemsQuery query)
+ private async Task<QueryResult<BaseItem>> GetGameGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
{
- var genres = GetRecursiveChildren(parent, user, new[] { CollectionType.Games })
+ var items = GetRecursiveChildren(queryParent, user, new[] { CollectionType.Games })
+ .OfType<Game>()
+ .Where(i => i.Genres.Contains(displayParent.Name, StringComparer.OrdinalIgnoreCase));
+
+ return GetResult(items, queryParent, query);
+ }
+
+ private async Task<QueryResult<BaseItem>> GetGameGenres(Folder parent, User user, InternalItemsQuery query)
+ {
+ var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Games })
.OfType<Game>()
.SelectMany(i => i.Genres)
.Distinct(StringComparer.OrdinalIgnoreCase)
@@ -600,9 +696,12 @@ namespace MediaBrowser.Controller.Entities
}
})
- .Where(i => i != null);
+ .Where(i => i != null)
+ .Select(i => GetUserView(i.Name, SpecialFolder.GameGenre, user, i.SortName, parent));
+
+ var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
- return GetResult(genres, query);
+ return GetResult(genres, parent, query);
}
private QueryResult<BaseItem> GetResult<T>(QueryResult<T> result)
@@ -616,36 +715,401 @@ namespace MediaBrowser.Controller.Entities
}
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
- UserItemsQuery query)
+ BaseItem queryParent,
+ InternalItemsQuery query)
where T : BaseItem
{
- return GetResult(items, null, query);
+ return GetResult(items, queryParent, null, query);
}
private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items,
+ BaseItem queryParent,
int? totalRecordLimit,
- UserItemsQuery query)
+ InternalItemsQuery query)
where T : BaseItem
{
- return SortAndFilter(items, totalRecordLimit, query, _libraryManager, _userDataManager);
+ return SortAndFilter(items, queryParent, totalRecordLimit, query, _libraryManager, _userDataManager);
}
public static QueryResult<BaseItem> SortAndFilter(IEnumerable<BaseItem> items,
+ BaseItem queryParent,
int? totalRecordLimit,
- UserItemsQuery query,
+ InternalItemsQuery query,
ILibraryManager libraryManager,
IUserDataManager userDataManager)
{
var user = query.User;
- items = items.Where(i => Filter(i, user, query, userDataManager));
+ items = items.Where(i => Filter(i, user, query, userDataManager, libraryManager));
+
+ items = FilterVirtualEpisodes(items,
+ query.IsMissing,
+ query.IsVirtualUnaired,
+ query.IsUnaired);
+
+ items = CollapseBoxSetItemsIfNeeded(items, query, queryParent, 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 queryParent,
+ User user)
+ {
+ if (CollapseBoxSetItems(query, queryParent, 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 queryParent,
+ User user)
+ {
+ // Could end up stuck in a loop like this
+ if (queryParent 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;
+ }
+
+ if (request.Tags.Length > 0)
+ {
+ return false;
+ }
+
+ if (request.OfficialRatings.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,
- UserItemsQuery query,
+ InternalItemsQuery query,
ILibraryManager libraryManager)
{
var user = query.User;
@@ -676,13 +1140,23 @@ namespace MediaBrowser.Controller.Entities
};
}
- private static bool Filter(BaseItem item, User user, UserItemsQuery query, IUserDataManager userDataManager)
+ private static bool Filter(BaseItem item, User user, InternalItemsQuery query, IUserDataManager userDataManager, ILibraryManager libraryManager)
{
if (query.MediaTypes.Length > 0 && !query.MediaTypes.Contains(item.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase))
{
return false;
}
+ if (query.IncludeItemTypes.Length > 0 && !query.IncludeItemTypes.Contains(item.GetClientTypeName(), StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ if (query.ExcludeItemTypes.Length > 0 && query.ExcludeItemTypes.Contains(item.GetClientTypeName(), StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
if (query.IsFolder.HasValue && query.IsFolder.Value != item.IsFolder)
{
return false;
@@ -695,6 +1169,27 @@ namespace MediaBrowser.Controller.Entities
UserItemData userData = null;
+ if (query.IsLiked.HasValue)
+ {
+ userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+
+ if (!userData.Likes.HasValue || userData.Likes != query.IsLiked.Value)
+ {
+ return false;
+ }
+ }
+
+ if (query.IsFavoriteOrLiked.HasValue)
+ {
+ userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
+ var isFavoriteOrLiked = userData.IsFavorite || (userData.Likes ?? false);
+
+ if (isFavoriteOrLiked != query.IsFavoriteOrLiked.Value)
+ {
+ return false;
+ }
+ }
+
if (query.IsFavorite.HasValue)
{
userData = userData ?? userDataManager.GetUserData(user.Id, item.GetUserDataKey());
@@ -724,6 +1219,355 @@ 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, libraryManager) != 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.GetTrailerIds().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 official rating filter
+ if (query.OfficialRatings.Length > 0 && !query.OfficialRatings.Contains(item.OfficialRating ?? string.Empty))
+ {
+ 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;
+ }
+ }
+ }
+
+ // Apply tag filter
+ var tags = query.Tags;
+ if (tags.Length > 0)
+ {
+ var hasTags = item as IHasTags;
+ if (hasTags == null)
+ {
+ return false;
+ }
+ if (!(tags.Any(v => hasTags.Tags.Contains(v, StringComparer.OrdinalIgnoreCase))))
+ {
+ return false;
+ }
+ }
+
return true;
}
@@ -737,7 +1581,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 =>
@@ -748,7 +1592,7 @@ namespace MediaBrowser.Controller.Entities
});
}
- private IEnumerable<Folder> GetMediaFolders(Folder parent, User user, string[] viewTypes)
+ private IEnumerable<Folder> GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes)
{
if (parent == null || parent is UserView)
{
@@ -758,7 +1602,7 @@ namespace MediaBrowser.Controller.Entities
return new[] { parent };
}
- private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, string[] viewTypes)
+ private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, IEnumerable<string> viewTypes)
{
if (parent == null || parent is UserView)
{
@@ -772,26 +1616,82 @@ namespace MediaBrowser.Controller.Entities
{
var list = new List<BaseItem>();
- list.Add(await _userViewManager.GetUserView("livetv", CollectionType.LiveTvNowPlaying, user, "0", CancellationToken.None).ConfigureAwait(false));
- list.Add(await _userViewManager.GetUserView("livetv", CollectionType.LiveTvChannels, user, string.Empty, CancellationToken.None).ConfigureAwait(false));
- list.Add(await _userViewManager.GetUserView("livetv", CollectionType.LiveTvRecordingGroups, user, string.Empty, CancellationToken.None).ConfigureAwait(false));
+ var parent = user.RootFolder;
+
+ //list.Add(await GetUserView(SpecialFolder.LiveTvNowPlaying, user, "0", parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.LiveTvChannels, user, string.Empty, parent).ConfigureAwait(false));
+ list.Add(await GetUserView(SpecialFolder.LiveTvRecordingGroups, user, string.Empty, parent).ConfigureAwait(false));
return list;
}
- private async Task<UserView> GetUserView(string category, string type, User user, string sortName, Folder parent)
+ private async Task<UserView> GetUserView(string name, string type, User user, string sortName, BaseItem parent)
{
- var view = await _userViewManager.GetUserView(category, type, user, sortName, CancellationToken.None)
+ var view = await _userViewManager.GetUserView(name, parent.Id.ToString("N"), type, user, sortName, CancellationToken.None)
.ConfigureAwait(false);
- if (parent.Id != view.ParentId)
- {
- view.ParentId = parent.Id;
- await view.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None)
+ return view;
+ }
+
+ private async Task<UserView> GetUserView(string type, User user, string sortName, BaseItem parent)
+ {
+ var view = await _userViewManager.GetUserView(parent.Id.ToString("N"), type, user, sortName, CancellationToken.None)
.ConfigureAwait(false);
- }
return view;
}
+
+ public static bool IsYearMismatched(BaseItem item, ILibraryManager libraryManager)
+ {
+ if (item.ProductionYear.HasValue)
+ {
+ var path = item.Path;
+
+ if (!string.IsNullOrEmpty(path))
+ {
+ var info = libraryManager.ParseName(Path.GetFileName(path));
+ var yearInName = info.Year;
+
+ // Go up a level if we didn't get a year
+ if (!yearInName.HasValue)
+ {
+ info = libraryManager.ParseName(Path.GetFileName(Path.GetDirectoryName(path)));
+ yearInName = info.Year;
+ }
+
+ 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);
+ }
}
}