Folder.cs 12 KB

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