diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs index 25a7ff9ec..5a787c0e4 100644 --- a/MediaBrowser.Api/ApiService.cs +++ b/MediaBrowser.Api/ApiService.cs @@ -6,6 +6,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Controller; using MediaBrowser.Model.DTO; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Api { @@ -26,10 +27,12 @@ namespace MediaBrowser.Api /// public static BaseItemContainer GetSerializationObject(BaseItem item, bool includeChildren, Guid userId) { + User user = Kernel.Instance.Users.First(u => u.Id == userId); + BaseItemContainer wrapper = new BaseItemContainer() { Item = item, - UserItemData = Kernel.Instance.GetUserItemData(userId, item.Id), + UserItemData = user.GetItemData(item.Id), Type = item.GetType().Name, IsFolder = (item is Folder) }; @@ -57,7 +60,7 @@ namespace MediaBrowser.Api if (folder != null) { - wrapper.Children = Kernel.Instance.GetParentalAllowedChildren(folder, userId).Select(c => GetSerializationObject(c, false, userId)); + wrapper.Children = folder.GetParentalAllowedChildren(user).Select(c => GetSerializationObject(c, false, userId)); } // Attach People by transforming them into BaseItemPerson (DTO) diff --git a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs index 902871fa1..dd20d2e42 100644 --- a/MediaBrowser.Api/HttpHandlers/GenresHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/GenresHandler.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller; using MediaBrowser.Model.DTO; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Api.HttpHandlers { @@ -13,8 +15,9 @@ namespace MediaBrowser.Api.HttpHandlers { Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; Guid userId = Guid.Parse(QueryString["userid"]); + User user = Kernel.Instance.Users.First(u => u.Id == userId); - return Kernel.Instance.GetAllGenres(parent, userId); + return Kernel.Instance.GetAllGenres(parent, user); } } } diff --git a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs index b3d85687f..b4c13540c 100644 --- a/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/ItemListHandler.cs @@ -5,6 +5,7 @@ using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller; using MediaBrowser.Model.DTO; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Api.HttpHandlers { @@ -24,34 +25,36 @@ namespace MediaBrowser.Api.HttpHandlers get { Folder parent = ApiService.GetItemById(ItemId) as Folder; + + User user = Kernel.Instance.Users.First(u => u.Id == UserId); if (ListType.Equals("inprogressitems", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetInProgressItems(parent, UserId); + return parent.GetInProgressItems(user); } else if (ListType.Equals("recentlyaddeditems", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetRecentlyAddedItems(parent, UserId); + return parent.GetRecentlyAddedItems(user); } else if (ListType.Equals("recentlyaddedunplayeditems", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetRecentlyAddedUnplayedItems(parent, UserId); + return parent.GetRecentlyAddedUnplayedItems(user); } else if (ListType.Equals("itemswithgenre", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetItemsWithGenre(parent, QueryString["name"], UserId); + return parent.GetItemsWithGenre(QueryString["name"], user); } else if (ListType.Equals("itemswithyear", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetItemsWithYear(parent, int.Parse(QueryString["year"]), UserId); + return parent.GetItemsWithYear(int.Parse(QueryString["year"]), user); } else if (ListType.Equals("itemswithstudio", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetItemsWithStudio(parent, QueryString["name"], UserId); + return parent.GetItemsWithStudio(QueryString["name"], user); } else if (ListType.Equals("itemswithperson", StringComparison.OrdinalIgnoreCase)) { - return Kernel.Instance.GetItemsWithPerson(parent, QueryString["name"], UserId); + return parent.GetItemsWithPerson(QueryString["name"], null, user); } throw new InvalidOperationException(); diff --git a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs index b33988b3e..ffd69006d 100644 --- a/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/StudiosHandler.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller; using MediaBrowser.Model.DTO; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Api.HttpHandlers { @@ -13,8 +15,9 @@ namespace MediaBrowser.Api.HttpHandlers { Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; Guid userId = Guid.Parse(QueryString["userid"]); - - return Kernel.Instance.GetAllStudios(parent, userId); + User user = Kernel.Instance.Users.First(u => u.Id == userId); + + return Kernel.Instance.GetAllStudios(parent, user); } } } diff --git a/MediaBrowser.Api/HttpHandlers/YearsHandler.cs b/MediaBrowser.Api/HttpHandlers/YearsHandler.cs index 8a58a2a19..801244b0d 100644 --- a/MediaBrowser.Api/HttpHandlers/YearsHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/YearsHandler.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using MediaBrowser.Common.Net.Handlers; using MediaBrowser.Controller; using MediaBrowser.Model.DTO; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Users; namespace MediaBrowser.Api.HttpHandlers { @@ -13,8 +15,9 @@ namespace MediaBrowser.Api.HttpHandlers { Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder; Guid userId = Guid.Parse(QueryString["userid"]); + User user = Kernel.Instance.Users.First(u => u.Id == userId); - return Kernel.Instance.GetAllYears(parent, userId); + return Kernel.Instance.GetAllYears(parent, user); } } } diff --git a/MediaBrowser.Controller/Kernel.cs b/MediaBrowser.Controller/Kernel.cs index 375b11a59..c11a40750 100644 --- a/MediaBrowser.Controller/Kernel.cs +++ b/MediaBrowser.Controller/Kernel.cs @@ -197,167 +197,16 @@ namespace MediaBrowser.Controller return RootFolder.FindById(id); } - /// - /// Determines if an item is allowed for a given user - /// - public bool IsParentalAllowed(BaseItem item, Guid userId) - { - // not yet implemented - return true; - } - - /// - /// Gets allowed children of an item - /// - public IEnumerable GetParentalAllowedChildren(Folder folder, Guid userId) - { - return folder.Children.Where(i => IsParentalAllowed(i, userId)); - } - - /// - /// Gets allowed recursive children of an item - /// - public IEnumerable GetParentalAllowedRecursiveChildren(Folder folder, Guid userId) - { - foreach (var item in GetParentalAllowedChildren(folder, userId)) - { - yield return item; - - var subFolder = item as Folder; - - if (subFolder != null) - { - foreach (var subitem in GetParentalAllowedRecursiveChildren(subFolder, userId)) - { - yield return subitem; - } - } - } - } - - /// - /// Gets user data for an item, if there is any - /// - public UserItemData GetUserItemData(Guid userId, Guid itemId) - { - User user = Users.First(u => u.Id == userId); - - if (user.ItemData.ContainsKey(itemId)) - { - return user.ItemData[itemId]; - } - - return null; - } - - /// - /// Gets all recently added items (recursive) within a folder, based on configuration and parental settings - /// - public IEnumerable GetRecentlyAddedItems(Folder parent, Guid userId) - { - DateTime now = DateTime.Now; - - User user = Users.First(u => u.Id == userId); - - return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < user.RecentItemDays); - } - - /// - /// Gets all recently added unplayed items (recursive) within a folder, based on configuration and parental settings - /// - public IEnumerable GetRecentlyAddedUnplayedItems(Folder parent, Guid userId) - { - return GetRecentlyAddedItems(parent, userId).Where(i => - { - var userdata = GetUserItemData(userId, i.Id); - - return userdata == null || userdata.PlayCount == 0; - }); - } - - /// - /// Gets all in-progress items (recursive) within a folder - /// - public IEnumerable GetInProgressItems(Folder parent, Guid userId) - { - return GetParentalAllowedRecursiveChildren(parent, userId).Where(i => - { - if (i is Folder) - { - return false; - } - - var userdata = GetUserItemData(userId, i.Id); - - return userdata != null && userdata.PlaybackPosition.Ticks > 0; - }); - } - - /// - /// Finds all recursive items within a top-level parent that contain the given studio and are allowed for the current user - /// - public IEnumerable GetItemsWithStudio(Folder parent, string studio, Guid userId) - { - return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.Studios != null && f.Studios.Any(s => s.Equals(studio, StringComparison.OrdinalIgnoreCase))); - } - - /// - /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user - /// - /// Specify this to limit results to a specific PersonType - public IEnumerable GetItemsWithPerson(Folder parent, string person, PersonType? personType, Guid userId) - { - return GetParentalAllowedRecursiveChildren(parent, userId).Where(c => - { - if (c.People != null) - { - if (personType.HasValue) - { - return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.PersonType == personType.Value); - } - else - { - return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase)); - } - } - - return false; - }); - } - /// - /// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user - /// - public IEnumerable GetItemsWithGenre(Folder parent, string genre, Guid userId) - { - return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.Genres != null && f.Genres.Any(s => s.Equals(genre, StringComparison.OrdinalIgnoreCase))); - } - - /// - /// Finds all recursive items within a top-level parent that contain the given year and are allowed for the current user - /// - public IEnumerable GetItemsWithYear(Folder parent, int year, Guid userId) - { - return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.ProductionYear.HasValue && f.ProductionYear == year); - } - - /// - /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user - /// - public IEnumerable GetItemsWithPerson(Folder parent, string personName, Guid userId) - { - return GetParentalAllowedRecursiveChildren(parent, userId).Where(f => f.People != null && f.People.Any(s => s.Name.Equals(personName, StringComparison.OrdinalIgnoreCase))); - } - /// /// Gets all years from all recursive children of a folder /// The CategoryInfo class is used to keep track of the number of times each year appears /// - public IEnumerable> GetAllYears(Folder parent, Guid userId) + public IEnumerable> GetAllYears(Folder parent, User user) { Dictionary data = new Dictionary(); // Get all the allowed recursive children - IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); + IEnumerable allItems = parent.GetParentalAllowedRecursiveChildren(user); foreach (var item in allItems) { @@ -403,12 +252,12 @@ namespace MediaBrowser.Controller /// Gets all studios from all recursive children of a folder /// The CategoryInfo class is used to keep track of the number of times each studio appears /// - public IEnumerable> GetAllStudios(Folder parent, Guid userId) + public IEnumerable> GetAllStudios(Folder parent, User user) { Dictionary data = new Dictionary(); // Get all the allowed recursive children - IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); + IEnumerable allItems = parent.GetParentalAllowedRecursiveChildren(user); foreach (var item in allItems) { @@ -457,12 +306,12 @@ namespace MediaBrowser.Controller /// Gets all genres from all recursive children of a folder /// The CategoryInfo class is used to keep track of the number of times each genres appears /// - public IEnumerable> GetAllGenres(Folder parent, Guid userId) + public IEnumerable> GetAllGenres(Folder parent, User user) { Dictionary data = new Dictionary(); // Get all the allowed recursive children - IEnumerable allItems = Kernel.Instance.GetParentalAllowedRecursiveChildren(parent, userId); + IEnumerable allItems = parent.GetParentalAllowedRecursiveChildren(user); foreach (var item in allItems) { diff --git a/MediaBrowser.Model/Entities/BaseItem.cs b/MediaBrowser.Model/Entities/BaseItem.cs index d2745e460..c9d5b936b 100644 --- a/MediaBrowser.Model/Entities/BaseItem.cs +++ b/MediaBrowser.Model/Entities/BaseItem.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Model.Entities { @@ -101,5 +102,13 @@ namespace MediaBrowser.Model.Entities { SetProviderId(provider.ToString(), value); } + + /// + /// Determines if a given user has access to this item + /// + internal bool IsParentalAllowed(User user) + { + return true; + } } } diff --git a/MediaBrowser.Model/Entities/Folder.cs b/MediaBrowser.Model/Entities/Folder.cs index 293d7a990..98f1d8229 100644 --- a/MediaBrowser.Model/Entities/Folder.cs +++ b/MediaBrowser.Model/Entities/Folder.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; +using MediaBrowser.Model.Users; namespace MediaBrowser.Model.Entities { @@ -18,6 +21,124 @@ namespace MediaBrowser.Model.Entities [IgnoreDataMember] public BaseItem[] Children { get; set; } + /// + /// Gets allowed children of an item + /// + public IEnumerable GetParentalAllowedChildren(User user) + { + return Children.Where(c => c.IsParentalAllowed(user)); + } + + /// + /// Gets allowed recursive children of an item + /// + public IEnumerable GetParentalAllowedRecursiveChildren(User user) + { + foreach (var item in GetParentalAllowedChildren(user)) + { + yield return item; + + var subFolder = item as Folder; + + if (subFolder != null) + { + foreach (var subitem in subFolder.GetParentalAllowedRecursiveChildren(user)) + { + yield return subitem; + } + } + } + } + + /// + /// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user + /// + public IEnumerable GetItemsWithGenre(string genre, User user) + { + return GetParentalAllowedRecursiveChildren(user).Where(f => f.Genres != null && f.Genres.Any(s => s.Equals(genre, StringComparison.OrdinalIgnoreCase))); + } + + /// + /// Finds all recursive items within a top-level parent that contain the given year and are allowed for the current user + /// + public IEnumerable GetItemsWithYear(int year, User user) + { + return GetParentalAllowedRecursiveChildren(user).Where(f => f.ProductionYear.HasValue && f.ProductionYear == year); + } + + /// + /// Finds all recursive items within a top-level parent that contain the given studio and are allowed for the current user + /// + public IEnumerable GetItemsWithStudio(string studio, User user) + { + return GetParentalAllowedRecursiveChildren(user).Where(f => f.Studios != null && f.Studios.Any(s => s.Equals(studio, StringComparison.OrdinalIgnoreCase))); + } + + /// + /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user + /// + /// Specify this to limit results to a specific PersonType + public IEnumerable GetItemsWithPerson(string person, PersonType? personType, User user) + { + return GetParentalAllowedRecursiveChildren(user).Where(c => + { + if (c.People != null) + { + if (personType.HasValue) + { + return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.PersonType == personType.Value); + } + else + { + return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase)); + } + } + + return false; + }); + } + + /// + /// Gets all recently added items (recursive) within a folder, based on configuration and parental settings + /// + public IEnumerable GetRecentlyAddedItems(User user) + { + DateTime now = DateTime.Now; + + return GetParentalAllowedRecursiveChildren(user).Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < user.RecentItemDays); + } + + /// + /// Gets all recently added unplayed items (recursive) within a folder, based on configuration and parental settings + /// + public IEnumerable GetRecentlyAddedUnplayedItems(User user) + { + return GetRecentlyAddedItems(user).Where(i => + { + var userdata = user.GetItemData(i.Id); + + return userdata == null || userdata.PlayCount == 0; + }); + } + + /// + /// Gets all in-progress items (recursive) within a folder + /// + public IEnumerable GetInProgressItems(User user) + { + return GetParentalAllowedRecursiveChildren(user).Where(i => + { + if (i is Folder) + { + return false; + } + + var userdata = user.GetItemData(i.Id); + + return userdata != null && userdata.PlaybackPosition.Ticks > 0; + }); + } + /// /// Finds an item by ID, recursively /// diff --git a/MediaBrowser.Model/Users/User.cs b/MediaBrowser.Model/Users/User.cs index 85776fb8b..dcef153c5 100644 --- a/MediaBrowser.Model/Users/User.cs +++ b/MediaBrowser.Model/Users/User.cs @@ -17,5 +17,18 @@ namespace MediaBrowser.Model.Users { RecentItemDays = 14; } + + /// + /// Gets user data for an item, if there is any + /// + public UserItemData GetItemData(Guid itemId) + { + if (ItemData.ContainsKey(itemId)) + { + return ItemData[itemId]; + } + + return null; + } } }