浏览代码

implemented filtering of ibn items based on like/dislike/favorite

Luke Pulverenti 12 年之前
父节点
当前提交
cdd1a03299

+ 110 - 18
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -70,9 +70,13 @@ namespace MediaBrowser.Api.UserLibrary
             items = FilterItems(request, items, user);
             items = FilterItems(request, items, user);
 
 
             var extractedItems = GetAllItems(request, items, user);
             var extractedItems = GetAllItems(request, items, user);
-            var ibnItemsArray = SortItems(request, extractedItems).ToArray();
-      
-            IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> ibnItems = ibnItemsArray;
+
+            extractedItems = FilterItems(request, extractedItems, user);
+            extractedItems = SortItems(request, extractedItems);
+
+            var ibnItemsArray = extractedItems.ToArray();
+
+            IEnumerable<IbnStub<TItemType>> ibnItems = ibnItemsArray;
 
 
             var result = new ItemsResult
             var result = new ItemsResult
             {
             {
@@ -104,23 +108,74 @@ namespace MediaBrowser.Api.UserLibrary
             return result;
             return result;
         }
         }
 
 
+        /// <summary>
+        /// Filters the items.
+        /// </summary>
+        /// <param name="request">The request.</param>
+        /// <param name="items">The items.</param>
+        /// <param name="user">The user.</param>
+        /// <returns>IEnumerable{IbnStub}.</returns>
+        private IEnumerable<IbnStub<TItemType>> FilterItems(GetItemsByName request, IEnumerable<IbnStub<TItemType>> items, User user)
+        {
+            var filters = request.GetFilters().ToList();
+
+            if (filters.Count == 0)
+            {
+                return items;
+            }
+
+            items = items.AsParallel();
+
+            if (filters.Contains(ItemFilter.Dislikes))
+            {
+                items = items.Where(i =>
+                {
+                    var userdata = i.GetUserItemData(UserDataRepository, user.Id).Result;
+
+                    return userdata != null && userdata.Likes.HasValue && !userdata.Likes.Value;
+                });
+            }
+
+            if (filters.Contains(ItemFilter.Likes))
+            {
+                items = items.Where(i =>
+                {
+                    var userdata = i.GetUserItemData(UserDataRepository, user.Id).Result;
+
+                    return userdata != null && userdata.Likes.HasValue && userdata.Likes.Value;
+                });
+            }
+
+            if (filters.Contains(ItemFilter.IsFavorite))
+            {
+                items = items.Where(i =>
+                {
+                    var userdata = i.GetUserItemData(UserDataRepository, user.Id).Result;
+
+                    return userdata != null && userdata.Likes.HasValue && userdata.IsFavorite;
+                });
+            }
+            
+            return items.AsEnumerable();
+        }
+        
         /// <summary>
         /// <summary>
         /// Sorts the items.
         /// Sorts the items.
         /// </summary>
         /// </summary>
         /// <param name="request">The request.</param>
         /// <param name="request">The request.</param>
         /// <param name="items">The items.</param>
         /// <param name="items">The items.</param>
         /// <returns>IEnumerable{BaseItem}.</returns>
         /// <returns>IEnumerable{BaseItem}.</returns>
