ItemResolveArgs.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. using MediaBrowser.Controller.Entities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using MediaBrowser.Controller.IO;
  7. namespace MediaBrowser.Controller.Library
  8. {
  9. /// <summary>
  10. /// These are arguments relating to the file system that are collected once and then referred to
  11. /// whenever needed. Primarily for entity resolution.
  12. /// </summary>
  13. public class ItemResolveArgs : EventArgs
  14. {
  15. /// <summary>
  16. /// Gets the file system children.
  17. /// </summary>
  18. /// <value>The file system children.</value>
  19. public IEnumerable<WIN32_FIND_DATA> FileSystemChildren
  20. {
  21. get { return FileSystemDictionary.Values; }
  22. }
  23. /// <summary>
  24. /// Gets or sets the file system dictionary.
  25. /// </summary>
  26. /// <value>The file system dictionary.</value>
  27. public Dictionary<string, WIN32_FIND_DATA> FileSystemDictionary { get; set; }
  28. /// <summary>
  29. /// Gets or sets the parent.
  30. /// </summary>
  31. /// <value>The parent.</value>
  32. public Folder Parent { get; set; }
  33. /// <summary>
  34. /// Gets or sets the file info.
  35. /// </summary>
  36. /// <value>The file info.</value>
  37. public WIN32_FIND_DATA FileInfo { get; set; }
  38. /// <summary>
  39. /// Gets or sets the path.
  40. /// </summary>
  41. /// <value>The path.</value>
  42. public string Path { get; set; }
  43. /// <summary>
  44. /// Gets a value indicating whether this instance is directory.
  45. /// </summary>
  46. /// <value><c>true</c> if this instance is directory; otherwise, <c>false</c>.</value>
  47. public bool IsDirectory
  48. {
  49. get
  50. {
  51. return FileInfo.dwFileAttributes.HasFlag(FileAttributes.Directory);
  52. }
  53. }
  54. /// <summary>
  55. /// Gets a value indicating whether this instance is hidden.
  56. /// </summary>
  57. /// <value><c>true</c> if this instance is hidden; otherwise, <c>false</c>.</value>
  58. public bool IsHidden
  59. {
  60. get
  61. {
  62. return FileInfo.IsHidden;
  63. }
  64. }
  65. /// <summary>
  66. /// Gets a value indicating whether this instance is system file.
  67. /// </summary>
  68. /// <value><c>true</c> if this instance is system file; otherwise, <c>false</c>.</value>
  69. public bool IsSystemFile
  70. {
  71. get
  72. {
  73. return FileInfo.IsSystemFile;
  74. }
  75. }
  76. /// <summary>
  77. /// Gets a value indicating whether this instance is vf.
  78. /// </summary>
  79. /// <value><c>true</c> if this instance is vf; otherwise, <c>false</c>.</value>
  80. public bool IsVf
  81. {
  82. // we should be considered a virtual folder if we are a child of one of the children of the system root folder.
  83. // this is a bit of a trick to determine that... the directory name of a sub-child of the root will start with
  84. // the root but not be equal to it
  85. get
  86. {
  87. if (!IsDirectory)
  88. {
  89. return false;
  90. }
  91. var parentDir = FileInfo.Path != null ? System.IO.Path.GetDirectoryName(FileInfo.Path) ?? string.Empty : string.Empty;
  92. return (parentDir.Length > Kernel.Instance.ApplicationPaths.RootFolderPath.Length
  93. && parentDir.StartsWith(Kernel.Instance.ApplicationPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase));
  94. }
  95. }
  96. /// <summary>
  97. /// Gets a value indicating whether this instance is physical root.
  98. /// </summary>
  99. /// <value><c>true</c> if this instance is physical root; otherwise, <c>false</c>.</value>
  100. public bool IsPhysicalRoot
  101. {
  102. get
  103. {
  104. return IsDirectory && Path.Equals(Kernel.Instance.ApplicationPaths.RootFolderPath, StringComparison.OrdinalIgnoreCase);
  105. }
  106. }
  107. /// <summary>
  108. /// Gets a value indicating whether this instance is root.
  109. /// </summary>
  110. /// <value><c>true</c> if this instance is root; otherwise, <c>false</c>.</value>
  111. public bool IsRoot
  112. {
  113. get
  114. {
  115. return Parent == null;
  116. }
  117. }
  118. /// <summary>
  119. /// Gets or sets the additional locations.
  120. /// </summary>
  121. /// <value>The additional locations.</value>
  122. private List<string> AdditionalLocations { get; set; }
  123. /// <summary>
  124. /// Adds the additional location.
  125. /// </summary>
  126. /// <param name="path">The path.</param>
  127. /// <exception cref="System.ArgumentNullException"></exception>
  128. public void AddAdditionalLocation(string path)
  129. {
  130. if (string.IsNullOrEmpty(path))
  131. {
  132. throw new ArgumentNullException();
  133. }
  134. if (AdditionalLocations == null)
  135. {
  136. AdditionalLocations = new List<string>();
  137. }
  138. AdditionalLocations.Add(path);
  139. }
  140. /// <summary>
  141. /// Gets the physical locations.
  142. /// </summary>
  143. /// <value>The physical locations.</value>
  144. public IEnumerable<string> PhysicalLocations
  145. {
  146. get
  147. {
  148. var paths = string.IsNullOrWhiteSpace(Path) ? new string[] {} : new[] {Path};
  149. return AdditionalLocations == null ? paths : paths.Concat(AdditionalLocations);
  150. }
  151. }
  152. /// <summary>
  153. /// Store these to reduce disk access in Resolvers
  154. /// </summary>
  155. /// <value>The metadata file dictionary.</value>
  156. private Dictionary<string, WIN32_FIND_DATA> MetadataFileDictionary { get; set; }
  157. /// <summary>
  158. /// Gets the metadata files.
  159. /// </summary>
  160. /// <value>The metadata files.</value>
  161. public IEnumerable<WIN32_FIND_DATA> MetadataFiles
  162. {
  163. get
  164. {
  165. if (MetadataFileDictionary != null)
  166. {
  167. return MetadataFileDictionary.Values;
  168. }
  169. return new WIN32_FIND_DATA[] {};
  170. }
  171. }
  172. /// <summary>
  173. /// Adds the metadata file.
  174. /// </summary>
  175. /// <param name="path">The path.</param>
  176. /// <exception cref="System.IO.FileNotFoundException"></exception>
  177. public void AddMetadataFile(string path)
  178. {
  179. var file = FileSystem.GetFileData(path);
  180. if (!file.HasValue)
  181. {
  182. throw new FileNotFoundException(path);
  183. }
  184. AddMetadataFile(file.Value);
  185. }
  186. /// <summary>
  187. /// Adds the metadata file.
  188. /// </summary>
  189. /// <param name="fileInfo">The file info.</param>
  190. public void AddMetadataFile(WIN32_FIND_DATA fileInfo)
  191. {
  192. AddMetadataFiles(new[] { fileInfo });
  193. }
  194. /// <summary>
  195. /// Adds the metadata files.
  196. /// </summary>
  197. /// <param name="files">The files.</param>
  198. /// <exception cref="System.ArgumentNullException"></exception>
  199. public void AddMetadataFiles(IEnumerable<WIN32_FIND_DATA> files)
  200. {
  201. if (files == null)
  202. {
  203. throw new ArgumentNullException();
  204. }
  205. if (MetadataFileDictionary == null)
  206. {
  207. MetadataFileDictionary = new Dictionary<string, WIN32_FIND_DATA>(StringComparer.OrdinalIgnoreCase);
  208. }
  209. foreach (var file in files)
  210. {
  211. MetadataFileDictionary[file.cFileName] = file;
  212. }
  213. }
  214. /// <summary>
  215. /// Gets the name of the file system entry by.
  216. /// </summary>
  217. /// <param name="name">The name.</param>
  218. /// <returns>System.Nullable{WIN32_FIND_DATA}.</returns>
  219. /// <exception cref="System.ArgumentNullException"></exception>
  220. public WIN32_FIND_DATA? GetFileSystemEntryByName(string name)
  221. {
  222. if (string.IsNullOrEmpty(name))
  223. {
  224. throw new ArgumentNullException();
  225. }
  226. return GetFileSystemEntryByPath(System.IO.Path.Combine(Path, name));
  227. }
  228. /// <summary>
  229. /// Gets the file system entry by path.
  230. /// </summary>
  231. /// <param name="path">The path.</param>
  232. /// <returns>System.Nullable{WIN32_FIND_DATA}.</returns>
  233. /// <exception cref="System.ArgumentNullException"></exception>
  234. public WIN32_FIND_DATA? GetFileSystemEntryByPath(string path)
  235. {
  236. if (string.IsNullOrEmpty(path))
  237. {
  238. throw new ArgumentNullException();
  239. }
  240. if (FileSystemDictionary != null)
  241. {
  242. WIN32_FIND_DATA entry;
  243. if (FileSystemDictionary.TryGetValue(path, out entry))
  244. {
  245. return entry;
  246. }
  247. }
  248. return null;
  249. }
  250. /// <summary>
  251. /// Gets the meta file by path.
  252. /// </summary>
  253. /// <param name="path">The path.</param>
  254. /// <returns>System.Nullable{WIN32_FIND_DATA}.</returns>
  255. /// <exception cref="System.ArgumentNullException"></exception>
  256. public WIN32_FIND_DATA? GetMetaFileByPath(string path)
  257. {
  258. if (string.IsNullOrEmpty(path))
  259. {
  260. throw new ArgumentNullException();
  261. }
  262. if (MetadataFileDictionary != null)
  263. {
  264. WIN32_FIND_DATA entry;
  265. if (MetadataFileDictionary.TryGetValue(System.IO.Path.GetFileName(path), out entry))
  266. {
  267. return entry;
  268. }
  269. }
  270. return GetFileSystemEntryByPath(path);
  271. }
  272. /// <summary>
  273. /// Gets the name of the meta file by.
  274. /// </summary>
  275. /// <param name="name">The name.</param>
  276. /// <returns>System.Nullable{WIN32_FIND_DATA}.</returns>
  277. /// <exception cref="System.ArgumentNullException"></exception>
  278. public WIN32_FIND_DATA? GetMetaFileByName(string name)
  279. {
  280. if (string.IsNullOrEmpty(name))
  281. {
  282. throw new ArgumentNullException();
  283. }
  284. if (MetadataFileDictionary != null)
  285. {
  286. WIN32_FIND_DATA entry;
  287. if (MetadataFileDictionary.TryGetValue(name, out entry))
  288. {
  289. return entry;
  290. }
  291. }
  292. return GetFileSystemEntryByName(name);
  293. }
  294. /// <summary>
  295. /// Determines whether [contains meta file by name] [the specified name].
  296. /// </summary>
  297. /// <param name="name">The name.</param>
  298. /// <returns><c>true</c> if [contains meta file by name] [the specified name]; otherwise, <c>false</c>.</returns>
  299. public bool ContainsMetaFileByName(string name)
  300. {
  301. return GetMetaFileByName(name).HasValue;
  302. }
  303. /// <summary>
  304. /// Determines whether [contains file system entry by name] [the specified name].
  305. /// </summary>
  306. /// <param name="name">The name.</param>
  307. /// <returns><c>true</c> if [contains file system entry by name] [the specified name]; otherwise, <c>false</c>.</returns>
  308. public bool ContainsFileSystemEntryByName(string name)
  309. {
  310. return GetFileSystemEntryByName(name).HasValue;
  311. }
  312. #region Equality Overrides
  313. /// <summary>
  314. /// Determines whether the specified <see cref="System.Object" /> is equal to this instance.
  315. /// </summary>
  316. /// <param name="obj">The object to compare with the current object.</param>
  317. /// <returns><c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.</returns>
  318. public override bool Equals(object obj)
  319. {
  320. return (Equals(obj as ItemResolveArgs));
  321. }
  322. /// <summary>
  323. /// Returns a hash code for this instance.
  324. /// </summary>
  325. /// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
  326. public override int GetHashCode()
  327. {
  328. return Path.GetHashCode();
  329. }
  330. /// <summary>
  331. /// Equalses the specified args.
  332. /// </summary>
  333. /// <param name="args">The args.</param>
  334. /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
  335. protected bool Equals(ItemResolveArgs args)
  336. {
  337. if (args != null)
  338. {
  339. if (args.Path == null && Path == null) return true;
  340. return args.Path != null && args.Path.Equals(Path, StringComparison.OrdinalIgnoreCase);
  341. }
  342. return false;
  343. }
  344. #endregion
  345. }
  346. }