PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/module/ASC.Migration/GoogleWorkspace/GoogleWorkspaceMigration.cs

https://gitlab.com/rekby-archive/onlyoffice-CommunityServer
C# | 234 lines | 201 code | 18 blank | 15 comment | 23 complexity | e3bf1c021e1f47e4a82e76c1b7c8922c MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.IO.Compression;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using ASC.Core;
  9. using ASC.Migration.Core;
  10. using ASC.Migration.Core.Models;
  11. using ASC.Migration.Core.Models.Api;
  12. using ASC.Migration.GoogleWorkspace.Models;
  13. using ASC.Migration.Resources;
  14. namespace ASC.Migration.GoogleWorkspace
  15. {
  16. [ApiMigrator("GoogleWorkspace")]
  17. public class GoogleWorkspaceMigration : AbstractMigration<GwsMigrationInfo, GwsMigratingUser, GwsMigratingContacts, GwsMigratingCalendar, GwsMigratingFiles, GwsMigratingMail>
  18. {
  19. private string[] takeouts;
  20. public override void Init(string path, CancellationToken cancellationToken)
  21. {
  22. this.cancellationToken = cancellationToken;
  23. List<string> tempTakeouts = new List<string>();
  24. var files = Directory.GetFiles(path);
  25. if (!files.Any() || !files.Any(f => f.EndsWith(".zip")))
  26. {
  27. throw new Exception("Folder must not be empty and should contain .zip files.");
  28. }
  29. foreach(var item in files)
  30. {
  31. if(item.EndsWith(".zip"))
  32. {
  33. tempTakeouts.Add(item);
  34. }
  35. }
  36. takeouts = tempTakeouts.ToArray();
  37. migrationInfo = new GwsMigrationInfo();
  38. migrationInfo.MigratorName = this.GetType().CustomAttributes.First().ConstructorArguments.First().Value.ToString();
  39. }
  40. public override Task<MigrationApiInfo> Parse()
  41. {
  42. ReportProgress(0, MigrationResource.StartOfDataProcessing);
  43. var progressStep = 100 / takeouts.Length;
  44. var i = 1;
  45. foreach (var takeout in takeouts)
  46. {
  47. if (cancellationToken.IsCancellationRequested) { ReportProgress(100, MigrationResource.MigrationCanceled); return null; }
  48. ReportProgress(GetProgress() + progressStep, MigrationResource.DataProcessing + $" {takeout} ({i++}/{takeouts.Length})");
  49. var tmpFolder = Path.Combine(TempPath.GetTempPath(), Path.GetFileNameWithoutExtension(takeout));
  50. try
  51. {
  52. ZipFile.ExtractToDirectory(takeout, tmpFolder);
  53. var rootFolder = Path.Combine(tmpFolder, "Takeout");
  54. if (!Directory.Exists(rootFolder))
  55. {
  56. throw new Exception("Takeout zip does not contain root 'Takeout' folder.");
  57. }
  58. var directories = Directory.GetDirectories(rootFolder);
  59. if (directories.Length == 1 && directories[0].Split(Path.DirectorySeparatorChar).Last() == "Groups")
  60. {
  61. var group = new GWSMigratingGroups(rootFolder, Log);
  62. group.Parse();
  63. if(group.Module.MigrationModule != null)
  64. {
  65. migrationInfo.Groups.Add(group);
  66. if (!migrationInfo.Modules.Exists(x => x.MigrationModule == group.Module.MigrationModule))
  67. {
  68. migrationInfo.Modules.Add(new MigrationModules(group.Module.MigrationModule, group.Module.Module));
  69. }
  70. }
  71. }
  72. else
  73. {
  74. var user = new GwsMigratingUser(takeout, rootFolder, Log);
  75. user.Parse();
  76. foreach (var element in user.ModulesList)
  77. {
  78. if (!migrationInfo.Modules.Exists(x => x.MigrationModule == element.MigrationModule))
  79. {
  80. migrationInfo.Modules.Add(new MigrationModules(element.MigrationModule, element.Module));
  81. }
  82. }
  83. migrationInfo.Users.Add(takeout, user);
  84. }
  85. }
  86. catch (Exception ex)
  87. {
  88. migrationInfo.failedArchives.Add(Path.GetFileName(takeout));
  89. Log($"Couldn't parse user from {Path.GetFileNameWithoutExtension(takeout)} archive", ex);
  90. }
  91. finally
  92. {
  93. if (Directory.Exists(tmpFolder))
  94. {
  95. Directory.Delete(tmpFolder, true);
  96. }
  97. }
  98. }
  99. ReportProgress(100, MigrationResource.DataProcessingCompleted);
  100. return Task.FromResult(migrationInfo.ToApiInfo());
  101. }
  102. public override Task Migrate(MigrationApiInfo migrationApiInfo)
  103. {
  104. ReportProgress(0, MigrationResource.PreparingForMigration);
  105. migrationInfo.Merge(migrationApiInfo);
  106. var usersForImport = migrationInfo.Users
  107. .Where(u => u.Value.ShouldImport)
  108. .Select(u => u.Value);
  109. importedUsers = new List<Guid>();
  110. var failedUsers = new List<GwsMigratingUser>();
  111. var usersCount = usersForImport.Count();
  112. var progressStep = 25 / usersCount;
  113. // Add all users first
  114. var i = 1;
  115. foreach (var user in usersForImport)
  116. {
  117. if (cancellationToken.IsCancellationRequested) { ReportProgress(100, MigrationResource.MigrationCanceled); return null; }
  118. ReportProgress(GetProgress() + progressStep, String.Format(MigrationResource.UserMigration, user.DisplayName, i++, usersCount));
  119. try
  120. {
  121. user.dataŠ”hange(migrationApiInfo.Users.Find(element => element.Key == user.Key));
  122. user.Migrate();
  123. importedUsers.Add(user.Guid);
  124. }
  125. catch (Exception ex)
  126. {
  127. failedUsers.Add(user);
  128. Log($"Couldn't migrate user {user.DisplayName} ({user.Email})", ex);
  129. }
  130. }
  131. var groupsForImport = migrationInfo.Groups
  132. .Where(g => g.ShouldImport)
  133. .Select(g => g);
  134. var groupsCount = groupsForImport.Count();
  135. if (groupsCount != 0)
  136. {
  137. progressStep = 25 / groupsForImport.Count();
  138. //Create all groups
  139. i = 1;
  140. foreach (var group in groupsForImport)
  141. {
  142. if (cancellationToken.IsCancellationRequested) { ReportProgress(100, MigrationResource.MigrationCanceled); return null; }
  143. ReportProgress(GetProgress() + progressStep, String.Format(MigrationResource.GroupMigration, group.GroupName, i++, groupsCount));
  144. try
  145. {
  146. group.Migrate();
  147. }
  148. catch (Exception ex)
  149. {
  150. Log($"Couldn't migrate group {group.GroupName} ", ex);
  151. }
  152. }
  153. }
  154. // Add files, contacts and other stuff
  155. i = 1;
  156. foreach (var user in usersForImport)
  157. {
  158. if (cancellationToken.IsCancellationRequested) { ReportProgress(100, MigrationResource.MigrationCanceled); return null; }
  159. if (failedUsers.Contains(user))
  160. {
  161. ReportProgress(GetProgress() + progressStep, String.Format(MigrationResource.UserSkipped, user.DisplayName, i, usersCount));
  162. continue;
  163. }
  164. var smallStep = progressStep / 4;
  165. try
  166. {
  167. user.MigratingContacts.Migrate();
  168. }
  169. catch (Exception ex)
  170. {
  171. Log($"Couldn't migrate user {user.DisplayName} ({user.Email}) contacts", ex);
  172. }
  173. finally
  174. {
  175. ReportProgress(GetProgress() + smallStep, String.Format(MigrationResource.MigratingUserContacts, user.DisplayName, i, usersCount));
  176. }
  177. /*try
  178. {
  179. user.MigratingCalendar.Migrate();
  180. }
  181. catch (Exception ex)
  182. {
  183. Log($"Couldn't migrate user {user.DisplayName} ({user.Email}) calendar", ex);
  184. }
  185. finally
  186. {
  187. ReportProgress(GetProgress() + smallStep, String.Format(MigrationResource.UserCalendarMigration, user.DisplayName, i, usersCount));
  188. }*/
  189. try
  190. {
  191. var currentUser = SecurityContext.CurrentAccount;
  192. SecurityContext.AuthenticateMe(user.Guid);
  193. user.MigratingFiles.SetUsersDict(usersForImport.Except(failedUsers));
  194. user.MigratingFiles.SetGroupsDict(groupsForImport);
  195. user.MigratingFiles.Migrate();
  196. SecurityContext.AuthenticateMe(currentUser.ID);
  197. }
  198. catch (Exception ex)
  199. {
  200. Log($"Couldn't migrate user {user.DisplayName} ({user.Email}) files", ex);
  201. }
  202. finally
  203. {
  204. ReportProgress(GetProgress() + smallStep, String.Format(MigrationResource.MigratingUserFiles, user.DisplayName, i, usersCount));
  205. }
  206. i++;
  207. }
  208. foreach (var item in takeouts)
  209. {
  210. File.Delete(item);
  211. }
  212. ReportProgress(100, MigrationResource.MigrationCompleted);
  213. return Task.CompletedTask;
  214. }
  215. }
  216. }