-        private IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> SortItems(GetItemsByName request, IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> items)
+        private IEnumerable<IbnStub<TItemType>> SortItems(GetItemsByName request, IEnumerable<IbnStub<TItemType>> items)
         {
         {
             if (string.Equals(request.SortBy, "SortName", StringComparison.OrdinalIgnoreCase))
             if (string.Equals(request.SortBy, "SortName", StringComparison.OrdinalIgnoreCase))
             {
             {
                 if (request.SortOrder.HasValue && request.SortOrder.Value == Model.Entities.SortOrder.Descending)
                 if (request.SortOrder.HasValue && request.SortOrder.Value == Model.Entities.SortOrder.Descending)
                 {
                 {
-                    items = items.OrderByDescending(i => i.Item1);
+                    items = items.OrderByDescending(i => i.Name);
                 }
                 }
                 else
                 else
                 {
                 {
-                    items = items.OrderBy(i => i.Item1);
+                    items = items.OrderBy(i => i.Name);
                 }
                 }
             }
             }
 
 
@@ -160,14 +215,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="items">The items.</param>
         /// <param name="items">The items.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected abstract IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user);
-
-        /// <summary>
-        /// Gets the entity.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>Task{BaseItem}.</returns>
-        protected abstract Task<TItemType> GetEntity(string name);
+        protected abstract IEnumerable<IbnStub<TItemType>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user);
 
 
         /// <summary>
         /// <summary>
         /// Gets the dto.
         /// Gets the dto.
@@ -176,17 +224,17 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <param name="fields">The fields.</param>
         /// <param name="fields">The fields.</param>
         /// <returns>Task{DtoBaseItem}.</returns>
         /// <returns>Task{DtoBaseItem}.</returns>
-        private async Task<BaseItemDto> GetDto(Tuple<string, Func<IEnumerable<BaseItem>>> stub, User user, List<ItemFields> fields)
+        private async Task<BaseItemDto> GetDto(IbnStub<TItemType> stub, User user, List<ItemFields> fields)
         {
         {
             BaseItem item;
             BaseItem item;
 
 
             try
             try
             {
             {
-                item = await GetEntity(stub.Item1).ConfigureAwait(false);
+                item = await stub.GetItem().ConfigureAwait(false);
             }
             }
             catch (IOException ex)
             catch (IOException ex)
             {
             {
-                Logger.ErrorException("Error getting IBN item {0}", ex, stub.Item1);
+                Logger.ErrorException("Error getting IBN item {0}", ex, stub.Name);
                 return null;
                 return null;
             }
             }
 
 
@@ -194,7 +242,7 @@ namespace MediaBrowser.Api.UserLibrary
 
 
             if (fields.Contains(ItemFields.ItemCounts))
             if (fields.Contains(ItemFields.ItemCounts))
             {
             {
-                var items = stub.Item2().ToList();
+                var items = stub.Items;
 
 
                 dto.ChildCount = items.Count;
                 dto.ChildCount = items.Count;
                 dto.RecentlyAddedItemCount = items.Count(i => i.IsRecentlyAdded(user));
                 dto.RecentlyAddedItemCount = items.Count(i => i.IsRecentlyAdded(user));
@@ -216,4 +264,48 @@ namespace MediaBrowser.Api.UserLibrary
         [ApiMember(Name = "SortBy", Description = "Optional. Options: SortName", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         [ApiMember(Name = "SortBy", Description = "Optional. Options: SortName", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string SortBy { get; set; }
         public string SortBy { get; set; }
     }
     }
+
+    public class IbnStub<T>
+        where T : BaseItem
+    {
+        private readonly Func<IEnumerable<BaseItem>> _childItemsFunction;
+        private List<BaseItem> _childItems;
+
+        private readonly Func<string,Task<T>> _itemFunction;
+        private Task<T> _itemTask;
+        
+        public string Name;
+
+        public BaseItem Item;
+        private Task<UserItemData> _userData;
+
+        public List<BaseItem> Items
+        {
+            get { return _childItems ?? (_childItems = _childItemsFunction().ToList()); }
+        }
+
+        public Task<T> GetItem()
+        {
+            return _itemTask ?? (_itemTask = _itemFunction(Name));
+        }
+
+        public async Task<UserItemData> GetUserItemData(IUserDataRepository repo, Guid userId)
+        {
+            var item = await GetItem().ConfigureAwait(false);
+
+            if (_userData == null)
+            {
+                _userData = repo.GetUserData(userId, item.GetUserDataKey());
+            }
+
+            return await _userData.ConfigureAwait(false);
+        }
+
+        public IbnStub(string name, Func<IEnumerable<BaseItem>> childItems, Func<string,Task<T>> item)
+        {
+            Name = name;
+            _childItemsFunction = childItems;
+            _itemFunction = item;
+        }
+    }
 }
 }

+ 3 - 3
MediaBrowser.Api/UserLibrary/GenresService.cs

@@ -48,14 +48,14 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="items">The items.</param>
         /// <param name="items">The items.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
+        protected override IEnumerable<IbnStub<Genre>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
         {
         {
             var itemsList = items.Where(i => i.Genres != null).ToList();
             var itemsList = items.Where(i => i.Genres != null).ToList();
 
 
             return itemsList
             return itemsList
                 .SelectMany(i => i.Genres)
                 .SelectMany(i => i.Genres)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
-                .Select(name => new Tuple<string, Func<IEnumerable<BaseItem>>>(name, () => itemsList.Where(i => i.Genres.Contains(name, StringComparer.OrdinalIgnoreCase))));
+                .Select(name => new IbnStub<Genre>(name, () => itemsList.Where(i => i.Genres.Contains(name, StringComparer.OrdinalIgnoreCase)), GetEntity));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -63,7 +63,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// </summary>
         /// <param name="name">The name.</param>
         /// <param name="name">The name.</param>
         /// <returns>Task{Genre}.</returns>
         /// <returns>Task{Genre}.</returns>
-        protected override Task<Genre> GetEntity(string name)
+        protected Task<Genre> GetEntity(string name)
         {
         {
             return LibraryManager.GetGenre(name);
             return LibraryManager.GetGenre(name);
         }
         }

+ 4 - 4
MediaBrowser.Api/UserLibrary/PersonsService.cs

@@ -53,7 +53,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="items">The items.</param>
         /// <param name="items">The items.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
+        protected override IEnumerable<IbnStub<Person>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
         {
         {
             var inputPersonTypes = ((GetPersons) request).PersonTypes;
             var inputPersonTypes = ((GetPersons) request).PersonTypes;
             var personTypes = string.IsNullOrEmpty(inputPersonTypes) ? new string[] { } : inputPersonTypes.Split(',');
             var personTypes = string.IsNullOrEmpty(inputPersonTypes) ? new string[] { } : inputPersonTypes.Split(',');
@@ -67,7 +67,7 @@ namespace MediaBrowser.Api.UserLibrary
                 .Select(i => i.Name)
                 .Select(i => i.Name)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
 
 
-                .Select(name => new Tuple<string, Func<IEnumerable<BaseItem>>>(name, () =>
+                .Select(name => new IbnStub<Person>(name, () =>
                 {
                 {
                     if (personTypes.Length == 0)
                     if (personTypes.Length == 0)
                     {
                     {
@@ -75,7 +75,7 @@ namespace MediaBrowser.Api.UserLibrary
                     }
                     }
 
 
                     return itemsList.Where(i => i.People.Any(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && personTypes.Contains(p.Type ?? string.Empty, StringComparer.OrdinalIgnoreCase)));
                     return itemsList.Where(i => i.People.Any(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase) && personTypes.Contains(p.Type ?? string.Empty, StringComparer.OrdinalIgnoreCase)));
-                })
+                }, GetEntity)
             );
             );
         }
         }
 
 
@@ -102,7 +102,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// </summary>
         /// <param name="name">The name.</param>
         /// <param name="name">The name.</param>
         /// <returns>Task{Genre}.</returns>
         /// <returns>Task{Genre}.</returns>
-        protected override Task<Person> GetEntity(string name)
+        protected Task<Person> GetEntity(string name)
         {
         {
             return LibraryManager.GetPerson(name);
             return LibraryManager.GetPerson(name);
         }
         }

+ 3 - 3
MediaBrowser.Api/UserLibrary/StudiosService.cs

@@ -48,14 +48,14 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="items">The items.</param>
         /// <param name="items">The items.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
+        protected override IEnumerable<IbnStub<Studio>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
         {
         {
             var itemsList = items.Where(i => i.Studios != null).ToList();
             var itemsList = items.Where(i => i.Studios != null).ToList();
 
 
             return itemsList
             return itemsList
                 .SelectMany(i => i.Studios)
                 .SelectMany(i => i.Studios)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
-                .Select(name => new Tuple<string, Func<IEnumerable<BaseItem>>>(name, () => itemsList.Where(i => i.Studios.Contains(name, StringComparer.OrdinalIgnoreCase))));
+                .Select(name => new IbnStub<Studio>(name, () => itemsList.Where(i => i.Studios.Contains(name, StringComparer.OrdinalIgnoreCase)), GetEntity));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -63,7 +63,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// </summary>
         /// <param name="name">The name.</param>
         /// <param name="name">The name.</param>
         /// <returns>Task{Studio}.</returns>
         /// <returns>Task{Studio}.</returns>
-        protected override Task<Studio> GetEntity(string name)
+        protected Task<Studio> GetEntity(string name)
         {
         {
             return LibraryManager.GetStudio(name);
             return LibraryManager.GetStudio(name);
         }
         }

+ 3 - 3
MediaBrowser.Api/UserLibrary/YearsService.cs

@@ -54,14 +54,14 @@ namespace MediaBrowser.Api.UserLibrary
         /// <param name="items">The items.</param>
         /// <param name="items">The items.</param>
         /// <param name="user">The user.</param>
         /// <param name="user">The user.</param>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
         /// <returns>IEnumerable{Tuple{System.StringFunc{System.Int32}}}.</returns>
-        protected override IEnumerable<Tuple<string, Func<IEnumerable<BaseItem>>>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
+        protected override IEnumerable<IbnStub<Year>> GetAllItems(GetItemsByName request, IEnumerable<BaseItem> items, User user)
         {
         {
             var itemsList = items.Where(i => i.ProductionYear != null).ToList();
             var itemsList = items.Where(i => i.ProductionYear != null).ToList();
 
 
             return itemsList
             return itemsList
                 .Select(i => i.ProductionYear.Value)
                 .Select(i => i.ProductionYear.Value)
                 .Distinct()
                 .Distinct()
-                .Select(year => new Tuple<string, Func<IEnumerable<BaseItem>>>(year.ToString(UsCulture), () => itemsList.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year)));
+                .Select(year => new IbnStub<Year>(year.ToString(UsCulture), () => itemsList.Where(i => i.ProductionYear.HasValue && i.ProductionYear.Value == year), GetEntity));
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -69,7 +69,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// </summary>
         /// </summary>
         /// <param name="name">The name.</param>
         /// <param name="name">The name.</param>
         /// <returns>Task{Studio}.</returns>
         /// <returns>Task{Studio}.</returns>
-        protected override Task<Year> GetEntity(string name)
+        protected Task<Year> GetEntity(string name)
         {
         {
             return LibraryManager.GetYear(int.Parse(name, UsCulture));
             return LibraryManager.GetYear(int.Parse(name, UsCulture));
         }
         }

+ 1 - 2
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.Localization;