Folder.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  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 override bool IsFolder
  9. {
  10. get
  11. {
  12. return true;
  13. }
  14. }
  15. public bool IsRoot { get; set; }
  16. public bool IsVirtualFolder
  17. {
  18. get
  19. {
  20. return Parent != null && Parent.IsRoot;
  21. }
  22. }
  23. public IEnumerable<BaseItem> Children { get; set; }
  24. /// <summary>
  25. /// Gets allowed children of an item
  26. /// </summary>
  27. public IEnumerable<BaseItem> GetParentalAllowedChildren(User user)
  28. {
  29. return Children.Where(c => c.IsParentalAllowed(user));
  30. }
  31. /// <summary>
  32. /// Gets allowed recursive children of an item
  33. /// </summary>
  34. public IEnumerable<BaseItem> GetParentalAllowedRecursiveChildren(User user)
  35. {
  36. foreach (var item in GetParentalAllowedChildren(user))
  37. {
  38. yield return item;
  39. var subFolder = item as Folder;
  40. if (subFolder != null)
  41. {
  42. foreach (var subitem in subFolder.GetParentalAllowedRecursiveChildren(user))
  43. {
  44. yield return subitem;
  45. }
  46. }
  47. }
  48. }
  49. /// <summary>
  50. /// 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
  51. /// </summary>
  52. public ItemSpecialCounts GetSpecialCounts(User user)
  53. {
  54. ItemSpecialCounts counts = new ItemSpecialCounts();
  55. IEnumerable<BaseItem> recursiveChildren = GetParentalAllowedRecursiveChildren(user);
  56. counts.RecentlyAddedItemCount = GetRecentlyAddedItems(recursiveChildren, user).Count();
  57. counts.RecentlyAddedUnPlayedItemCount = GetRecentlyAddedUnplayedItems(recursiveChildren, user).Count();
  58. counts.InProgressItemCount = GetInProgressItems(recursiveChildren, user).Count();
  59. counts.PlayedPercentage = GetPlayedPercentage(recursiveChildren, user);
  60. return counts;
  61. }
  62. /// <summary>
  63. /// Finds all recursive items within a top-level parent that contain the given genre and are allowed for the current user
  64. /// </summary>
  65. public IEnumerable<BaseItem> GetItemsWithGenre(string genre, User user)
  66. {
  67. return GetParentalAllowedRecursiveChildren(user).Where(f => f.Genres != null && f.Genres.Any(s => s.Equals(genre, StringComparison.OrdinalIgnoreCase)));
  68. }
  69. /// <summary>
  70. /// Finds all recursive items within a top-level parent that contain the given year and are allowed for the current user
  71. /// </summary>
  72. public IEnumerable<BaseItem> GetItemsWithYear(int year, User user)
  73. {
  74. return GetParentalAllowedRecursiveChildren(user).Where(f => f.ProductionYear.HasValue && f.ProductionYear == year);
  75. }
  76. /// <summary>
  77. /// Finds all recursive items within a top-level parent that contain the given studio and are allowed for the current user
  78. /// </summary>
  79. public IEnumerable<BaseItem> GetItemsWithStudio(string studio, User user)
  80. {
  81. return GetParentalAllowedRecursiveChildren(user).Where(f => f.Studios != null && f.Studios.Any(s => s.Equals(studio, StringComparison.OrdinalIgnoreCase)));
  82. }
  83. /// <summary>
  84. /// Finds all recursive items within a top-level parent that the user has marked as a favorite
  85. /// </summary>
  86. public IEnumerable<BaseItem> GetFavoriteItems(User user)
  87. {
  88. return GetParentalAllowedRecursiveChildren(user).Where(c =>
  89. {
  90. UserItemData data = c.GetUserData(user, false);
  91. if (data != null)
  92. {
  93. return data.IsFavorite;
  94. }
  95. return false;
  96. });
  97. }
  98. /// <summary>
  99. /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
  100. /// </summary>
  101. public IEnumerable<BaseItem> GetItemsWithPerson(string person, User user)
  102. {
  103. return GetParentalAllowedRecursiveChildren(user).Where(c =>
  104. {
  105. if (c.People != null)
  106. {
  107. return c.People.ContainsKey(person);
  108. }
  109. return false;
  110. });
  111. }
  112. /// <summary>
  113. /// Finds all recursive items within a top-level parent that contain the given person and are allowed for the current user
  114. /// </summary>
  115. /// <param name="personType">Specify this to limit results to a specific PersonType</param>
  116. public IEnumerable<BaseItem> GetItemsWithPerson(string person, string personType, User user)
  117. {
  118. return GetParentalAllowedRecursiveChildren(user).Where(c =>
  119. {
  120. if (c.People != null)
  121. {
  122. return c.People.ContainsKey(person) && c.People[person].Type.Equals(personType, StringComparison.OrdinalIgnoreCase);
  123. }
  124. return false;
  125. });
  126. }
  127. /// <summary>
  128. /// Gets all recently added items (recursive) within a folder, based on configuration and parental settings
  129. /// </summary>
  130. public IEnumerable<BaseItem> GetRecentlyAddedItems(User user)
  131. {
  132. return GetRecentlyAddedItems(GetParentalAllowedRecursiveChildren(user), user);
  133. }
  134. /// <summary>
  135. /// Gets all recently added unplayed items (recursive) within a folder, based on configuration and parental settings
  136. /// </summary>
  137. public IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(User user)
  138. {
  139. return GetRecentlyAddedUnplayedItems(GetParentalAllowedRecursiveChildren(user), user);
  140. }
  141. /// <summary>
  142. /// Gets all in-progress items (recursive) within a folder
  143. /// </summary>
  144. public IEnumerable<BaseItem> GetInProgressItems(User user)
  145. {
  146. return GetInProgressItems(GetParentalAllowedRecursiveChildren(user), user);
  147. }
  148. /// <summary>
  149. /// Takes a list of items and returns the ones that are recently added
  150. /// </summary>
  151. private static IEnumerable<BaseItem> GetRecentlyAddedItems(IEnumerable<BaseItem> itemSet, User user)
  152. {
  153. return itemSet.Where(i => !(i.IsFolder) && i.IsRecentlyAdded(user));
  154. }
  155. /// <summary>
  156. /// Takes a list of items and returns the ones that are recently added and unplayed
  157. /// </summary>
  158. private static IEnumerable<BaseItem> GetRecentlyAddedUnplayedItems(IEnumerable<BaseItem> itemSet, User user)
  159. {
  160. return GetRecentlyAddedItems(itemSet, user).Where(i =>
  161. {
  162. var userdata = i.GetUserData(user, false);
  163. return userdata == null || userdata.PlayCount == 0;
  164. });
  165. }
  166. /// <summary>
  167. /// Takes a list of items and returns the ones that are in progress
  168. /// </summary>
  169. private static IEnumerable<BaseItem> GetInProgressItems(IEnumerable<BaseItem> itemSet, User user)
  170. {
  171. return itemSet.Where(i =>
  172. {
  173. if (i.IsFolder)
  174. {
  175. return false;
  176. }
  177. var userdata = i.GetUserData(user, false);
  178. return userdata != null && userdata.PlaybackPositionTicks > 0;
  179. });
  180. }
  181. /// <summary>
  182. /// Gets the total played percentage for a set of items
  183. /// </summary>
  184. private static decimal GetPlayedPercentage(IEnumerable<BaseItem> itemSet, User user)
  185. {
  186. itemSet = itemSet.Where(i => !(i.IsFolder));
  187. if (!itemSet.Any())
  188. {
  189. return 0;
  190. }
  191. decimal totalPercent = 0;
  192. foreach (BaseItem item in itemSet)
  193. {
  194. UserItemData data = item.GetUserData(user, false);
  195. if (data == null)
  196. {
  197. continue;
  198. }
  199. if (data.PlayCount > 0)
  200. {
  201. totalPercent += 100;
  202. }
  203. else if (data.PlaybackPositionTicks > 0 && item.RunTimeTicks.HasValue)
  204. {
  205. decimal itemPercent = data.PlaybackPositionTicks;
  206. itemPercent /= item.RunTimeTicks.Value;
  207. totalPercent += itemPercent;
  208. }
  209. }
  210. return totalPercent / itemSet.Count();
  211. }
  212. /// <summary>
  213. /// Marks the item as either played or unplayed
  214. /// </summary>
  215. public override void SetPlayedStatus(User user, bool wasPlayed)
  216. {
  217. base.SetPlayedStatus(user, wasPlayed);
  218. // Now sweep through recursively and update status
  219. foreach (BaseItem item in GetParentalAllowedChildren(user))
  220. {
  221. item.SetPlayedStatus(user, wasPlayed);
  222. }
  223. }
  224. /// <summary>
  225. /// Finds an item by ID, recursively
  226. /// </summary>
  227. public override BaseItem FindItemById(Guid id)
  228. {
  229. var result = base.FindItemById(id);
  230. if (result != null)
  231. {
  232. return result;
  233. }
  234. foreach (BaseItem item in Children)
  235. {
  236. result = item.FindItemById(id);
  237. if (result != null)
  238. {
  239. return result;
  240. }
  241. }
  242. return null;
  243. }
  244. /// <summary>
  245. /// Finds an item by path, recursively
  246. /// </summary>
  247. public BaseItem FindByPath(string path)
  248. {
  249. if (Path.Equals(path, StringComparison.OrdinalIgnoreCase))
  250. {
  251. return this;
  252. }
  253. foreach (BaseItem item in Children)
  254. {
  255. var folder = item as Folder;
  256. if (folder != null)
  257. {
  258. var foundItem = folder.FindByPath(path);
  259. if (foundItem != null)
  260. {
  261. return foundItem;
  262. }
  263. }
  264. else if (item.Path.Equals(path, StringComparison.OrdinalIgnoreCase))
  265. {
  266. return item;
  267. }
  268. }
  269. return null;
  270. }
  271. }
  272. }