using System; using System.Collections.Generic; using System.Linq; namespace MediaBrowser.Model.Entities { public class Folder : BaseItem { public override bool IsFolder { get { return true; } } public bool IsRoot { get; set; } public IEnumerable 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; } } } } /// /// Since it can be slow to make all of these calculations at once, this method will provide a way to get them all back together /// public ItemSpecialCounts GetSpecialCounts(User user) { ItemSpecialCounts counts = new ItemSpecialCounts(); IEnumerable recursiveChildren = GetParentalAllowedRecursiveChildren(user); counts.RecentlyAddedItemCount = GetRecentlyAddedItems(recursiveChildren, user).Count(); counts.RecentlyAddedUnPlayedItemCount = GetRecentlyAddedUnplayedItems(recursiveChildren, user).Count(); counts.InProgressItemCount = GetInProgressItems(recursiveChildren, user).Count(); counts.PlayedPercentage = GetPlayedPercentage(recursiveChildren, user); return counts; } /// /// 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 /// public IEnumerable GetItemsWithPerson(string person, User user) { return GetParentalAllowedRecursiveChildren(user).Where(c => { if (c.People != null) { 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 person and are allowed for the current user /// /// Specify this to limit results to a specific PersonType public IEnumerable GetItemsWithPerson(string person, string personType, User user) { return GetParentalAllowedRecursiveChildren(user).Where(c => { if (c.People != null) { return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.Type == personType); } return false; }); } /// /// Gets all recently added items (recursive) within a folder, based on configuration and parental settings /// public IEnumerable GetRecentlyAddedItems(User user) { return GetRecentlyAddedItems(GetParentalAllowedRecursiveChildren(user), user); } /// /// Gets all recently added unplayed items (recursive) within a folder, based on configuration and parental settings /// public IEnumerable GetRecentlyAddedUnplayedItems(User user) { return GetRecentlyAddedUnplayedItems(GetParentalAllowedRecursiveChildren(user), user); } /// /// Gets all in-progress items (recursive) within a folder /// public IEnumerable GetInProgressItems(User user) { return GetInProgressItems(GetParentalAllowedRecursiveChildren(user), user); } private static IEnumerable GetRecentlyAddedItems(IEnumerable itemSet, User user) { return itemSet.Where(i => !(i.IsFolder) && i.IsRecentlyAdded(user)); } private static IEnumerable GetRecentlyAddedUnplayedItems(IEnumerable itemSet, User user) { return GetRecentlyAddedItems(itemSet, user).Where(i => { var userdata = i.GetUserData(user); return userdata == null || userdata.PlayCount == 0; }); } private static IEnumerable GetInProgressItems(IEnumerable itemSet, User user) { return itemSet.Where(i => { if (i.IsFolder) { return false; } var userdata = i.GetUserData(user); return userdata != null && userdata.PlaybackPositionTicks > 0; }); } private static decimal GetPlayedPercentage(IEnumerable itemSet, User user) { itemSet = itemSet.Where(i => !(i.IsFolder)); if (!itemSet.Any()) { return 0; } decimal totalPercent = 0; foreach (BaseItem item in itemSet) { UserItemData data = item.GetUserData(user); if (data == null) { continue; } if (data.PlayCount > 0) { totalPercent += 100; } else if (data.PlaybackPositionTicks > 0 && item.RunTimeTicks.HasValue) { decimal itemPercent = data.PlaybackPositionTicks; itemPercent /= item.RunTimeTicks.Value; totalPercent += itemPercent; } } return totalPercent / itemSet.Count(); } /// /// Finds an item by ID, recursively /// public override BaseItem FindItemById(Guid id) { var result = base.FindItemById(id); if (result != null) { return result; } foreach (BaseItem item in Children) { result = item.FindItemById(id); if (result != null) { return result; } } return null; } /// /// Finds an item by path, recursively /// public BaseItem FindByPath(string path) { if (Path.Equals(path, StringComparison.OrdinalIgnoreCase)) { return this; } foreach (BaseItem item in Children) { var folder = item as Folder; if (folder != null) { var foundItem = folder.FindByPath(path); if (foundItem != null) { return foundItem; } } else if (item.Path.Equals(path, StringComparison.OrdinalIgnoreCase)) { return item; } } return null; } } }