Folder.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace MediaBrowser.Model.Entities
  5. {
  6. public class Folder : BaseItem
  7. {
  8. public bool IsRoot { get; set; }
  9. public bool IsVirtualFolder
  10. {
  11. get
  12. {
  13. return Parent != null && Parent.IsRoot;
  14. }
  15. }
  16. public BaseItem[] Children { get; set; }
  17. /// <summary>
  18. /// Gets allowed children of an item
  19. /// </summary>
  20. public IEnumerable<BaseItem> GetParentalAllowedChildren(User user)
  21. {
  22. return Children.Where(c => c.IsParentalAllowed(user));
  23. }
  24. /// <summary>
  25. /// Gets allowed recursive children of an item
  26. /// </summary>
  27. public IEnumerable<BaseItem> GetParentalAllowedRecursiveChildren(User user)
  28. {
  29. foreach (var item in GetParentalAllowedChildren(user))
  30. {
  31. yield return item;
  32. var subFolder = item as Folder;
  33. if (subFolder != null)
  34. {
  35. foreach (var subitem in subFolder.GetParentalAllowedRecursiveChildren(user))
  36. {
  37. yield return subitem;
  38. }
  39. }
  40. }
  41. }
  42. /// <summary>
  43. /// 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
  44. /// </summary>
  45. public ItemSpecialCounts GetSpecialCounts(User user)
  46. {
  47. ItemSpecialCounts counts = new ItemSpecialCounts();
  48. IEnumerable<BaseItem> recursiveChildren = GetParentalAllowedRecursiveChildren(user);
  49. counts.RecentlyAddedItemCount = GetRecentlyAddedItems(recursiveChildren, user).Count();
  50. counts.RecentlyAddedUnPlayedItemCount = GetRecentlyAddedUnplayedItems(recursiveChildren, user).Count();
  51. counts.InProgressItemCount = GetInProgressItems(recursiveChildren, user).Count();
  52. counts.WatchedPercentage = GetWatchedPercentage(recursiveChildren, user);
  53. return counts;
  54. }
  55. /// <summary>
  56. /// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user
  57. /// </summary>
  58. public IEnumerable<BaseItem> GetItemsWithGenre(string genre, User user)
  59. {
  60. return GetParentalAllowedRecursiveChildren(user).Where(f => f.Genres != null && f.Genres.Any(s => s.Equals(genre, StringComparison.OrdinalIgnoreCase)));
  61. }
  62. /// <summary>
  63. /// Finds all recursive items within a top-level parent that contain the given year and are allowed for the current user
  64. /// </summary>
  65. public IEnumerable<BaseItem> GetItemsWithYear(int year, User user)
  66. {
  67. return GetParentalAllowedRecursiveChildren(user).Where(f => f.ProductionYear.HasValue && f.ProductionYear == year);
  68. }
  69. /// <summary>
  70. /// Finds all recursive items within a top-level parent that contain the given studio and are allowed for the current user
  71. /// </summary>
  72. public IEnumerable<BaseItem> GetItemsWithStudio(string studio, User user)
  73. {
  74. return GetParentalAllowedRecursiveChildren(user).Where(f => f.Studios != null && f.Studios.Any(s => s.Equals(studio, StringComparison.OrdinalIgnoreCase)));
  75. }
  76. /// <summary>
  77. /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
  78. /// </summary>
  79. public IEnumerable<BaseItem> GetItemsWithPerson(string person, User user)
  80. {
  81. return GetParentalAllowedRecursiveChildren(user).Where(c =>
  82. {
  83. if (c.People != null)
  84. {
  85. return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase));
  86. }
  87. return false;
  88. });
  89. }
  90. /// <summary>
  91. /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
  92. /// </summary>
  93. /// <param name="personType">Specify this to limit results to a specific PersonType</param>
  94. public IEnumerable<BaseItem> GetItemsWithPerson(string person, string personType, User user)
  95. {
  96. return GetParentalAllowedRecursiveChildren(user).Where(c =>
  97. {
  98. if (c.People != null)
  99. {
  100. return c.People.Any(p => p.Name.Equals(person, StringComparison.OrdinalIgnoreCase) && p.Type == personType);
  101. }
  102. return false;
  103. });
  104. }
  105. /// <summary>
  106. /// Gets all recently added items (recursive) within a folder, based on configuration and parental settings
  107. /// </summary>
  108. public IEnumerable<BaseItem> GetRecentlyAddedItems(User user)
  109. {
  110. return GetRecentlyAddedItems(GetParentalAllowedRecursiveChildren(user), user);
  111. }
  112. /// <summary>
  113. /// Gets all recently added unplayed items (recursive) within a folder, based on configuration and parental settings
  114. /// </summary>
  115. public IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(User user)
  116. {
  117. return GetRecentlyAddedUnplayedItems(GetParentalAllowedRecursiveChildren(user), user);
  118. }
  119. /// <summary>
  120. /// Gets all in-progress items (recursive) within a folder
  121. /// </summary>
  122. public IEnumerable<BaseItem> GetInProgressItems(User user)
  123. {
  124. return GetInProgressItems(GetParentalAllowedRecursiveChildren(user), user);
  125. }
  126. private static IEnumerable<BaseItem> GetRecentlyAddedItems(IEnumerable<BaseItem> itemSet, User user)
  127. {
  128. DateTime now = DateTime.Now;
  129. return itemSet.Where(i => !(i is Folder) && (now - i.DateCreated).TotalDays < user.RecentItemDays);
  130. }
  131. private static IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(IEnumerable<BaseItem> itemSet, User user)
  132. {
  133. return GetRecentlyAddedItems(itemSet, user).Where(i =>
  134. {
  135. var userdata = i.GetUserData(user);
  136. return userdata == null || userdata.PlayCount == 0;
  137. });
  138. }
  139. private static IEnumerable<BaseItem> GetInProgressItems(IEnumerable<BaseItem> itemSet, User user)
  140. {
  141. return itemSet.Where(i =>
  142. {
  143. if (i is Folder)
  144. {
  145. return false;
  146. }
  147. var userdata = i.GetUserData(user);
  148. return userdata != null && userdata.PlaybackPositionTicks > 0;
  149. });
  150. }
  151. private static decimal GetWatchedPercentage(IEnumerable<BaseItem> itemSet, User user)
  152. {
  153. itemSet = itemSet.Where(i => !(i is Folder));
  154. if (!itemSet.Any())
  155. {
  156. return 0;
  157. }
  158. decimal totalPercent = 0;
  159. foreach (BaseItem item in itemSet)
  160. {
  161. UserItemData data = item.GetUserData(user);
  162. if (data == null)
  163. {
  164. continue;
  165. }
  166. if (data.PlayCount > 0)
  167. {
  168. totalPercent += 100;
  169. }
  170. else if (data.PlaybackPositionTicks > 0 && item.RunTimeTicks.HasValue)
  171. {
  172. decimal itemPercent = data.PlaybackPositionTicks;
  173. itemPercent /= item.RunTimeTicks.Value;
  174. totalPercent += itemPercent;
  175. }
  176. }
  177. return totalPercent / itemSet.Count();
  178. }
  179. /// <summary>
  180. /// Finds an item by ID, recursively
  181. /// </summary>
  182. public override BaseItem FindItemById(Guid id)
  183. {
  184. var result = base.FindItemById(id);
  185. if (result != null)
  186. {
  187. return result;
  188. }
  189. foreach (BaseItem item in Children)
  190. {
  191. result = item.FindItemById(id);
  192. if (result != null)
  193. {
  194. return result;
  195. }
  196. }
  197. return null;
  198. }
  199. /// <summary>
  200. /// Finds an item by path, recursively
  201. /// </summary>
  202. public BaseItem FindByPath(string path)
  203. {
  204. if (Path.Equals(path, StringComparison.OrdinalIgnoreCase))
  205. {
  206. return this;
  207. }
  208. foreach (BaseItem item in Children)
  209. {
  210. var folder = item as Folder;
  211. if (folder != null)
  212. {
  213. var foundItem = folder.FindByPath(path);
  214. if (foundItem != null)
  215. {
  216. return foundItem;
  217. }
  218. }
  219. else if (item.Path.Equals(path, StringComparison.OrdinalIgnoreCase))
  220. {
  221. return item;
  222. }
  223. }
  224. return null;
  225. }
  226. }
  227. }