/// <summary> /// Generate the revisions list based on an older GroupSummary. /// </summary> /// <param name="oldGroupSummary">The previous version of the folder summary.</param> /// <returns>The list of all revisions in the given group.</returns> public List <Revision> GenerateRevisions(GroupSummary oldGroupSummary) { List <Revision> revisions = new List <Revision>(); List <string> oldFilesNames = oldGroupSummary.Files.Select(info => info.Name).ToList(); foreach (FileInfo file in Files) { FileInfo previousVersionFileInfo = oldGroupSummary.Files.Find(f => f.Name == file.Name); //The file was not in the old version, so we need to create the add revision if (previousVersionFileInfo == null) { revisions.Add(new Revision { GroupName = this.GroupName, Action = Action.Create, Data = GetFileData(file.Name), File = file }); } else { //We remove the file from the old list to notify that we have found it. oldFilesNames.Remove(file.Name); //We can compare the modifry date to find if the file have been modify. if (file.LastModificationDate > previousVersionFileInfo.LastModificationDate) { revisions.Add(new Revision { Action = Action.Modify, GroupName = this.GroupName, Data = GetFileData(file.Name), File = file }); } //Server Case else if (file.LastModificationDate < previousVersionFileInfo.LastModificationDate) { revisions.Add(new Revision { Action = Action.Modify, GroupName = this.GroupName, File = previousVersionFileInfo }); } } } IEnumerable <FileInfo> removedFiles = oldGroupSummary.Files.Where(info => oldFilesNames.Contains(info.Name)); revisions.AddRange(removedFiles.Select(removedFile => new Revision { Action = Action.Delete, GroupName = this.GroupName, File = removedFile })); return(revisions); }
public void Update() { Files = new List <FileInfo>(); IEnumerable <string> filePaths = Directory.EnumerateFiles(Path.Combine(rootFolderpath, GroupName)); foreach (string filePath in filePaths) { FileInfo fileInfo = new FileInfo { Name = Path.GetFileName(filePath), CreationDate = System.IO.File.GetCreationTime(filePath), LastModificationDate = System.IO.File.GetLastWriteTime(filePath) }; Files.Add(fileInfo); } }
public void Execute() { // Blocking call foreach (Job job in syncJobs.GetConsumingEnumerable()) { Console.WriteLine(@"Execute Job {0}", ++executionCount); List <Revision> returnRevisions = new List <Revision>(); // For each client group revision foreach (GroupSummary clientGroupSummary in job.GroupSummaries) { // Check user authorizations if (dataStore.CheckUserInGroup(job.Username, clientGroupSummary.GroupName)) { // Get the server GroupSummary equal to client GroupSummary GroupSummary serverGroupSummary = serverGroupSummaries.Find(s => s.GroupName == clientGroupSummary.GroupName); if (serverGroupSummary != null) { // Build revision list with client List <Revision> revisions = serverGroupSummary.GenerateRevisions(clientGroupSummary); foreach (Revision rev in revisions) { ShareLibrary.Models.FileInfo currentServerFile = serverGroupSummary.Files.Find(f => f.Name == rev.File.Name); ShareLibrary.Models.FileInfo currentClientFile = clientGroupSummary.Files.Find(f => f.Name == rev.File.Name); Revision currentRelatedjobRevision = job.Revisions.Find(r => r.File?.Name == currentClientFile?.Name); switch (rev.Action) { case Action.Create: // Rebind the currentRelatedjobRevision from the server instead of the client currentRelatedjobRevision = job.Revisions.Find(r => r.File?.Name == currentServerFile?.Name); // Case 1 : The file was deleted by the current client // Update server history (delete the current file) if (currentRelatedjobRevision?.File.Name == rev.File.Name && currentRelatedjobRevision?.Action == Action.Delete) { currentRelatedjobRevision.Apply(rootPath); serverGroupSummary.Update(); } // Case 2 : There is a new file on the server and the current client doesn't have it. // Add revision to response with data (Create) else { returnRevisions.Add(rev); } break; case Action.Modify: rev.Data = currentRelatedjobRevision?.Data ?? rev.Data; // Case 1 : Server modification date > client modification date // Add revision to response with data (Modify) if (currentServerFile.LastModificationDate > currentClientFile.LastModificationDate) { returnRevisions.Add(rev); } // Case 2 : Server modification date < client modification date // Update server history (replace the current file) else { rev.Apply(rootPath); serverGroupSummary.Update(); } break; case Action.Delete: // Case 1 : The file was created by the current client. // Update server history (add the current file) if (currentRelatedjobRevision?.Action == Action.Create) { currentRelatedjobRevision.Apply(rootPath); serverGroupSummary.Update(); } // Case 2 : The file is deleted for real (deleted from an other client) // Add revision to response (Delete) else { rev.Data = new byte[0]; returnRevisions.Add(rev); } break; } } } else { // Initial case when the server does not have the client group synced // Add the client files (revisions) to the server files List <Revision> clientRevisions = job.Revisions.FindAll(r => r.GroupName == clientGroupSummary.GroupName); // Create the group directory Directory.CreateDirectory(Path.Combine(rootPath, clientGroupSummary.GroupName)); // Add every client file to the server foreach (Revision clientRev in clientRevisions) { clientRev.Apply(rootPath); } // Create the server group summary because he didn't exist serverGroupSummaries.Add(new GroupSummary(clientGroupSummary.GroupName, rootPath)); } } } // Return the truth job.CallBack(returnRevisions); } }