diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2015-01-25 01:34:50 -0500 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2015-01-25 01:34:50 -0500 |
| commit | a1a56557ece84d8b726a6c06b2620fa43ff22461 (patch) | |
| tree | a9b96eccbe5fd08c34174f5c5cff8e01ac822fea | |
| parent | 67559378009062a26173888ad457d0c9116bfc9a (diff) | |
sync updates
67 files changed, 568 insertions, 432 deletions
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 2aaec8627..dff433c9d 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -174,7 +174,7 @@ namespace MediaBrowser.Api return libraryManager.GetPerson(DeSlugPersonName(name, libraryManager)); } - protected IEnumerable<BaseItem> GetAllLibraryItems(Guid? userId, IUserManager userManager, ILibraryManager libraryManager, string parentId = null) + protected IList<BaseItem> GetAllLibraryItems(Guid? userId, IUserManager userManager, ILibraryManager libraryManager, string parentId, Func<BaseItem,bool> filter) { if (!string.IsNullOrEmpty(parentId)) { @@ -189,10 +189,13 @@ namespace MediaBrowser.Api throw new ArgumentException("User not found"); } - return folder.GetRecursiveChildren(user); + return folder + .GetRecursiveChildren(user, filter) + .ToList(); } - return folder.GetRecursiveChildren(); + return folder + .GetRecursiveChildren(filter); } if (userId.HasValue) { @@ -203,10 +206,16 @@ namespace MediaBrowser.Api throw new ArgumentException("User not found"); } - return userManager.GetUserById(userId.Value).RootFolder.GetRecursiveChildren(user); + return userManager + .GetUserById(userId.Value) + .RootFolder + .GetRecursiveChildren(user, filter) + .ToList(); } - return libraryManager.RootFolder.GetRecursiveChildren(); + return libraryManager + .RootFolder + .GetRecursiveChildren(filter); } /// <summary> @@ -222,8 +231,9 @@ namespace MediaBrowser.Api return name; } - return libraryManager.RootFolder.RecursiveChildren - .OfType<Audio>() + return libraryManager.RootFolder + .GetRecursiveChildren(i => i is IHasArtist) + .Cast<IHasArtist>() .SelectMany(i => i.AllArtists) .Distinct(StringComparer.OrdinalIgnoreCase) .FirstOrDefault(i => @@ -264,8 +274,8 @@ namespace MediaBrowser.Api return name; } - return libraryManager.RootFolder.GetRecursiveChildren() - .OfType<Game>() + return libraryManager.RootFolder + .GetRecursiveChildren(i => i is Game) .SelectMany(i => i.Genres) .Distinct(StringComparer.OrdinalIgnoreCase) .FirstOrDefault(i => @@ -287,7 +297,8 @@ namespace MediaBrowser.Api return name; } - return libraryManager.RootFolder.GetRecursiveChildren() + return libraryManager.RootFolder + .GetRecursiveChildren() .SelectMany(i => i.Studios) .Distinct(StringComparer.OrdinalIgnoreCase) .FirstOrDefault(i => @@ -309,7 +320,8 @@ namespace MediaBrowser.Api return name; } - return libraryManager.RootFolder.GetRecursiveChildren() + return libraryManager.RootFolder + .GetRecursiveChildren() .SelectMany(i => i.People) .Select(i => i.Name) .Distinct(StringComparer.OrdinalIgnoreCase) diff --git a/MediaBrowser.Api/GamesService.cs b/MediaBrowser.Api/GamesService.cs index 39e357f49..c18c32920 100644 --- a/MediaBrowser.Api/GamesService.cs +++ b/MediaBrowser.Api/GamesService.cs @@ -102,8 +102,8 @@ namespace MediaBrowser.Api /// <returns>System.Object.</returns> public object Get(GetGameSystemSummaries request) { - var gameSystems = GetAllLibraryItems(request.UserId, _userManager, _libraryManager) - .OfType<GameSystem>() + var gameSystems = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, i => i is GameSystem) + .Cast<GameSystem>() .ToList(); var user = request.UserId == null ? null : _userManager.GetUserById(request.UserId.Value); @@ -119,9 +119,8 @@ namespace MediaBrowser.Api public object Get(GetPlayerIndex request) { - var games = GetAllLibraryItems(request.UserId, _userManager, _libraryManager) - .OfType<Game>() - .ToList(); + var games = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, i => i is Game) + .Cast<Game>(); var lookup = games .ToLookup(i => i.PlayersSupported ?? -1) @@ -150,9 +149,11 @@ namespace MediaBrowser.Api DisplayName = system.Name }; - var items = user == null ? system.RecursiveChildren : system.GetRecursiveChildren(user); + var items = user == null ? + system.GetRecursiveChildren(i => i is Game) : + system.GetRecursiveChildren(user, i => i is Game); - var games = items.OfType<Game>().ToList(); + var games = items.Cast<Game>().ToList(); summary.ClientInstalledGameCount = games.Count(i => i.IsPlaceHolder); diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index 152a64c24..78bc14ab0 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -51,7 +51,7 @@ namespace MediaBrowser.Api var cancellationToken = CancellationToken.None; var albums = _libraryManager.RootFolder - .RecursiveChildren + .GetRecursiveChildren() .OfType<MusicAlbum>() .Where(i => i.HasArtist(item.Name)) .ToList(); diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 98c259825..ea90afc3b 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -215,7 +215,7 @@ namespace MediaBrowser.Api { var folder = (Folder)item; - foreach (var child in folder.RecursiveChildren.ToList()) + foreach (var child in folder.GetRecursiveChildren()) { child.IsLocked = newLockData; await child.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index bac6f6a39..f147234fe 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -392,52 +392,43 @@ namespace MediaBrowser.Api.Library /// <returns>System.Object.</returns> public object Get(GetItemCounts request) { - var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager) - .Where(i => i.LocationType != LocationType.Virtual) - .ToList(); - - var filteredItems = request.UserId.HasValue ? FilterItems(items, request, request.UserId.Value).ToList() : items; - - var albums = filteredItems.OfType<MusicAlbum>().ToList(); - var episodes = filteredItems.OfType<Episode>().ToList(); - var games = filteredItems.OfType<Game>().ToList(); - var movies = filteredItems.OfType<Movie>().ToList(); - var musicVideos = filteredItems.OfType<MusicVideo>().ToList(); - var boxsets = filteredItems.OfType<BoxSet>().ToList(); - var books = filteredItems.OfType<Book>().ToList(); - var songs = filteredItems.OfType<Audio>().ToList(); - var series = filteredItems.OfType<Series>().ToList(); + var filteredItems = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, i => i.LocationType != LocationType.Virtual && FilterItem(i, request, request.UserId)); var counts = new ItemCounts { - AlbumCount = albums.Count, - EpisodeCount = episodes.Count, - GameCount = games.Count, - GameSystemCount = filteredItems.OfType<GameSystem>().Count(), - MovieCount = movies.Count, - SeriesCount = series.Count, - SongCount = songs.Count, - MusicVideoCount = musicVideos.Count, - BoxSetCount = boxsets.Count, - BookCount = books.Count, - - UniqueTypes = items.Select(i => i.GetClientTypeName()).Distinct().ToList() + AlbumCount = filteredItems.Count(i => i is MusicAlbum), + EpisodeCount = filteredItems.Count(i => i is Episode), + GameCount = filteredItems.Count(i => i is Game), + GameSystemCount = filteredItems.Count(i => i is GameSystem), + MovieCount = filteredItems.Count(i => i is Movie), + SeriesCount = filteredItems.Count(i => i is Series), + SongCount = filteredItems.Count(i => i is Audio), + MusicVideoCount = filteredItems.Count(i => i is MusicVideo), + BoxSetCount = filteredItems.Count(i => i is BoxSet), + BookCount = filteredItems.Count(i => i is Book), + + UniqueTypes = filteredItems.Select(i => i.GetClientTypeName()).Distinct().ToList() }; return ToOptimizedSerializedResultUsingCache(counts); } - private IEnumerable<T> FilterItems<T>(IEnumerable<T> items, GetItemCounts request, Guid userId) - where T : BaseItem + private bool FilterItem(BaseItem item, GetItemCounts request, Guid? userId) { - if (request.IsFavorite.HasValue) + if (userId.HasValue) { - var val = request.IsFavorite.Value; + if (request.IsFavorite.HasValue) + { + var val = request.IsFavorite.Value; - items = items.Where(i => _userDataManager.GetUserData(userId, i.GetUserDataKey()).IsFavorite == val); + if (_userDataManager.GetUserData(userId.Value, item.GetUserDataKey()).IsFavorite != val) + { + return false; + } + } } - return items; + return true; } /// <summary> @@ -711,13 +702,24 @@ namespace MediaBrowser.Api.Library public object Get(GetYearIndex request) { - IEnumerable<BaseItem> items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager); + var includeTypes = string.IsNullOrWhiteSpace(request.IncludeItemTypes) + ? new string[] { } + : request.IncludeItemTypes.Split(','); - if (!string.IsNullOrEmpty(request.IncludeItemTypes)) + Func<BaseItem, bool> filter = i => { - var vals = request.IncludeItemTypes.Split(','); - items = items.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)); - } + if (includeTypes.Length > 0) + { + if (!includeTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + + return true; + }; + + IEnumerable<BaseItem> items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, null, filter); var lookup = items .ToLookup(i => i.ProductionYear ?? -1) @@ -747,8 +749,7 @@ namespace MediaBrowser.Api.Library var dtos = GetSoundtrackSongIds(item, inheritFromParent) .Select(_libraryManager.GetItemById) .OfType<MusicAlbum>() - .SelectMany(i => i.RecursiveChildren) - .OfType<Audio>() + .SelectMany(i => i.GetRecursiveChildren(a => a is Audio)) .OrderBy(i => i.SortName) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 0b8bb4036..07f5942c6 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -121,8 +121,7 @@ namespace MediaBrowser.Api.Movies { var user = _userManager.GetUserById(request.UserId.Value); - var movies = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId) - .Where(i => i is Movie); + IEnumerable<BaseItem> movies = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Movie); movies = _libraryManager.ReplaceVideosWithPrimaryVersions(movies); @@ -174,11 +173,11 @@ namespace MediaBrowser.Api.Movies (request.UserId.HasValue ? user.RootFolder : _libraryManager.RootFolder) : _libraryManager.GetItemById(request.Id); + Func<BaseItem, bool> filter = i => i.Id != item.Id && includeInSearch(i); + var inputItems = user == null - ? _libraryManager.RootFolder.GetRecursiveChildren().Where(i => i.Id != item.Id) - : user.RootFolder.GetRecursiveChildren(user).Where(i => i.Id != item.Id); - - inputItems = inputItems.Where(includeInSearch); + ? _libraryManager.RootFolder.GetRecursiveChildren(filter) + : user.RootFolder.GetRecursiveChildren(user, filter); var list = inputItems.ToList(); diff --git a/MediaBrowser.Api/Music/AlbumsService.cs b/MediaBrowser.Api/Music/AlbumsService.cs index 4cfb3c7d4..76c6c5776 100644 --- a/MediaBrowser.Api/Music/AlbumsService.cs +++ b/MediaBrowser.Api/Music/AlbumsService.cs @@ -77,14 +77,14 @@ namespace MediaBrowser.Api.Music var album1 = (MusicAlbum)item1; var album2 = (MusicAlbum)item2; - var artists1 = album1.GetRecursiveChildren() - .OfType<Audio>() + var artists1 = album1.GetRecursiveChildren(i => i is IHasArtist) + .Cast<IHasArtist>() .SelectMany(i => i.AllArtists) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); - var artists2 = album2.GetRecursiveChildren() - .OfType<Audio>() + var artists2 = album2.GetRecursiveChildren(i => i is IHasArtist) + .Cast<IHasArtist>() .SelectMany(i => i.AllArtists) .Distinct(StringComparer.OrdinalIgnoreCase) .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index 61c7305b5..4dcf72407 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -194,21 +194,23 @@ namespace MediaBrowser.Api { result.Series = season.Series.Name; - result.EpisodeCount = season.GetRecursiveChildren().Count(i => i is Episode); + result.EpisodeCount = season.GetRecursiveChildren(i => i is Episode).Count; } var series = item as Series; if (series != null) { - result.EpisodeCount = series.GetRecursiveChildren().Count(i => i is Episode); + result.EpisodeCount = series.GetRecursiveChildren(i => i is Episode).Count; } var album = item as MusicAlbum; if (album != null) { - var songs = album.GetRecursiveChildren().OfType<Audio>().ToList(); + var songs = album.GetRecursiveChildren(i => i is Audio) + .Cast<Audio>() + .ToList(); result.SongCount = songs.Count; diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index 150aebf50..e061c391a 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -76,13 +76,13 @@ namespace MediaBrowser.Api (request.UserId.HasValue ? user.RootFolder : libraryManager.RootFolder) : libraryManager.GetItemById(request.Id); - var fields = request.GetItemFields().ToList(); + Func<BaseItem, bool> filter = i => i.Id != item.Id && includeInSearch(i); var inputItems = user == null - ? libraryManager.RootFolder.GetRecursiveChildren().Where(i => i.Id != item.Id) - : user.RootFolder.GetRecursiveChildren(user).Where(i => i.Id != item.Id); + ? libraryManager.RootFolder.GetRecursiveChildren(filter) + : user.RootFolder.GetRecursiveChildren(user, filter); - var items = GetSimilaritems(item, inputItems.Where(includeInSearch), getSimilarityScore) + var items = GetSimilaritems(item, inputItems, getSimilarityScore) .ToList(); IEnumerable<BaseItem> returnItems = items; @@ -165,7 +165,7 @@ namespace MediaBrowser.Api // Find common keywords points += GetKeywords(item1).Where(i => GetKeywords(item2).Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 10); - + // Find common studios points += item1.Studios.Where(i => item2.Studios.Contains(i, StringComparer.OrdinalIgnoreCase)).Sum(i => 3); diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs index 79db6cbe5..ccb844912 100644 --- a/MediaBrowser.Api/TvShowsService.cs +++ b/MediaBrowser.Api/TvShowsService.cs @@ -256,10 +256,10 @@ namespace MediaBrowser.Api { var user = _userManager.GetUserById(request.UserId); - var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId) - .OfType<Episode>(); + var items = GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, i => i is Episode); - var itemsList = _libraryManager.Sort(items, user, new[] { "PremiereDate", "AirTime", "SortName" }, SortOrder.Ascending) + var itemsList = _libraryManager + .Sort(items, user, new[] { "PremiereDate", "AirTime", "SortName" }, SortOrder.Ascending) .Cast<Episode>() .ToList(); @@ -450,24 +450,25 @@ namespace MediaBrowser.Api episodes = episodes.Where(i => i.IsVirtualUnaired == val); } + IEnumerable<BaseItem> returnItems = episodes; + // This must be the last filter if (!string.IsNullOrEmpty(request.AdjacentTo)) { - episodes = UserViewBuilder.FilterForAdjacency(episodes, request.AdjacentTo) - .Cast<Episode>(); + returnItems = UserViewBuilder.FilterForAdjacency(returnItems, request.AdjacentTo); } - episodes = _libraryManager.ReplaceVideosWithPrimaryVersions(episodes).Cast<Episode>(); + returnItems = _libraryManager.ReplaceVideosWithPrimaryVersions(returnItems); var dtoOptions = GetDtoOptions(request); - var returnItems = _dtoService.GetBaseItemDtos(episodes, dtoOptions, user) + var dtos = _dtoService.GetBaseItemDtos(returnItems, dtoOptions, user) .ToArray(); return new ItemsResult { - TotalRecordCount = returnItems.Length, - Items = returnItems + TotalRecordCount = dtos.Length, + Items = dtos }; } } diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index e0747b547..880d57b9a 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -56,46 +56,52 @@ namespace MediaBrowser.Api.UserLibrary protected ItemsResult GetResult(GetItemsByName request) { User user = null; - BaseItem item; + BaseItem parentItem; List<BaseItem> libraryItems; if (request.UserId.HasValue) { user = UserManager.GetUserById(request.UserId.Value); - item = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId); - + parentItem = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId); libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList(); } else { - item = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId); - - libraryItems = LibraryManager.RootFolder.RecursiveChildren.ToList(); + parentItem = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId); + libraryItems = LibraryManager.RootFolder.GetRecursiveChildren().ToList(); } IEnumerable<BaseItem> items; - if (item.IsFolder) + var excludeItemTypes = request.GetExcludeItemTypes(); + var includeItemTypes = request.GetIncludeItemTypes(); + var mediaTypes = request.GetMediaTypes(); + + Func<BaseItem, bool> filter = i => FilterItem(request, i, excludeItemTypes, includeItemTypes, mediaTypes); + + if (parentItem.IsFolder) { - var folder = (Folder)item; + var folder = (Folder)parentItem; if (request.UserId.HasValue) { - items = request.Recursive ? folder.GetRecursiveChildren(user) : folder.GetChildren(user, true); + items = request.Recursive ? + folder.GetRecursiveChildren(user, filter) : + folder.GetChildren(user, true).Where(filter); } else { - items = request.Recursive ? folder.GetRecursiveChildren() : folder.Children; + items = request.Recursive ? + folder.GetRecursiveChildren(filter) : + folder.Children.Where(filter); } } else { - items = new[] { item }; + items = new[] { parentItem }.Where(filter); } - items = FilterItems(request, items); - var extractedItems = GetAllItems(request, items); var filteredItems = FilterItems(request, extractedItems, user); @@ -290,33 +296,41 @@ namespace MediaBrowser.Api.UserLibrary /// Filters the items. /// </summary> /// <param name="request">The request.</param> - /// <param name="items">The items.</param> + /// <param name="f">The f.</param> + /// <param name="excludeItemTypes">The exclude item types.</param> + /// <param name="includeItemTypes">The include item types.</param> + /// <param name="mediaTypes">The media types.</param> /// <returns>IEnumerable{BaseItem}.</returns> - protected virtual IEnumerable<BaseItem> FilterItems(GetItemsByName request, IEnumerable<BaseItem> items) + protected bool FilterItem(GetItemsByName request, BaseItem f, string[] excludeItemTypes, string[] includeItemTypes, string[] mediaTypes) { // Exclude item types - if (!string.IsNullOrEmpty(request.ExcludeItemTypes)) + if (excludeItemTypes.Length > 0) { - var vals = request.ExcludeItemTypes.Split(','); - items = items.Where(f => !vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)); + if (excludeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } } // Include item types - if (!string.IsNullOrEmpty(request.IncludeItemTypes)) + if (includeItemTypes.Length > 0) { - var vals = request.IncludeItemTypes.Split(','); - items = items.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)); + if (!includeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } } // Include MediaTypes - if (!string.IsNullOrEmpty(request.MediaTypes)) + if (mediaTypes.Length > 0) { - var vals = request.MediaTypes.Split(','); - - items = items.Where(f => vals.Contains(f.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase)); + if (!mediaTypes.Contains(f.MediaType ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + return false; + } } - return items; + return true; } /// <summary> diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 6f6bd2dff..15b1f6dba 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -398,7 +398,7 @@ namespace MediaBrowser.Api.UserLibrary { if (user == null) { - items = ((Folder)item).RecursiveChildren; + items = ((Folder)item).GetRecursiveChildren(); items = _libraryManager.ReplaceVideosWithPrimaryVersions(items); } @@ -464,7 +464,7 @@ namespace MediaBrowser.Api.UserLibrary SortBy = request.GetOrderBy(), SortOrder = request.SortOrder ?? SortOrder.Ascending, - Filter = (i, u) => ApplyAdditionalFilters(request, i, u, true, _libraryManager), + Filter = i => ApplyAdditionalFilters(request, i, user, true, _libraryManager), Limit = request.Limit, StartIndex = request.StartIndex, diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 3fc42c6b1..c6ec53018 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -259,7 +259,7 @@ namespace MediaBrowser.Api.UserLibrary [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string EnableImageTypes { get; set; } - + public GetLatestMedia() { Limit = 20; @@ -304,36 +304,45 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(request.UserId); - // Avoid implicitly captured closure - var libraryItems = string.IsNullOrEmpty(request.ParentId) && user != null ? - GetItemsConfiguredForLatest(user) : - GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId); + var includeTypes = string.IsNullOrWhiteSpace(request.IncludeItemTypes) + ? new string[] { } + : request.IncludeItemTypes.Split(','); - libraryItems = libraryItems.OrderByDescending(i => i.DateCreated) - .Where(i => i.LocationType != LocationType.Virtual); + var currentUser = user; + + Func<BaseItem, bool> filter = i => + { + if (includeTypes.Length > 0) + { + if (!includeTypes.Contains(i.GetType().Name, StringComparer.OrdinalIgnoreCase)) + { + return false; + } + } + if (request.IsPlayed.HasValue) + { + var val = request.IsPlayed.Value; + if (i.IsPlayed(currentUser) != val) + { + return false; + } + } - //if (request.IsFolder.HasValue) - //{ - //var val = request.IsFolder.Value; - libraryItems = libraryItems.Where(f => f.IsFolder == false); - //} + return i.LocationType != LocationType.Virtual && !i.IsFolder; + }; - if (!string.IsNullOrEmpty(request.IncludeItemTypes)) - { - var vals = request.IncludeItemTypes.Split(','); - libraryItems = libraryItems.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)); - } + // Avoid implicitly captured closure + var libraryItems = string.IsNullOrEmpty(request.ParentId) && user != null ? + GetItemsConfiguredForLatest(user, filter) : + GetAllLibraryItems(request.UserId, _userManager, _libraryManager, request.ParentId, filter); - var currentUser = user; + libraryItems = libraryItems.OrderByDescending(i => i.DateCreated); if (request.IsPlayed.HasValue) { var takeLimit = request.Limit * 20; - - var val = request.IsPlayed.Value; - libraryItems = libraryItems.Where(f => f.IsPlayed(currentUser) == val) - .Take(takeLimit); + libraryItems = libraryItems.Take(takeLimit); } // Avoid implicitly captured closure @@ -394,12 +403,15 @@ namespace MediaBrowser.Api.UserLibrary return ToOptimizedResult(dtos.ToList()); } - private IEnumerable<BaseItem> GetItemsConfiguredForLatest(User user) + private IEnumerable<BaseItem> GetItemsConfiguredForLatest(User user, Func<BaseItem,bool> filter) { + // Avoid implicitly captured closure + var currentUser = user; + return user.RootFolder.GetChildren(user, true) .OfType<Folder>() .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N"))) - .SelectMany(i => i.GetRecursiveChildren(user)) + .SelectMany(i => i.GetRecursiveChildren(currentUser, filter)) .DistinctBy(i => i.Id); } @@ -453,8 +465,7 @@ namespace MediaBrowser.Api.UserLibrary var currentUser = user; var dtos = series - .GetRecursiveChildren() - .Where(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0) + .GetRecursiveChildren(i => i is Episode && i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == 0) .OrderBy(i => { if (i.PremiereDate.HasValue) diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs index 7974657d9..00a7e8b67 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs @@ -68,7 +68,7 @@ namespace MediaBrowser.Controller.Entities.Audio { get { - return RecursiveChildren.OfType<Audio>(); + return GetRecursiveChildren(i => i is Audio).Cast<Audio>(); } } @@ -173,7 +173,8 @@ namespace MediaBrowser.Controller.Entities.Audio id.ArtistProviderIds = artist.ProviderIds; } - id.SongInfos = RecursiveChildren.OfType<Audio>() + id.SongInfos = GetRecursiveChildren(i => i is Audio) + .Cast<Audio>() .Select(i => i.GetLookupInfo()) .ToList(); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 45476d6a6..5cca91202 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Entities.Audio { public bool IsAccessedByName { get; set; } public List<string> ProductionLocations { get; set; } - + public override bool IsFolder { get @@ -122,7 +122,7 @@ namespace MediaBrowser.Controller.Entities.Audio public async Task RefreshAllMetadata(MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken) { - var items = RecursiveChildren.ToList(); + var items = GetRecursiveChildren().ToList(); var songs = items.OfType<Audio>().ToList(); @@ -169,7 +169,7 @@ namespace MediaBrowser.Controller.Entities.Audio // Refresh current item await RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); - + // Refresh all non-songs foreach (var item in others) { @@ -204,7 +204,8 @@ namespace MediaBrowser.Controller.Entities.Audio { var info = GetItemLookupInfo<ArtistInfo>(); - info.SongInfos = RecursiveChildren.OfType<Audio>() + info.SongInfos = GetRecursiveChildren(i => i is Audio) + .Cast<Audio>() .Select(i => i.GetLookupInfo()) .ToList(); @@ -213,9 +214,19 @@ namespace MediaBrowser.Controller.Entities.Audio public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) { - return inputItems.OfType<IHasArtist>() - .Where(i => i.HasArtist(Name)) - .Cast<BaseItem>(); + return inputItems.Where(ItemFilter); + } + + public Func<BaseItem, bool> ItemFilter + { + get + { + return i => + { + var hasArtist = i as IHasArtist; + return hasArtist != null && hasArtist.HasArtist(Name); + }; + } } } } diff --git a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs index ad2d39c79..b2c2a1b48 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicGenre.cs @@ -52,7 +52,13 @@ namespace MediaBrowser.Controller.Entities.Audio public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) { - return inputItems.Where(i => (i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase)); + return inputItems.Where(ItemFilter); + } + + + public Func<BaseItem, bool> ItemFilter + { + get { return i => (i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } } } } diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 234a33d78..b819d14e5 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1155,7 +1155,7 @@ namespace MediaBrowser.Controller.Entities if (!string.IsNullOrWhiteSpace(info.ItemName) && !string.IsNullOrWhiteSpace(info.ItemType)) { - return LibraryManager.RootFolder.RecursiveChildren.FirstOrDefault(i => + return LibraryManager.RootFolder.GetRecursiveChildren(i => { if (string.Equals(i.Name, info.ItemName, StringComparison.OrdinalIgnoreCase)) { @@ -1173,7 +1173,8 @@ namespace MediaBrowser.Controller.Entities } return false; - }); + + }).FirstOrDefault(); } return null; diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index dd3d145a0..9cc320095 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Controller.Entities /// <summary> /// Class Folder /// </summary> - public class Folder : BaseItem, IHasThemeMedia, IHasTags + public class Folder : BaseItem, IHasThemeMedia, IHasTags, IHasPreferredMetadataLanguage { public static IUserManager UserManager { get; set; } public static IUserViewManager UserViewManager { get; set; } @@ -30,6 +30,14 @@ namespace MediaBrowser.Controller.Entities public List<Guid> ThemeVideoIds { get; set; } public List<string> Tags { get; set; } + public string PreferredMetadataLanguage { get; set; } + + /// <summary> + /// Gets or sets the preferred metadata country code. + /// </summary> + /// <value>The preferred metadata country code.</value> + public string PreferredMetadataCountryCode { get; set; } + public Folder() { LinkedChildren = new List<LinkedChild>(); @@ -796,18 +804,20 @@ namespace MediaBrowser.Controller.Entities { var user = query.User; + Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); + var items = query.Recursive - ? GetRecursiveChildren(user) - : GetChildren(user, true); + ? GetRecursiveChildren(user, filter) + : GetChildren(user, true).Where(filter); - var result = SortAndFilter(items, query); + var result = PostFilterAndSort(items, query); return Task.FromResult(result); } - protected QueryResult<BaseItem> SortAndFilter(IEnumerable<BaseItem> items, InternalItemsQuery query) + protected QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, InternalItemsQuery query) { - return UserViewBuilder.FilterAndSort(items, this, null, query, LibraryManager, UserDataManager); + return UserViewBuilder.PostFilterAndSort(items, this, null, query, LibraryManager); } /// <summary> @@ -832,11 +842,11 @@ namespace MediaBrowser.Controller.Entities //the true root should return our users root folder children if (IsPhysicalRoot) return user.RootFolder.GetChildren(user, includeLinkedChildren); - var list = new List<BaseItem>(); + var result = new Dictionary<Guid, BaseItem>(); - var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, includeHidden, false); + AddChildren(user, includeLinkedChildren, result, includeHidden, false, null); - return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list; + return result.Values; } protected virtual IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) @@ -849,31 +859,30 @@ namespace MediaBrowser.Controller.Entities /// </summary> /// <param name="user">The user.</param> /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param> - /// <param name="list">The list.</param> + /// <param name="result">The result.</param> /// <param name="includeHidden">if set to <c>true</c> [include hidden].</param> /// <param name="recursive">if set to <c>true</c> [recursive].</param> + /// <param name="filter">The filter.</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - private bool AddChildrenToList(User user, bool includeLinkedChildren, List<BaseItem> list, bool includeHidden, bool recursive) + private void AddChildren(User user, bool includeLinkedChildren, Dictionary<Guid, BaseItem> result, bool includeHidden, bool recursive, Func<BaseItem, bool> filter) { - var hasLinkedChildren = false; - foreach (var child in GetEligibleChildrenForRecursiveChildren(user)) { if (child.IsVisible(user)) { if (includeHidden || !child.IsHiddenFromUser(user)) { - list.Add(child); + if (filter == null || filter(child)) + { + result[child.Id] = child; + } } if (recursive && child.IsFolder) { var folder = (Folder)child; - if (folder.AddChildrenToList(user, includeLinkedChildren, list, includeHidden, true)) - { - hasLinkedChildren = true; - } + folder.AddChildren(user, includeLinkedChildren, result, includeHidden, true, filter); } } } @@ -884,14 +893,13 @@ namespace MediaBrowser.Controller.Entities { if (child.IsVisible(user)) { - hasLinkedChildren = true; - - list.Add(child); + if (filter == null || filter(child)) + { + result[child.Id] = child; + } } } } - - return hasLinkedChildren; } /// <summary> @@ -901,18 +909,23 @@ namespace MediaBrowser.Controller.Entities /// <param name="includeLinkedChildren">if set to <c>true</c> [include linked children].</param> /// <returns>IEnumerable{BaseItem}.</returns> /// <exception cref="System.ArgumentNullException"></exception> - public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true) + public IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true) + { + return GetRecursiveChildren(user, i => true); + } + + public virtual IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter) { if (user == null) { throw new ArgumentNullException("user"); } - var list = new List<BaseItem>(); + var result = new Dictionary<Guid, BaseItem>(); - var hasLinkedChildren = AddChildrenToList(user, includeLinkedChildren, list, false, true); + AddChildren(user, true, result, false, true, filter); - return hasLinkedChildren ? list.DistinctBy(i => i.Id).ToList() : list; + return result.Values; } /// <summary> @@ -921,9 +934,14 @@ namespace MediaBrowser.Controller.Entities /// <returns>IList{BaseItem}.</returns> public IList<BaseItem> GetRecursiveChildren() { + return GetRecursiveChildren(null); + } + + public IList<BaseItem> GetRecursiveChildren(Func<BaseItem, bool> filter) + { var list = new List<BaseItem>(); - AddChildrenToList(list, true, null); + AddChildrenToList(list, true, filter); return list; } @@ -1136,8 +1154,7 @@ namespace MediaBrowser.Controller.Entities bool resetPosition) { // Sweep through recursively and update status - var tasks = GetRecursiveChildren(user, true) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) + var tasks = GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) .Select(c => c.MarkPlayed(user, datePlayed, resetPosition)); await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1151,8 +1168,7 @@ namespace MediaBrowser.Controller.Entities public override async Task MarkUnplayed(User user) { // Sweep through recursively and update status - var tasks = GetRecursiveChildren(user, true) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) + var tasks = GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) .Select(c => c.MarkUnplayed(user)); await Task.WhenAll(tasks).ConfigureAwait(false); @@ -1181,15 +1197,15 @@ namespace MediaBrowser.Controller.Entities return this; } - return RecursiveChildren.FirstOrDefault(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) || + return GetRecursiveChildren(i => string.Equals(i.Path, path, StringComparison.OrdinalIgnoreCase) || (!i.IsFolder && !i.IsInMixedFolder && string.Equals(i.ContainingFolderPath, path, StringComparison.OrdinalIgnoreCase)) || - i.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase)); + i.PhysicalLocations.Contains(path, StringComparer.OrdinalIgnoreCase)) + .FirstOrDefault(); } public override bool IsPlayed(User user) { - return GetRecursiveChildren(user) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual) + return GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual) .All(i => i.IsPlayed(user)); } @@ -1216,8 +1232,7 @@ namespace MediaBrowser.Controller.Entities } else { - children = folder.GetRecursiveChildren(user) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual); + children = folder.GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual); } // Loop through each recursive child diff --git a/MediaBrowser.Controller/Entities/GameGenre.cs b/MediaBrowser.Controller/Entities/GameGenre.cs index 16ca6e70a..d69a6ca46 100644 --- a/MediaBrowser.Controller/Entities/GameGenre.cs +++ b/MediaBrowser.Controller/Entities/GameGenre.cs @@ -42,7 +42,13 @@ namespace MediaBrowser.Controller.Entities public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) { - return inputItems.Where(i => (i is Game) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase)); + return inputItems.Where(ItemFilter); + } + + + public Func<BaseItem, bool> ItemFilter + { + get { return i => (i is Game) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } } } } diff --git a/MediaBrowser.Controller/Entities/Genre.cs b/MediaBrowser.Controller/Entities/Genre.cs index da5569afc..a33e6131f 100644 --- a/MediaBrowser.Controller/Entities/Genre.cs +++ b/MediaBrowser.Controller/Entities/Genre.cs @@ -46,7 +46,12 @@ namespace MediaBrowser.Controller.Entities public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) { - return inputItems.Where(i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase)); + return inputItems.Where(ItemFilter); + } + + public Func<BaseItem, bool> ItemFilter + { + get { return i => !(i is Game) && !(i is IHasMusicGenres) && i.Genres.Contains(Name, StringComparer.OrdinalIgnoreCase); } } } } diff --git a/MediaBrowser.Controller/Entities/IItemByName.cs b/MediaBrowser.Controller/Entities/IItemByName.cs index 70d5b840f..e303e9453 100644 --- a/MediaBrowser.Controller/Entities/IItemByName.cs +++ b/MediaBrowser.Controller/Entities/IItemByName.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace MediaBrowser.Controller.Entities { @@ -13,6 +14,8 @@ namespace MediaBrowser.Controller.Entities /// <param name="inputItems">The input items.</param> /// <returns>IEnumerable{BaseItem}.</returns> IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems); + + Func<BaseItem, bool> ItemFilter { get; } } public interface IHasDualAccess : IItemByName diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 30043682d..e99c11e87 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Entities public User User { get; set; } - public Func<BaseItem, User, bool> Filter { get; set; } + public Func<BaseItem, bool> Filter { get; set; } public bool? IsFolder { get; set; } public bool? IsFavorite { get; set; } diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 63690661a..e08d88b02 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Controller.Entities.Movies /// <summary> /// Class BoxSet /// </summary> - public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IMetadataContainer, IHasShares + public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IMetadataContainer, IHasShares { public List<Share> Shares { get; set; } @@ -55,14 +55,6 @@ namespace MediaBrowser.Controller.Entities.Movies /// <value>The tags.</value> public List<string> Keywords { get; set; } - public string PreferredMetadataLanguage { get; set; } - - /// <summary> - /// Gets or sets the preferred metadata country code. - /// </summary> - /// <value>The preferred metadata country code.</value> - public string PreferredMetadataCountryCode { get; set; } - /// <summary> /// Gets or sets the display order. /// </summary> @@ -103,7 +95,7 @@ namespace MediaBrowser.Controller.Entities.Movies var currentOfficialRating = OfficialRating; // Gather all possible ratings - var ratings = RecursiveChildren + var ratings = GetRecursiveChildren() .Concat(GetLinkedChildren()) .Where(i => i is Movie || i is Series) .Select(i => i.OfficialRating) @@ -148,7 +140,7 @@ namespace MediaBrowser.Controller.Entities.Movies { // Refresh bottom up, children first, then the boxset // By then hopefully the movies within will have Tmdb collection values - var items = RecursiveChildren.ToList(); + var items = GetRecursiveChildren().ToList(); var totalItems = items.Count; var percentages = new Dictionary<Guid, double>(totalItems); diff --git a/MediaBrowser.Controller/Entities/Person.cs b/MediaBrowser.Controller/Entities/Person.cs index 6d256e81c..19af6e6f0 100644 --- a/MediaBrowser.Controller/Entities/Person.cs +++ b/MediaBrowser.Controller/Entities/Person.cs @@ -57,7 +57,13 @@ namespace MediaBrowser.Controller.Entities public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) { - return inputItems.Where(i => i.People.Any(p => string.Equals(p.Name, Name, StringComparison.OrdinalIgnoreCase))); + return inputItems.Where(ItemFilter); + } + + + public Func<BaseItem, bool> ItemFilter + { + get { return i => i.People.Any(p => string.Equals(p.Name, Name, StringComparison.OrdinalIgnoreCase)); } } } diff --git a/MediaBrowser.Controller/Entities/Studio.cs b/MediaBrowser.Controller/Entities/Studio.cs index 58d46facc..53c635eba 100644 --- a/MediaBrowser.Controller/Entities/Studio.cs +++ b/MediaBrowser.Controller/Entities/Studio.cs @@ -52,7 +52,13 @@ namespace MediaBrowser.Controller.Entities public IEnumerable<BaseItem> GetTaggedItems(IEnumerable<BaseItem> inputItems) { - return inputItems.Where(i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase)); + return inputItems.Where(ItemFilter); + } + + + public Func<BaseItem, bool> ItemFilter + { + get { return i => i.Studios.Contains(Name, StringComparer.OrdinalIgnoreCase); } } } } diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs index 61d0aec60..f28306661 100644 --- a/MediaBrowser.Controller/Entities/TV/Season.cs +++ b/MediaBrowser.Controller/Entities/TV/Season.cs @@ -244,7 +244,7 @@ namespace MediaBrowser.Controller.Entities.TV private IEnumerable<Episode> GetEpisodes() { - var episodes = RecursiveChildren.OfType<Episode>(); + var episodes = GetRecursiveChildren().OfType<Episode>(); var series = Series; if (series != null && series.ContainsEpisodesWithoutSeasonFolders) @@ -254,12 +254,12 @@ namespace MediaBrowser.Controller.Entities.TV if (seasonNumber.HasValue) { - list.AddRange(series.RecursiveChildren.OfType<Episode>() + list.AddRange(series.GetRecursiveChildren().OfType<Episode>() .Where(i => i.ParentIndexNumber.HasValue && i.ParentIndexNumber.Value == seasonNumber.Value)); } else { - list.AddRange(series.RecursiveChildren.OfType<Episode>() + list.AddRange(series.GetRecursiveChildren().OfType<Episode>() .Where(i => !i.ParentIndexNumber.HasValue)); } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 0ec9121f3..ba537403b 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Controller.Entities.TV /// <summary> /// Class Series /// </summary> - public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IHasSpecialFeatures + public class Series : Folder, IHasSoundtracks, IHasTrailers, IHasDisplayOrder, IHasLookupInfo<SeriesInfo>, IHasSpecialFeatures { public List<Guid> SpecialFeatureIds { get; set; } public List<Guid> SoundtrackIds { get; set; } @@ -23,12 +23,6 @@ namespace MediaBrowser.Controller.Entities.TV public int? AnimeSeriesIndex { get; set; } - /// <summary> - /// Gets or sets the preferred metadata country code. - /// </summary> - /// <value>The preferred metadata country code.</value> - public string PreferredMetadataCountryCode { get; set; } - public Series() { AirDays = new List<DayOfWeek>(); @@ -93,7 +87,7 @@ namespace MediaBrowser.Controller.Entities.TV { get { - return RecursiveChildren.OfType<Episode>() + return GetRecursiveChildren(i => i is Episode) .Select(i => i.DateCreated) .OrderByDescending(i => i) .FirstOrDefault(); @@ -206,8 +200,8 @@ namespace MediaBrowser.Controller.Entities.TV internal IEnumerable<Episode> GetEpisodes(User user, int seasonNumber, bool includeMissingEpisodes, bool includeVirtualUnairedEpisodes, IEnumerable<Episode> additionalEpisodes) { - var episodes = GetRecursiveChildren(user) - .OfType<Episode>(); + var episodes = GetRecursiveChildren(user, i => i is Episode) + .Cast<Episode>(); episodes = FilterEpisodesBySeason(episodes, seasonNumber, DisplaySpecialsWithSeasons); @@ -262,8 +256,6 @@ namespace MediaBrowser.Controller.Entities.TV return config.BlockUnratedItems.Contains(UnratedItem.Series); } - public string PreferredMetadataLanguage { get; set; } - public SeriesInfo GetLookupInfo() { var info = GetItemLookupInfo<SeriesInfo>(); diff --git a/MediaBrowser.Controller/Entities/UserRootFolder.cs b/MediaBrowser.Controller/Entities/UserRootFolder.cs index a7276e262..b065ae171 100644 --- a/MediaBrowser.Controller/Entities/UserRootFolder.cs +++ b/MediaBrowser.Controller/Entities/UserRootFolder.cs @@ -18,10 +18,13 @@ namespace MediaBrowser.Controller.Entities { public override async Task<QueryResult<BaseItem>> GetItems(InternalItemsQuery query) { + var user = query.User; + Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager); + if (query.Recursive) { - var items = query.User.RootFolder.GetRecursiveChildren(query.User); - return SortAndFilter(items, query); + var items = query.User.RootFolder.GetRecursiveChildren(query.User, filter); + return PostFilterAndSort(items, query); } var result = await UserViewManager.GetUserViews(new UserViewQuery @@ -30,7 +33,7 @@ namespace MediaBrowser.Controller.Entities }, CancellationToken.None).ConfigureAwait(false); - return SortAndFilter(result, query); + return PostFilterAndSort(result.Where(filter), query); } public override bool IsPreSorted diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs index 0364ff678..f1436d45e 100644 --- a/MediaBrowser.Controller/Entities/UserView.cs +++ b/MediaBrowser.Controller/Entities/UserView.cs @@ -40,12 +40,13 @@ namespace MediaBrowser.Controller.Entities return result.Items; } - public override IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true) + public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter) { var result = GetItems(new InternalItemsQuery { User = user, - Recursive = true + Recursive = true, + Filter = filter }).Result; diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs index ac8be37d4..7b3021306 100644 --- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs +++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs @@ -406,7 +406,9 @@ 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), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos }, i => i is MusicVideo || i is Audio.Audio && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private async Task<QueryResult<BaseItem>> GetMovieFolders(Folder parent, User user, InternalItemsQuery query) @@ -414,7 +416,7 @@ namespace MediaBrowser.Controller.Entities if (query.Recursive) { var recursiveItems = GetRecursiveChildren(parent, user, - new[] {CollectionType.Movies, CollectionType.BoxSets, string.Empty}) + new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }) .Where(i => i is Movie || i is BoxSet); //var collections = _collectionManager.CollapseItemsWithinBoxSets(recursiveItems, user).ToList(); @@ -490,7 +492,9 @@ 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), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }, i => i is Movie && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private QueryResult<BaseItem> GetMovieResume(Folder parent, User user, InternalItemsQuery query) @@ -499,7 +503,9 @@ 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), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Movies, CollectionType.BoxSets, string.Empty }, i => i is Movie && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query) @@ -544,15 +550,16 @@ namespace MediaBrowser.Controller.Entities return GetResult(GetMediaFolders(user).SelectMany(i => { var hasCollectionType = i as ICollectionFolder; + Func<BaseItem, bool> filter = b => b is BoxSet; if (hasCollectionType != null && string.Equals(hasCollectionType.CollectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase)) { - return i.GetChildren(user, true); + return i.GetChildren(user, true).Where(filter); } - return i.GetRecursiveChildren(user); + return i.GetRecursiveChildren(user, filter); - }).OfType<BoxSet>(), parent, query); + }), parent, query); } private async Task<QueryResult<BaseItem>> GetTvView(Folder parent, User user, InternalItemsQuery query) @@ -598,7 +605,9 @@ 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>(), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is Game && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private QueryResult<BaseItem> GetRecentlyPlayedGames(Folder parent, User user, InternalItemsQuery query) @@ -607,7 +616,9 @@ 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>(), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.Games }, i => i is Game && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private QueryResult<BaseItem> GetFavoriteGames(Folder parent, User user, InternalItemsQuery query) @@ -622,7 +633,9 @@ 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>(), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }, i => i is Episode && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query) @@ -646,7 +659,9 @@ namespace MediaBrowser.Controller.Entities query.SortOrder = SortOrder.Descending; query.IsResumable = true; - return GetResult(GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }).OfType<Episode>(), parent, GetSpecialItemsLimit(), query); + var items = GetRecursiveChildren(parent, user, new[] { CollectionType.TvShows, string.Empty }, i => i is Episode && FilterItem(i, query)); + + return PostFilterAndSort(items, parent, GetSpecialItemsLimit(), query); } private QueryResult<BaseItem> GetTvSeries(Folder parent, User user, InternalItemsQuery query) @@ -748,29 +763,32 @@ namespace MediaBrowser.Controller.Entities InternalItemsQuery query) where T : BaseItem { - return GetResult(items, queryParent, null, query); + items = items.Where(i => Filter(i, query.User, query, _userDataManager, _libraryManager)); + + return PostFilterAndSort(items, queryParent, null, query, _libraryManager); } - private QueryResult<BaseItem> GetResult<T>(IEnumerable<T> items, + public bool FilterItem(BaseItem item, InternalItemsQuery query) + { + return Filter(item, query.User, query, _userDataManager, _libraryManager); + } + + private QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, BaseItem queryParent, int? totalRecordLimit, InternalItemsQuery query) - where T : BaseItem { - return FilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager, _userDataManager); + return PostFilterAndSort(items, queryParent, totalRecordLimit, query, _libraryManager); } - public static QueryResult<BaseItem> FilterAndSort(IEnumerable<BaseItem> items, + public static QueryResult<BaseItem> PostFilterAndSort(IEnumerable<BaseItem> items, BaseItem queryParent, int? totalRecordLimit, InternalItemsQuery query, - ILibraryManager libraryManager, - IUserDataManager userDataManager) + ILibraryManager libraryManager) { var user = query.User; - items = items.Where(i => Filter(i, user, query, userDataManager, libraryManager)); - items = FilterVirtualEpisodes(items, query.IsMissing, query.IsVirtualUnaired, @@ -1169,7 +1187,7 @@ namespace MediaBrowser.Controller.Entities }; } - private static bool Filter(BaseItem item, User user, InternalItemsQuery query, IUserDataManager userDataManager, ILibraryManager libraryManager) + public 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)) { @@ -1191,7 +1209,7 @@ namespace MediaBrowser.Controller.Entities return false; } - if (query.Filter != null && !query.Filter(item, user)) + if (query.Filter != null && !query.Filter(item)) { return false; } @@ -1641,6 +1659,16 @@ namespace MediaBrowser.Controller.Entities return parent.GetRecursiveChildren(user); } + private IEnumerable<BaseItem> GetRecursiveChildren(Folder parent, User user, IEnumerable<string> viewTypes, Func<BaseItem,bool> filter) + { + if (parent == null || parent is UserView) + { + return GetMediaFolders(user, viewTypes).SelectMany(i => i.GetRecursiveChildren(user, filter)); + } + + return parent.GetRecursiveChildren(user, filter); + } + private async Task<IEnumerable<BaseItem>> GetLiveTvFolders(User user) { var list = new List<BaseItem>(); diff --git a/MediaBrowser.Controller/Entities/Year.cs b/MediaBrowser.Controller/Entities/Year.cs index 11b0ce3d2..bbf473a9a 100644 --- a/MediaBrowser.Controller/Entities/Year.cs +++ b/MediaBrowser.Controller/Entities/Year.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -56,5 +57,11 @@ namespace MediaBrowser.Controller.Entities return inputItems.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year); } + + + public Func<BaseItem, bool> ItemFilter + { + get { throw new System.NotImplementedException(); } + } } } diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs index e48cddaaa..071a9bf93 100644 --- a/MediaBrowser.Controller/Playlists/Playlist.cs +++ b/MediaBrowser.Controller/Playlists/Playlist.cs @@ -50,9 +50,16 @@ namespace MediaBrowser.Controller.Playlists return GetPlayableItems(user); } - public override IEnumerable<BaseItem> GetRecursiveChildren(User user, bool includeLinkedChildren = true) + public override IEnumerable<BaseItem> GetRecursiveChildren(User user, Func<BaseItem, bool> filter) { - return GetPlayableItems(user); + var items = GetPlayableItems(user); + + if (filter != null) + { + items = items.Where(filter); + } + + return items; } public IEnumerable<Tuple<LinkedChild, BaseItem>> GetManageableItems() @@ -76,38 +83,38 @@ namespace MediaBrowser.Controller.Playlists .Where(m => string.Equals(m.MediaType, playlistMediaType, StringComparison.OrdinalIgnoreCase)); } - private static IEnumerable<BaseItem> GetPlaylistItems(BaseItem i, User user) + private static IEnumerable<BaseItem> GetPlaylistItems(BaseItem item, User user) { - var musicGenre = i as MusicGenre; + var musicGenre = item as MusicGenre; if (musicGenre != null) { - var items = user == null - ? LibraryManager.RootFolder.GetRecursiveChildren() - : user.RootFolder.GetRecursiveChildren(user, true); + Func<BaseItem, bool> filter = i => i is Audio && i.Genres.Contains(musicGenre.Name, StringComparer.OrdinalIgnoreCase); - var songs = items - .OfType<Audio>() - .Where(a => a.Genres.Contains(musicGenre.Name, StringComparer.OrdinalIgnoreCase)); + var items = user == null + ? LibraryManager.RootFolder.GetRecursiveChildren(filter) + : user.RootFolder.GetRecursiveChildren(user, filter); - return LibraryManager.Sort(songs, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); + return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); } - var musicArtist = i as MusicArtist; + var musicArtist = item as MusicArtist; if (musicArtist != null) { - var items = user == null - ? LibraryManager.RootFolder.GetRecursiveChildren() - : user.RootFolder.GetRecursiveChildren(user, true); + Func<BaseItem, bool> filter = i => + { + var audio = i as Audio; + return audio != null && audio.HasArtist(musicArtist.Name); + }; - var songs = items - .OfType<Audio>() - .Where(a => a.HasArtist(musicArtist.Name)); + var items = user == null + ? LibraryManager.RootFolder.GetRecursiveChildren(filter) + : user.RootFolder.GetRecursiveChildren(user, filter); - return LibraryManager.Sort(songs, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); + return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending); } // Grab these explicitly to avoid the sorting that will happen below - var collection = i as BoxSet; + var collection = item as BoxSet; if (collection != null) { var items = user == null @@ -119,7 +126,7 @@ namespace MediaBrowser.Controller.Playlists } // Grab these explicitly to avoid the sorting that will happen below - var season = i as Season; + var season = item as Season; if (season != null) { var items = user == null @@ -130,21 +137,18 @@ namespace MediaBrowser.Controller.Playlists .Where(m => !m.IsFolder); } - var folder = i as Folder; + var folder = item as Folder; if (folder != null) { var items = user == null - ? folder.GetRecursiveChildren() - : folder.GetRecursiveChildren(user, true); - - items = items - .Where(m => !m.IsFolder); + ? folder.GetRecursiveChildren(m => !m.IsFolder) + : folder.GetRecursiveChildren(user, m => !m.IsFolder); return LibraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending); } - return new[] { i }; + return new[] { item }; } [IgnoreDataMember] diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs index 1faf690c9..f2b006410 100644 --- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs +++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs @@ -479,9 +479,7 @@ namespace MediaBrowser.Dlna.ContentDirectory private async Task<QueryResult<ServerItem>> GetItemsFromPerson(Person person, User user, int? startIndex, int? limit) { - var items = user.RootFolder.GetRecursiveChildren(user) - .Where(i => i is Movie || i is Series) - .Where(i => i.ContainsPerson(person.Name)) + var items = user.RootFolder.GetRecursiveChildren(user, i => i is Movie || i is Series && i.ContainsPerson(person.Name)) .ToList(); var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery @@ -595,7 +593,7 @@ namespace MediaBrowser.Dlna.ContentDirectory }); } - private bool FilterUnsupportedContent(BaseItem i, User user) + private bool FilterUnsupportedContent(BaseItem i) { // Unplayable if (i.LocationType == LocationType.Virtual && !i.IsFolder) diff --git a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs index d913bd076..2852f5719 100644 --- a/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs +++ b/MediaBrowser.Providers/MediaInfo/SubtitleScheduledTask.cs @@ -58,10 +58,13 @@ namespace MediaBrowser.Providers.MediaInfo var options = GetOptions(); var videos = _libraryManager.RootFolder - .RecursiveChildren - .OfType<Video>() - .Where(i => + .GetRecursiveChildren(i => { + if (!(i is Video)) + { + return false; + } + if (i.LocationType == LocationType.Remote || i.LocationType == LocationType.Virtual) { return false; @@ -72,6 +75,7 @@ namespace MediaBrowser.Providers.MediaInfo (options.DownloadMovieSubtitles && i is Movie); }) + .Cast<Video>() .ToList(); var numComplete = 0; diff --git a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs index dd4b33542..cc2142292 100644 --- a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs +++ b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs @@ -177,9 +177,8 @@ namespace MediaBrowser.Providers.Movies var numComplete = 0; // Gather all movies into a lookup by tmdb id - var allMovies = _libraryManager.RootFolder.RecursiveChildren - .Where(i => i is Movie) - .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb))) + var allMovies = _libraryManager.RootFolder + .GetRecursiveChildren(i => i is Movie && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb))) .ToLookup(i => i.GetProviderId(MetadataProviders.Tmdb)); foreach (var id in list) diff --git a/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs b/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs index dac3c4836..2ba700b09 100644 --- a/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs +++ b/MediaBrowser.Providers/Music/AlbumImageFromSongProvider.cs @@ -20,7 +20,8 @@ namespace MediaBrowser.Providers.Music { var album = (MusicAlbum)item; - var image = album.RecursiveChildren.OfType<Audio>() + var image = album.GetRecursiveChildren() + .OfType<Audio>() .Select(i => i.GetImagePath(type)) .FirstOrDefault(i => !string.IsNullOrEmpty(i)); diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs index 64dcd913d..11348361a 100644 --- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs +++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs @@ -45,7 +45,9 @@ namespace MediaBrowser.Providers.Music { if (!item.IsLocked) { - var songs = item.RecursiveChildren.OfType<Audio>().ToList(); + var songs = item.GetRecursiveChildren(i => i is Audio) + .Cast<Audio>() + .ToList(); if (!item.LockedFields.Contains(MetadataFields.Genres)) { diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index 77ae9eec9..51c4d18a9 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -44,8 +44,8 @@ namespace MediaBrowser.Providers.Music if (!item.IsLocked) { var taggedItems = item.IsAccessedByName ? - item.GetTaggedItems(_libraryManager.RootFolder.RecursiveChildren.Where(i => i is IHasArtist && !i.IsFolder)).ToList() : - item.RecursiveChildren.Where(i => i is IHasArtist && !i.IsFolder).ToList(); + _libraryManager.RootFolder.GetRecursiveChildren(i => !i.IsFolder && item.ItemFilter(i)).ToList() : + item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToList(); if (!item.LockedFields.Contains(MetadataFields.Genres)) { diff --git a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs index 253acc13f..0258fd539 100644 --- a/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs +++ b/MediaBrowser.Providers/People/TvdbPersonImageProvider.cs @@ -56,10 +56,12 @@ namespace MediaBrowser.Providers.People public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken) { + // Avoid implicitly captured closure + var itemName = item.Name; + var seriesWithPerson = _library.RootFolder - .RecursiveChildren - .OfType<Series>() - .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb)) && i.People.Any(p => string.Equals(p.Name, item.Name, StringComparison.OrdinalIgnoreCase))) + .GetRecursiveChildren(i => i is Series && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb)) && i.People.Any(p => string.Equals(p.Name, itemName, StringComparison.OrdinalIgnoreCase))) + .Cast<Series>() .ToList(); var infos = seriesWithPerson.Select(i => GetImageFromSeriesData(i, item.Name, cancellationToken)) diff --git a/MediaBrowser.Providers/TV/DummySeasonProvider.cs b/MediaBrowser.Providers/TV/DummySeasonProvider.cs index f82439de9..fb5282551 100644 --- a/MediaBrowser.Providers/TV/DummySeasonProvider.cs +++ b/MediaBrowser.Providers/TV/DummySeasonProvider.cs @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.TV private async Task<bool> AddDummySeasonFolders(Series series, CancellationToken cancellationToken) { - var episodesInSeriesFolder = series.RecursiveChildren + var episodesInSeriesFolder = series.GetRecursiveChildren() .OfType<Episode>() .Where(i => !i.IsInSeasonFolder) .ToList(); @@ -134,7 +134,7 @@ namespace MediaBrowser.Providers.TV .Where(i => i.LocationType == LocationType.Virtual) .ToList(); - var episodes = series.RecursiveChildren.OfType<Episode>().ToList(); + var episodes = series.GetRecursiveChildren().OfType<Episode>().ToList(); var seasonsToRemove = virtualSeasons .Where(i => diff --git a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs index 8b46b082b..d45128288 100644 --- a/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/MissingEpisodeProvider.cs @@ -139,7 +139,7 @@ namespace MediaBrowser.Providers.TV /// <returns></returns> private bool HasInvalidContent(IEnumerable<Series> group) { - var allItems = group.ToList().SelectMany(i => i.RecursiveChildren).ToList(); + var allItems = group.ToList().SelectMany(i => i.GetRecursiveChildren()).ToList(); return allItems.OfType<Season>().Any(i => !i.IndexNumber.HasValue) || allItems.OfType<Episode>().Any(i => @@ -163,22 +163,23 @@ namespace MediaBrowser.Providers.TV /// <param name="episodeLookup">The episode lookup.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - private async Task<bool> AddMissingEpisodes(List<Series> series, + private async Task<bool> AddMissingEpisodes(List<Series> series, bool seriesHasBadData, - string seriesDataPath, - IEnumerable<Tuple<int, int>> episodeLookup, + string seriesDataPath, + IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken) { var existingEpisodes = (from s in series let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) - from c in s.RecursiveChildren.OfType<Episode>() + from c in s.GetRecursiveChildren().OfType<Episode>() select new Tuple<int, Episode>((c.ParentIndexNumber ?? 0) + seasonOffset, c)) .ToList(); var lookup = episodeLookup as IList<Tuple<int, int>> ?? episodeLookup.ToList(); var seasonCounts = (from e in lookup - group e by e.Item1 into g select g) + group e by e.Item1 into g + select g) .ToDictionary(g => g.Key, g => g.Count()); var hasChanges = false; @@ -244,23 +245,23 @@ namespace MediaBrowser.Providers.TV { var seriesAndOffsets = series.Select(s => new { Series = s, SeasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) }).ToList(); - var bestMatch = seriesAndOffsets.FirstOrDefault(s => s.Series.RecursiveChildren.OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == seasonNumber)) ?? - seriesAndOffsets.FirstOrDefault(s => s.Series.RecursiveChildren.OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == 1)) ?? - seriesAndOffsets.OrderBy(s => s.Series.RecursiveChildren.OfType<Season>().Select(season => season.IndexNumber + s.SeasonOffset).Min()).First(); + var bestMatch = seriesAndOffsets.FirstOrDefault(s => s.Series.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == seasonNumber)) ?? + seriesAndOffsets.FirstOrDefault(s => s.Series.GetRecursiveChildren().OfType<Season>().Any(season => (season.IndexNumber + s.SeasonOffset) == 1)) ?? + seriesAndOffsets.OrderBy(s => s.Series.GetRecursiveChildren().OfType<Season>().Select(season => season.IndexNumber + s.SeasonOffset).Min()).First(); return bestMatch.Series; } - + /// <summary> /// Removes the virtual entry after a corresponding physical version has been added /// </summary> - private async Task<bool> RemoveObsoleteOrMissingEpisodes(IEnumerable<Series> series, + private async Task<bool> RemoveObsoleteOrMissingEpisodes(IEnumerable<Series> series, IEnumerable<Tuple<int, int>> episodeLookup) { var existingEpisodes = (from s in series let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1) - from c in s.RecursiveChildren.OfType<Episode>() - select new { SeasonOffset = seasonOffset, Episode = c }) + from c in s.GetRecursiveChildren().OfType<Episode>() + select new { SeasonOffset = seasonOffset, Episode = c }) .ToList(); var physicalEpisodes = existingEpisodes @@ -320,7 +321,7 @@ namespace MediaBrowser.Providers.TV /// <param name="series">The series.</param> /// <param name="episodeLookup">The episode lookup.</param> /// <returns>Task{System.Boolean}.</returns> - private async Task<bool> RemoveObsoleteOrMissingSeasons(IEnumerable<Series> series, + private async Task<bool> RemoveObsoleteOrMissingSeasons(IEnumerable<Series> series, IEnumerable<Tuple<int, int>> episodeLookup) { var existingSeasons = (from s in series @@ -361,7 +362,7 @@ namespace MediaBrowser.Providers.TV // Season does not have a number // Remove if there are no episodes directly in series without a season number - return i.Season.Series.RecursiveChildren.OfType<Episode>().All(s => s.ParentIndexNumber.HasValue || !s.IsInSeasonFolder); + return i.Season.Series.GetRecursiveChildren().OfType<Episode>().All(s => s.ParentIndexNumber.HasValue || !s.IsInSeasonFolder); }) .ToList(); diff --git a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs index 2506b53ad..8b22f45a3 100644 --- a/MediaBrowser.Providers/TV/SeriesPostScanTask.cs +++ b/MediaBrowser.Providers/TV/SeriesPostScanTask.cs @@ -44,8 +44,8 @@ namespace MediaBrowser.Providers.TV private async Task RunInternal(IProgress<double> progress, CancellationToken cancellationToken) { var seriesList = _libraryManager.RootFolder - .RecursiveChildren - .OfType<Series>() + .GetRecursiveChildren(i => i is Series) + .Cast<Series>() .ToList(); var provider = new DummySeasonProvider(_config, _logger, _localization, _libraryManager); @@ -65,8 +65,8 @@ namespace MediaBrowser.Providers.TV { cancellationToken.ThrowIfCancellationRequested(); - var episodes = series.RecursiveChildren - .OfType<Episode>() + var episodes = series.GetRecursiveChildren(i => i is Episode) + .Cast<Episode>() .ToList(); var physicalEpisodes = episodes.Where(i => i.LocationType != LocationType.Virtual) diff --git a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs index 32ed5d7f6..4bc4a2c8d 100644 --- a/MediaBrowser.Providers/TV/TvdbPrescanTask.cs +++ b/MediaBrowser.Providers/TV/TvdbPrescanTask.cs @@ -110,10 +110,10 @@ namespace MediaBrowser.Providers.TV .Select(Path.GetFileName) .ToList(); - var seriesIdsInLibrary = _libraryManager.RootFolder.RecursiveChildren - .OfType<Series>() + var seriesIdsInLibrary = _libraryManager.RootFolder + .GetRecursiveChildren(i => i is Series && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) + .Cast<Series>() .Select(i => i.GetProviderId(MetadataProviders.Tvdb)) - .Where(i => !string.IsNullOrEmpty(i)) .ToList(); var missingSeries = seriesIdsInLibrary.Except(existingDirectories, StringComparer.OrdinalIgnoreCase) @@ -301,9 +301,9 @@ namespace MediaBrowser.Providers.TV var numComplete = 0; // Gather all series into a lookup by tvdb id - var allSeries = _libraryManager.RootFolder.RecursiveChildren - .OfType<Series>() - .Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) + var allSeries = _libraryManager.RootFolder + .GetRecursiveChildren(i => i is Series && !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tvdb))) + .Cast<Series>() .ToLookup(i => i.GetProviderId(MetadataProviders.Tvdb)); foreach (var seriesId in list) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 85a31337b..5640f2745 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -96,10 +96,10 @@ namespace MediaBrowser.Server.Implementations.Dto if (byName != null && !(item is LiveTvChannel)) { var libraryItems = user != null ? - user.RootFolder.GetRecursiveChildren(user) : - _libraryManager.RootFolder.RecursiveChildren; + user.RootFolder.GetRecursiveChildren(user, byName.ItemFilter) : + _libraryManager.RootFolder.GetRecursiveChildren(byName.ItemFilter); - SetItemByNameInfo(item, dto, byName.GetTaggedItems(libraryItems).ToList(), user); + SetItemByNameInfo(item, dto, libraryItems.ToList(), user); } FillSyncInfo(dto, item, itemIdsWithSyncJobs, options); @@ -119,10 +119,10 @@ namespace MediaBrowser.Server.Implementations.Dto if (byName != null && !(item is LiveTvChannel)) { var libraryItems = user != null ? - user.RootFolder.GetRecursiveChildren(user) : - _libraryManager.RootFolder.RecursiveChildren; + user.RootFolder.GetRecursiveChildren(user, byName.ItemFilter) : + _libraryManager.RootFolder.GetRecursiveChildren(byName.ItemFilter); - SetItemByNameInfo(item, dto, byName.GetTaggedItems(libraryItems).ToList(), user); + SetItemByNameInfo(item, dto, libraryItems.ToList(), user); return dto; } @@ -153,7 +153,14 @@ namespace MediaBrowser.Server.Implementations.Dto var result = _syncManager.GetLibraryItemIds(new SyncJobItemQuery { - TargetId = deviceId + TargetId = deviceId, + Statuses = new List<SyncJobItemStatus> + { + SyncJobItemStatus.Converting, + SyncJobItemStatus.Queued, + SyncJobItemStatus.Transferring, + SyncJobItemStatus.Synced + } }); return result.Items; @@ -451,9 +458,8 @@ namespace MediaBrowser.Server.Implementations.Dto if (!string.IsNullOrEmpty(item.Album)) { var parentAlbum = _libraryManager.RootFolder - .GetRecursiveChildren() - .Where(i => i is MusicAlbum) - .FirstOrDefault(i => string.Equals(i.Name, item.Album, StringComparison.OrdinalIgnoreCase)); + .GetRecursiveChildren(i => i is MusicAlbum && string.Equals(i.Name, item.Album, StringComparison.OrdinalIgnoreCase)) + .FirstOrDefault(); if (parentAlbum != null) { @@ -1385,7 +1391,7 @@ namespace MediaBrowser.Server.Implementations.Dto { linkedChildren = user == null ? folder.GetRecursiveChildren().ToList() - : folder.GetRecursiveChildren(user, true).ToList(); + : folder.GetRecursiveChildren(user).ToList(); var parentWithBackdrop = linkedChildren.FirstOrDefault(i => i.GetImages(ImageType.Backdrop).Any()); @@ -1402,7 +1408,7 @@ namespace MediaBrowser.Server.Implementations.Dto { linkedChildren = user == null ? folder.GetRecursiveChildren().ToList() - : folder.GetRecursiveChildren(user, true).ToList(); + : folder.GetRecursiveChildren(user).ToList(); } var parentWithImage = linkedChildren.FirstOrDefault(i => i.GetImages(ImageType.Primary).Any()); @@ -1479,12 +1485,14 @@ namespace MediaBrowser.Server.Implementations.Dto if (season != null) { - children = season.GetEpisodes(user).Where(i => i.LocationType != LocationType.Virtual); + children = season + .GetEpisodes(user) + .Where(i => i.LocationType != LocationType.Virtual); } else { - children = folder.GetRecursiveChildren(user) - .Where(i => !i.IsFolder && i.LocationType != LocationType.Virtual); + children = folder + .GetRecursiveChildren(user, i => !i.IsFolder && i.LocationType != LocationType.Virtual); } // Loop through each recursive child diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index e6976c54b..dd5dc82e8 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -245,7 +245,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints var collections = user.RootFolder.GetChildren(user, true).ToList(); - var allRecursiveChildren = user.RootFolder.GetRecursiveChildren(user) + var allRecursiveChildren = user.RootFolder + .GetRecursiveChildren(user) .Select(i => i.Id) .Distinct() .ToDictionary(i => i); diff --git a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs index 2fc5f9bc2..10e50e497 100644 --- a/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs +++ b/MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs @@ -226,7 +226,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization private List<string> GetOtherDuplicatePaths(string targetPath, Series series, int seasonNumber, int episodeNumber, int? endingEpisodeNumber) { - var episodePaths = series.RecursiveChildren + var episodePaths = series.GetRecursiveChildren() .OfType<Episode>() .Where(i => { @@ -335,8 +335,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization result.ExtractedName = nameWithoutYear; result.ExtractedYear = yearInName; - return _libraryManager.RootFolder.RecursiveChildren - .OfType<Series>() + return _libraryManager.RootFolder.GetRecursiveChildren(i => i is Series) + .Cast<Series>() .Select(i => NameUtils.GetMatchScore(nameWithoutYear, yearInName, i)) .Where(i => i.Item2 > 0) .OrderByDescending(i => i.Item2) @@ -400,9 +400,8 @@ namespace MediaBrowser.Server.Implementations.FileOrganization { // If there's already a season folder, use that var season = series - .RecursiveChildren - .OfType<Season>() - .FirstOrDefault(i => i.LocationType == LocationType.FileSystem && i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber); + .GetRecursiveChildren(i => i is Season && i.LocationType == LocationType.FileSystem && i.IndexNumber.HasValue && i.IndexNumber.Value == seasonNumber) + .FirstOrDefault(); if (season != null) { diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs index a113e8d5e..2af6e5588 100644 --- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs +++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs @@ -67,29 +67,26 @@ namespace MediaBrowser.Server.Implementations.Intros ? null : _localization.GetRatingLevel(item.OfficialRating); - var libaryItems = user.RootFolder.GetRecursiveChildren(user, false) - .ToList(); - var random = new Random(Environment.TickCount + Guid.NewGuid().GetHashCode()); var candidates = new List<ItemWithTrailer>(); if (config.EnableIntrosFromMoviesInLibrary) { - var itemsWithTrailers = libaryItems - .Where(i => - { - var hasTrailers = i as IHasTrailers; - - if (hasTrailers != null && hasTrailers.LocalTrailerIds.Count > 0) - { - if (i is Movie) - { - return !IsDuplicate(item, i); - } - } - return false; - }); + var itemsWithTrailers = user.RootFolder + .GetRecursiveChildren(user, i => + { + var hasTrailers = i as IHasTrailers; + + if (hasTrailers != null && hasTrailers.LocalTrailerIds.Count > 0) + { + if (i is Movie) + { + return !IsDuplicate(item, i); + } + } + return false; + }); candidates.AddRange(itemsWithTrailers.Select(i => new ItemWithTrailer { @@ -141,15 +138,16 @@ namespace MediaBrowser.Server.Implementations.Intros })); } + return GetResult(item, candidates, config, ratingLevel); + } + + private IEnumerable<IntroInfo> GetResult(BaseItem item, IEnumerable<ItemWithTrailer> candidates, CinemaModeConfiguration config, int? ratingLevel) + { var customIntros = !string.IsNullOrWhiteSpace(config.CustomIntroPath) ? GetCustomIntros(item) : new List<IntroInfo>(); var trailerLimit = config.TrailerLimit; - if (customIntros.Count > 0) - { - trailerLimit--; - } // Avoid implicitly captured closure return candidates.Where(i => diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index d93705a51..0ebd1aace 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -337,8 +337,8 @@ namespace MediaBrowser.Server.Implementations.Library /// <returns>Task.</returns> private async Task UpdateSeasonZeroNames(string newName, CancellationToken cancellationToken) { - var seasons = RootFolder.RecursiveChildren - .OfType<Season>() + var seasons = RootFolder.GetRecursiveChildren(i => i is Season) + .Cast<Season>() .Where(i => i.IndexNumber.HasValue && i.IndexNumber.Value == 0 && !string.Equals(i.Name, newName, StringComparison.Ordinal)) .ToList(); @@ -393,7 +393,7 @@ namespace MediaBrowser.Server.Implementations.Library var locationType = item.LocationType; var children = item.IsFolder - ? ((Folder)item).RecursiveChildren.ToList() + ? ((Folder)item).GetRecursiveChildren().ToList() : new List<BaseItem>(); foreach (var metadataPath in GetMetadataPaths(item, children)) @@ -919,9 +919,10 @@ namespace MediaBrowser.Server.Implementations.Library { var validFilename = _fileSystem.GetValidFilename(name).Trim(); - var existing = RootFolder.RecursiveChildren - .OfType<T>() - .FirstOrDefault(i => string.Equals(_fileSystem.GetValidFilename(i.Name).Trim(), validFilename, StringComparison.OrdinalIgnoreCase)); + var existing = RootFolder + .GetRecursiveChildren(i => i is T && string.Equals(_fileSystem.GetValidFilename(i.Name).Trim(), validFilename, StringComparison.OrdinalIgnoreCase)) + .Cast<T>() + .FirstOrDefault(); if (existing != null) { diff --git a/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs index 9196bf734..b72406730 100644 --- a/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Channels; @@ -25,8 +24,8 @@ namespace MediaBrowser.Server.Implementations.Library public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { var items = _libraryManager.RootFolder - .RecursiveChildren - .OfType<IHasTrailers>() + .GetRecursiveChildren(i => i is IHasTrailers) + .Cast<IHasTrailers>() .ToList(); var channelTrailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs index b8c29c19b..5a7533ad2 100644 --- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs +++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs @@ -32,8 +32,8 @@ namespace MediaBrowser.Server.Implementations.Library var artist = _libraryManager.GetArtist(name); var genres = user.RootFolder - .GetRecursiveChildren(user) - .OfType<Audio>() + .GetRecursiveChildren(user, i => i is Audio) + .Cast<Audio>() .Where(i => i.HasArtist(name)) .SelectMany(i => i.Genres) .Concat(artist.Genres) @@ -45,8 +45,8 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user) { var genres = item - .GetRecursiveChildren(user, true) - .OfType<Audio>() + .GetRecursiveChildren(user, i => i is Audio) + .Cast<Audio>() .SelectMany(i => i.Genres) .Concat(item.Genres) .Distinct(StringComparer.OrdinalIgnoreCase); @@ -57,8 +57,8 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user) { var genres = item - .GetRecursiveChildren(user, true) - .OfType<Audio>() + .GetRecursiveChildren(user, i => i is Audio) + .Cast<Audio>() .SelectMany(i => i.Genres) .Concat(item.Genres) .Distinct(StringComparer.OrdinalIgnoreCase); @@ -68,12 +68,13 @@ namespace MediaBrowser.Server.Implementations.Library public IEnumerable<Audio> GetInstantMixFromGenres(IEnumerable<string> genres, User user) { - var inputItems = user.RootFolder.GetRecursiveChildren(user); + var inputItems = user.RootFolder + .GetRecursiveChildren(user, i => i is Audio); var genresDictionary = genres.ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); return inputItems - .OfType<Audio>() + .Cast<Audio>() .Select(i => new Tuple<Audio, int>(i, i.Genres.Count(genresDictionary.ContainsKey))) .Where(i => i.Item2 > 0) .OrderByDescending(i => i.Item2) diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 1c92f6c4a..51cad7a35 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -35,20 +35,19 @@ namespace MediaBrowser.Server.Implementations.Library { IEnumerable<BaseItem> inputItems; + Func<BaseItem, bool> filter = i => !(i is ICollectionFolder); + if (string.IsNullOrWhiteSpace(query.UserId)) { - inputItems = _libraryManager.RootFolder.RecursiveChildren; + inputItems = _libraryManager.RootFolder.GetRecursiveChildren(filter); } else { var user = _userManager.GetUserById(query.UserId); - inputItems = user.RootFolder.GetRecursiveChildren(user, true); + inputItems = user.RootFolder.GetRecursiveChildren(user, filter); } - - inputItems = inputItems.Where(i => !(i is ICollectionFolder)); - inputItems = _libraryManager.ReplaceVideosWithPrimaryVersions(inputItems); var results = await GetSearchHints(inputItems, query).ConfigureAwait(false); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index 5363aef25..7636833e4 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -44,9 +44,10 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var allItems = _libraryManager.RootFolder.GetRecursiveChildren(); - - var allSongs = allItems.Where(i => !i.IsFolder).OfType<IHasArtist>().ToList(); + var allSongs = _libraryManager.RootFolder + .GetRecursiveChildren(i => !i.IsFolder && (i is IHasArtist)) + .Cast<IHasArtist>() + .ToList(); var allArtists = allSongs.SelectMany(i => i.AllArtists) .Distinct(StringComparer.OrdinalIgnoreCase) diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs index b2f2a60c2..757936aa7 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.RecursiveChildren.Where(i => (i is Game)) + var items = _libraryManager.RootFolder.GetRecursiveChildren(i => (i is Game)) .SelectMany(i => i.Genres) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs index 43dc69e63..3a06fac1b 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.RecursiveChildren.Where(i => !(i is IHasMusicGenres) && !(i is Game)) + var items = _libraryManager.RootFolder.GetRecursiveChildren(i => !(i is IHasMusicGenres) && !(i is Game)) .SelectMany(i => i.Genres) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs index dfdbda1d9..25eddb48a 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.RecursiveChildren.Where(i => (i is IHasMusicGenres)) + var items = _libraryManager.RootFolder.GetRecursiveChildren(i => (i is IHasMusicGenres)) .SelectMany(i => i.Genres) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs index 643deef01..5feebab9c 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators /// <returns>Task.</returns> public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var items = _libraryManager.RootFolder.RecursiveChildren + var items = _libraryManager.RootFolder.GetRecursiveChildren() .SelectMany(i => i.Studios) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs index 5b8f27f58..5ea5fb254 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators public async Task Run(IProgress<double> progress, CancellationToken cancellationToken) { - var allYears = _libraryManager.RootFolder.RecursiveChildren + var allYears = _libraryManager.RootFolder.GetRecursiveChildren(i => i.ProductionYear.HasValue) .Select(i => i.ProductionYear ?? -1) .Where(i => i > 0) .Distinct() diff --git a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs index 7c10f2767..6a3759f13 100644 --- a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs +++ b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Photos protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) { var photoAlbum = (PhotoAlbum)item; - var items = GetFinalItems(photoAlbum.RecursiveChildren.Where(i => i is Photo).ToList()); + var items = GetFinalItems(photoAlbum.GetRecursiveChildren(i => i is Photo).ToList()); return Task.FromResult(items); } diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 2b2c52406..980c3d14a 100644 --- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -23,8 +23,7 @@ namespace MediaBrowser.Server.Implementations.Playlists protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) { - return RecursiveChildren - .OfType<Playlist>(); + return GetRecursiveChildren(i => i is Playlist); } public override bool IsHidden diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs index 8da9ba222..c511f40e0 100644 --- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs +++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs @@ -81,8 +81,7 @@ namespace MediaBrowser.Server.Implementations.Playlists var folder = item as Folder; if (folder != null) { - options.MediaType = folder.GetRecursiveChildren() - .Where(i => !i.IsFolder && i.SupportsAddingToPlaylist) + options.MediaType = folder.GetRecursiveChildren(i => !i.IsFolder && i.SupportsAddingToPlaylist) .Select(i => i.MediaType) .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); } diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs index 2a115c8dd..7132db2ef 100644 --- a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs +++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs @@ -145,8 +145,8 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks /// <returns>Task.</returns> public async Task Execute(CancellationToken cancellationToken, IProgress<double> progress) { - var videos = _libraryManager.RootFolder.RecursiveChildren - .OfType<Video>() + var videos = _libraryManager.RootFolder.GetRecursiveChildren(i => i is Video) + .Cast<Video>() .ToList(); var numComplete = 0; diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 7112c2357..5284a42e4 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -899,10 +899,9 @@ namespace MediaBrowser.Server.Implementations.Session { var folder = (Folder)item; - var items = user == null ? folder.RecursiveChildren : - folder.GetRecursiveChildren(user); - - items = items.Where(i => !i.IsFolder); + var items = user == null ? + folder.GetRecursiveChildren(i => !i.IsFolder) : + folder.GetRecursiveChildren(user, i => !i.IsFolder); items = items.OrderBy(i => i.SortName); diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs index b926ee338..fd4474b80 100644 --- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs +++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs @@ -288,18 +288,14 @@ namespace MediaBrowser.Server.Implementations.Sync var itemByName = item as IItemByName; if (itemByName != null) { - var items = user.RootFolder - .GetRecursiveChildren(user); - - return itemByName.GetTaggedItems(items); + return user.RootFolder + .GetRecursiveChildren(user, itemByName.ItemFilter); } if (item.IsFolder) { var folder = (Folder)item; - var items = folder.GetRecursiveChildren(user); - - items = items.Where(i => !i.IsFolder); + var items = folder.GetRecursiveChildren(user, i => !i.IsFolder); if (!folder.IsPreSorted) { diff --git a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs index 8c21727a4..11dfb4791 100644 --- a/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs +++ b/MediaBrowser.Server.Implementations/TV/TVSeriesManager.cs @@ -36,8 +36,8 @@ namespace MediaBrowser.Server.Implementations.TV ? new string[] { } : new[] { request.ParentId }; - var items = GetAllLibraryItems(user, parentIds) - .OfType<Series>(); + var items = GetAllLibraryItems(user, parentIds, i => i is Series) + .Cast<Series>(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); @@ -54,8 +54,9 @@ namespace MediaBrowser.Server.Implementations.TV throw new ArgumentException("User not found"); } - var items = parentsFolders.SelectMany(i => i.GetRecursiveChildren(user)) - .OfType<Series>(); + var items = parentsFolders + .SelectMany(i => i.GetRecursiveChildren(user, s => s is Series)) + .Cast<Series>(); // Avoid implicitly captured closure var episodes = GetNextUpEpisodes(request, user, items); @@ -63,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.TV return GetResult(episodes, null, request); } - private IEnumerable<BaseItem> GetAllLibraryItems(User user, string[] parentIds) + private IEnumerable<BaseItem> GetAllLibraryItems(User user, string[] parentIds, Func<BaseItem,bool> filter) { if (parentIds.Length > 0) { @@ -71,7 +72,7 @@ namespace MediaBrowser.Server.Implementations.TV { var folder = (Folder)_libraryManager.GetItemById(new Guid(i)); - return folder.GetRecursiveChildren(user); + return folder.GetRecursiveChildren(user, filter); }); } @@ -81,7 +82,7 @@ namespace MediaBrowser.Server.Implementations.TV throw new ArgumentException("User not found"); } - return user.RootFolder.GetRecursiveChildren(user); + return user.RootFolder.GetRecursiveChildren(user, filter); } public IEnumerable<Episode> GetNextUpEpisodes(NextUpQuery request, User user, IEnumerable<Series> series) @@ -126,6 +127,7 @@ namespace MediaBrowser.Server.Implementations.TV { // Get them in display order, then reverse var allEpisodes = series.GetSeasons(user, true, true) + .Where(i => !i.IndexNumber.HasValue || i.IndexNumber.Value != 0) .SelectMany(i => i.GetEpisodes(user, true, true)) .Reverse() .ToList(); diff --git a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs index 2af8f33da..65e5be7a7 100644 --- a/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs +++ b/MediaBrowser.Server.Startup.Common/FFMpeg/FFMpegDownloadInfo.cs @@ -37,10 +37,10 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg switch (environment.SystemArchitecture) { case Architecture.X86_X64: - info.Version = "20140716"; + info.Version = "20150124"; break; case Architecture.X86: - info.Version = "20140923"; + info.Version = "20150124"; break; } break; @@ -128,14 +128,14 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg case Architecture.X86_X64: return new[] { - "http://ffmpeg.gusari.org/static/64bit/ffmpeg.static.64bit.latest.tar.gz", - "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/linux/ffmpeg.static.64bit.2014-07-16.tar.gz" + "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz", + "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/linux/ffmpeg-release-64bit-static.tar.xz" }; case Architecture.X86: return new[] { - "http://ffmpeg.gusari.org/static/32bit/ffmpeg.static.32bit.latest.tar.gz", - "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/linux/ffmpeg.static.32bit.2014-07-16.tar.gz" + "http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-32bit-static.tar.xz", + "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/linux/ffmpeg-release-32bit-static.tar.xz" }; } break; diff --git a/MediaBrowser.XbmcMetadata/EntryPoint.cs b/MediaBrowser.XbmcMetadata/EntryPoint.cs index 38c583bd3..4b89785ae 100644 --- a/MediaBrowser.XbmcMetadata/EntryPoint.cs +++ b/MediaBrowser.XbmcMetadata/EntryPoint.cs @@ -50,8 +50,7 @@ namespace MediaBrowser.XbmcMetadata return; } - var items = _libraryManager.RootFolder.RecursiveChildren; - items = person.GetTaggedItems(items).ToList(); + var items = _libraryManager.RootFolder.GetRecursiveChildren(person.ItemFilter); foreach (var item in items) { diff --git a/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs index c592ec4b7..b8ea74588 100644 --- a/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs @@ -51,8 +51,8 @@ namespace MediaBrowser.XbmcMetadata.Savers } var albums = artist - .RecursiveChildren - .OfType<MusicAlbum>() + .GetRecursiveChildren(i => i is MusicAlbum) + .Cast<MusicAlbum>() .ToList(); AddAlbums(albums, writer); |
