diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index b06007c787..ce36dd2ac9 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -139,28 +139,19 @@ namespace MediaBrowser.Api.Movies typeof(Trailer).Name, //typeof(LiveTvProgram).Name }, - // IsMovie = true + // IsMovie = true }; var parentIds = string.IsNullOrWhiteSpace(request.ParentId) ? new string[] { } : new[] { request.ParentId }; var movies = _libraryManager.GetItemList(query, parentIds) .OrderBy(i => (int)i.SourceType); - var listEligibleForCategories = new List(); var listEligibleForSuggestion = new List(); var list = movies.ToList(); - listEligibleForCategories.AddRange(list); listEligibleForSuggestion.AddRange(list); - listEligibleForCategories = listEligibleForCategories - // Exclude trailers from the suggestion categories - .Where(i => i is Movie) - .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) - .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) - .ToList(); - listEligibleForSuggestion = listEligibleForSuggestion .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) .DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString(), StringComparer.OrdinalIgnoreCase) @@ -170,7 +161,7 @@ namespace MediaBrowser.Api.Movies dtoOptions.Fields = request.GetItemFields().ToList(); - var result = GetRecommendationCategories(user, listEligibleForCategories, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); + var result = GetRecommendationCategories(user, request.ParentId, listEligibleForSuggestion, request.CategoryLimit, request.ItemLimit, dtoOptions); return ToOptimizedResult(result); } @@ -233,44 +224,43 @@ namespace MediaBrowser.Api.Movies return result; } - private IEnumerable GetRecommendationCategories(User user, List allMoviesForCategories, List allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions) + private IEnumerable GetRecommendationCategories(User user, string parentId, List allMovies, int categoryLimit, int itemLimit, DtoOptions dtoOptions) { var categories = new List(); - var recentlyPlayedMovies = allMoviesForCategories - .Select(i => + var parentIds = string.IsNullOrWhiteSpace(parentId) ? new string[] { } : new[] { parentId }; + var query = new InternalItemsQuery(user) + { + IncludeItemTypes = new[] { - var userdata = _userDataRepository.GetUserData(user, i); - return new Tuple(i, userdata.Played, userdata.LastPlayedDate ?? DateTime.MinValue); - }) - .Where(i => i.Item2) - .OrderByDescending(i => i.Item3) - .Select(i => i.Item1) - .ToList(); + typeof(Movie).Name, + //typeof(Trailer).Name, + //typeof(LiveTvProgram).Name + }, + // IsMovie = true + SortBy = new[] { ItemSortBy.DatePlayed, ItemSortBy.Random }, + SortOrder = SortOrder.Descending, + Limit = 7 + }; - var excludeFromLiked = recentlyPlayedMovies.Take(10); - var likedMovies = allMovies - .Select(i => - { - var score = 0; - var userData = _userDataRepository.GetUserData(user, i); + var recentlyPlayedMovies = _libraryManager.GetItemList(query, parentIds).ToList(); - if (userData.IsFavorite) - { - score = 2; - } - else - { - score = userData.Likes.HasValue ? userData.Likes.Value ? 1 : -1 : 0; - } + var likedMovies = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name + }, + IsMovie = true, + SortBy = new[] { ItemSortBy.Random }, + SortOrder = SortOrder.Descending, + Limit = 10, + IsFavoriteOrLiked = true, + ExcludeItemIds = recentlyPlayedMovies.Select(i => i.Id.ToString("N")).ToArray() - return new Tuple(i, score); - }) - .OrderByDescending(i => i.Item2) - .ThenBy(i => Guid.NewGuid()) - .Where(i => i.Item2 > 0) - .Select(i => i.Item1) - .Where(i => !excludeFromLiked.Contains(i)); + }, parentIds); var mostRecentMovies = recentlyPlayedMovies.Take(6).ToList(); // Get recently played directors @@ -286,8 +276,8 @@ namespace MediaBrowser.Api.Movies var similarToRecentlyPlayed = GetSimilarTo(user, allMovies, recentlyPlayedMovies.Take(7).OrderBy(i => Guid.NewGuid()), itemLimit, dtoOptions, RecommendationType.SimilarToRecentlyPlayed).GetEnumerator(); var similarToLiked = GetSimilarTo(user, allMovies, likedMovies, itemLimit, dtoOptions, RecommendationType.SimilarToLikedItem).GetEnumerator(); - var hasDirectorFromRecentlyPlayed = GetWithDirector(user, allMovies, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator(); - var hasActorFromRecentlyPlayed = GetWithActor(user, allMovies, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator(); + var hasDirectorFromRecentlyPlayed = GetWithDirector(user, recentDirectors, itemLimit, dtoOptions, RecommendationType.HasDirectorFromRecentlyPlayed).GetEnumerator(); + var hasActorFromRecentlyPlayed = GetWithActor(user, recentActors, itemLimit, dtoOptions, RecommendationType.HasActorFromRecentlyPlayed).GetEnumerator(); var categoryTypes = new List> { @@ -330,23 +320,34 @@ namespace MediaBrowser.Api.Movies return categories.OrderBy(i => i.RecommendationType).ThenBy(i => Guid.NewGuid()); } - private IEnumerable GetWithDirector(User user, List allMovies, IEnumerable directors, int itemLimit, DtoOptions dtoOptions, RecommendationType type) + private IEnumerable GetWithDirector(User user, IEnumerable names, int itemLimit, DtoOptions dtoOptions, RecommendationType type) { - var userId = user.Id; - - foreach (var director in directors) + foreach (var name in names) { - var items = allMovies - .Where(i => _libraryManager.GetPeople(i).Any(p => string.Equals(p.Type, PersonType.Director, StringComparison.OrdinalIgnoreCase) && string.Equals(p.Name, director, StringComparison.OrdinalIgnoreCase))) - .Take(itemLimit) - .ToList(); + var items = _libraryManager.GetItemList(new InternalItemsQuery(user) + { + Person = name, + // Account for duplicates by imdb id, since the database doesn't support this yet + Limit = itemLimit + 2, + PersonTypes = new[] { PersonType.Director }, + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name + }, + IsMovie = true + + }).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) + .Take(itemLimit) + .ToList(); if (items.Count > 0) { yield return new RecommendationDto { - BaselineItemName = director, - CategoryId = director.GetMD5().ToString("N"), + BaselineItemName = name, + CategoryId = name.GetMD5().ToString("N"), RecommendationType = type, Items = _dtoService.GetBaseItemDtos(items, dtoOptions, user).ToArray() }; @@ -354,20 +355,26 @@ namespace MediaBrowser.Api.Movies } } - private IEnumerable GetWithActor(User user, List allMovies, IEnumerable names, int itemLimit, DtoOptions dtoOptions, RecommendationType type) + private IEnumerable GetWithActor(User user, IEnumerable names, int itemLimit, DtoOptions dtoOptions, RecommendationType type) { foreach (var name in names) { - var itemsWithActor = _libraryManager.GetItemIds(new InternalItemsQuery(user) + var items = _libraryManager.GetItemList(new InternalItemsQuery(user) { - Person = name - - }); - - var items = allMovies - .Where(i => itemsWithActor.Contains(i.Id)) - .Take(itemLimit) - .ToList(); + Person = name, + // Account for duplicates by imdb id, since the database doesn't support this yet + Limit = itemLimit + 2, + IncludeItemTypes = new[] + { + typeof(Movie).Name, + typeof(Trailer).Name, + typeof(LiveTvProgram).Name + }, + IsMovie = true + + }).DistinctBy(i => i.GetProviderId(MetadataProviders.Imdb) ?? Guid.NewGuid().ToString("N")) + .Take(itemLimit) + .ToList(); if (items.Count > 0) { diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs index 7e38d7ed9f..f3f05a08fa 100644 --- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs +++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs @@ -53,6 +53,7 @@ namespace MediaBrowser.Controller.Entities public string Person { get; set; } public string[] PersonIds { get; set; } public string[] ItemIds { get; set; } + public string[] ExcludeItemIds { get; set; } public string AdjacentTo { get; set; } public string[] PersonTypes { get; set; } @@ -166,6 +167,7 @@ namespace MediaBrowser.Controller.Entities PersonIds = new string[] { }; ChannelIds = new string[] { }; ItemIds = new string[] { }; + ExcludeItemIds = new string[] { }; AncestorIds = new string[] { }; TopParentIds = new string[] { }; ExcludeTags = new string[] { };