DriveService.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using Masuit.MyBlogs.Core.Extensions.DriveHelpers;
  2. using Masuit.MyBlogs.Core.Models.Drive;
  3. using Microsoft.Graph;
  4. namespace Masuit.MyBlogs.Core.Infrastructure.Drive
  5. {
  6. public class DriveService : IDriveService
  7. {
  8. private readonly IDriveAccountService _accountService;
  9. private readonly GraphServiceClient _graph;
  10. private readonly DriveContext _driveContext;
  11. public DriveService(IDriveAccountService accountService, DriveContext driveContext)
  12. {
  13. _accountService = accountService;
  14. _graph = accountService.Graph;
  15. _driveContext = driveContext;
  16. }
  17. /// <summary>
  18. /// 获取根目录的所有项目
  19. /// </summary>
  20. /// <returns></returns>
  21. public async Task<List<DriveFile>> GetRootItems(string siteName, bool showHiddenFolders)
  22. {
  23. var drive = siteName != "onedrive" ? _graph.Sites[GetSiteId(siteName)].Drive : _graph.Me.Drive;
  24. var request = drive.Root.Children.Request();
  25. var result = await request.GetAsync();
  26. var files = await GetItems(result, siteName, showHiddenFolders);
  27. return files.OrderByDescending(f => f.CreatedTime).ToList();
  28. }
  29. /// <summary>
  30. /// 根据路径获取文件夹下所有项目
  31. /// </summary>
  32. /// <param name="path"></param>
  33. /// <param name="siteName"></param>
  34. /// <param name="showHiddenFolders"></param>
  35. /// <returns></returns>
  36. public async Task<List<DriveFile>> GetDriveItemsByPath(string path, string siteName, bool showHiddenFolders)
  37. {
  38. var drive = siteName != "onedrive" ? _graph.Sites[GetSiteId(siteName)].Drive : _graph.Me.Drive;
  39. var result = await drive.Root.ItemWithPath(path).Children.Request().GetAsync();
  40. var files = await GetItems(result, siteName, showHiddenFolders);
  41. files = files.OrderByDescending(f => f.CreatedTime).ToList();
  42. return files;
  43. }
  44. /// <summary>
  45. /// 根据路径获取项目
  46. /// </summary>
  47. /// <param name="path"></param>
  48. /// <returns></returns>
  49. public async Task<DriveFile> GetDriveItemByPath(string path, string siteName = "onedrive")
  50. {
  51. string[] imgArray = { ".png", ".jpg", ".jpeg", ".bmp", ".webp" };
  52. var extension = Path.GetExtension(path);
  53. var drive = siteName != "onedrive" ? _graph.Sites[GetSiteId(siteName)].Drive : _graph.Me.Drive;
  54. //这么写是因为:分块上传图片后直接获取会报错。
  55. if (imgArray.Contains(extension))
  56. {
  57. await drive.Root.ItemWithPath(path).Thumbnails.Request().GetAsync();
  58. }
  59. var result = await drive.Root.ItemWithPath(path).Request().GetAsync();
  60. return GetItem(result);
  61. }
  62. /// <summary>
  63. /// 获得上传url
  64. /// </summary>
  65. /// <param name="path"></param>
  66. /// <param name="siteName"></param>
  67. /// <returns></returns>
  68. public async Task<string> GetUploadUrl(string path, string siteName = "onedrive")
  69. {
  70. var drive = siteName != "onedrive" ? _graph.Sites[GetSiteId(siteName)].Drive : _graph.Me.Drive;
  71. var requestUrl = drive.Root.ItemWithPath(path).CreateUploadSession().Request().RequestUrl;
  72. var apiCallHelper = new ProtectedApiCallHelper(new HttpClient());
  73. var uploadUrl = "";
  74. await apiCallHelper.CallWebApiAndProcessResultASync(requestUrl, _accountService.GetToken(), o =>
  75. {
  76. uploadUrl = o["uploadUrl"].ToString();
  77. }, ProtectedApiCallHelper.Method.Post);
  78. return uploadUrl;
  79. }
  80. #region PrivateMethod
  81. private DriveFile GetItem(DriveItem result)
  82. {
  83. var file = new DriveFile()
  84. {
  85. CreatedTime = result.CreatedDateTime,
  86. Name = result.Name,
  87. Size = result.Size,
  88. Id = result.Id
  89. };
  90. if (result.AdditionalData != null)
  91. {
  92. //可能是文件夹
  93. if (result.AdditionalData.TryGetValue("@microsoft.graph.downloadUrl", out var downloadUrl))
  94. {
  95. file.DownloadUrl = ReplaceCDNUrls(downloadUrl.ToString());
  96. }
  97. }
  98. return file;
  99. }
  100. private async Task<List<DriveFile>> GetItems(IDriveItemChildrenCollectionPage result, string siteName = "onedrive", bool showHiddenFolders = false)
  101. {
  102. var files = new List<DriveFile>();
  103. foreach (var item in result)
  104. {
  105. //要隐藏文件
  106. if (!showHiddenFolders)
  107. {
  108. //跳过隐藏的文件
  109. var hiddenFolders = _driveContext.Sites.Single(site => site.Name == siteName).HiddenFolders;
  110. if (hiddenFolders != null)
  111. {
  112. if (hiddenFolders.Any(str => str == item.Name))
  113. {
  114. continue;
  115. }
  116. }
  117. }
  118. var file = new DriveFile()
  119. {
  120. CreatedTime = item.CreatedDateTime,
  121. Name = item.Name,
  122. Size = item.Size,
  123. Id = item.Id
  124. };
  125. if (item.AdditionalData != null)
  126. {
  127. //可能是文件夹
  128. if (item.AdditionalData.TryGetValue("@microsoft.graph.downloadUrl", out var downloadUrl))
  129. {
  130. file.DownloadUrl = ReplaceCDNUrls(downloadUrl.ToString());
  131. }
  132. }
  133. files.Add(file);
  134. }
  135. if (result.Count == 200)
  136. {
  137. files.AddRange(await GetItems(await result.NextPageRequest.GetAsync(), siteName, showHiddenFolders));
  138. }
  139. return files;
  140. }
  141. /// <summary>
  142. /// 根据名称返回siteid
  143. /// </summary>
  144. /// <returns></returns>
  145. private string GetSiteId(string siteName)
  146. {
  147. var site = _driveContext.Sites.SingleOrDefault(s => s.Name == siteName);
  148. return site?.SiteId;
  149. }
  150. private string ReplaceCDNUrls(string downloadUrl)
  151. {
  152. if (OneDriveConfiguration.CDNUrls.Length > 0)
  153. {
  154. return OneDriveConfiguration.CDNUrls.Select(item => item.Split(";", StringSplitOptions.RemoveEmptyEntries)).Where(strings => strings.Length > 1).Aggregate(downloadUrl, (current, strings) => current.Replace(strings[0], strings[1..][DateTime.Now.Second % (strings.Length - 1)]));
  155. }
  156. return downloadUrl;
  157. }
  158. #endregion PrivateMethod
  159. }
  160. }