Example #1
0
 protected void OnBackupFailed(int serverHostID)
 {
     BackupFailed?.Invoke(serverHostID);
 }
 private void IterateOverFiles(List <FolderFileItem> paths, string backupDirectory)
 {
     try
     {
         HadError  = false;
         IsRunning = true;
         if (Directory.Exists(backupDirectory) || _isCalculatingFileSize)
         {
             var backupName = "backup-" + DateTime.Now.ToString("yyyy-MM-dd-H-mm-ss");
             backupDirectory = Path.Combine(backupDirectory, "easy-backup", backupName);
             if (!Directory.Exists(backupDirectory) && !_isCalculatingFileSize)
             {
                 Directory.CreateDirectory(backupDirectory);
             }
             else if (!_isCalculatingFileSize)
             {
                 // ok, somehow they started two backups within the same second >_> wait 1 second and start again
                 Task.Delay(1000);
                 backupName      = "backup-" + DateTime.Now.ToString("yyyy-MM-dd-H-mm-ss");
                 backupDirectory = Path.Combine(backupDirectory, "easy-backup", backupName);
                 if (!Directory.Exists(backupDirectory))
                 {
                     Directory.CreateDirectory(backupDirectory);
                 }
                 else
                 {
                     throw new Exception("Couldn't create backup directory (directory already exists)");
                 }
             }
             // ok, start copying the files if not using compressed file.
             if (!UsesCompressedFile || _isCalculatingFileSize)
             {
                 foreach (FolderFileItem item in paths)
                 {
                     if (HasBeenCanceled)
                     {
                         break;
                     }
                     var directoryName = Path.GetDirectoryName(item.Path);
                     var pathRoot      = Path.GetPathRoot(item.Path);
                     directoryName = directoryName.Replace(pathRoot, "");
                     directoryName = Path.Combine(pathRoot.Replace(":\\", ""), directoryName);
                     var outputDirectoryPath = Path.Combine(backupDirectory, directoryName);
                     if (!Directory.Exists(outputDirectoryPath) && !_isCalculatingFileSize)
                     {
                         Directory.CreateDirectory(outputDirectoryPath);
                     }
                     if (!_isCalculatingFileSize)
                     {
                         StartedCopyingItem?.Invoke(item);
                     }
                     if (item.IsDirectory && Directory.Exists(item.Path))
                     {
                         if (item.OnlyCopiesLatestFile && item.CanEnableOnlyCopiesLatestFile)
                         {
                             // scan directory and copy only the latest file out of it
                             var directoryInfo = new DirectoryInfo(item.Path);
                             var latestFile    = directoryInfo.GetFiles().OrderByDescending(x => x.LastWriteTimeUtc).FirstOrDefault();
                             if (latestFile != null)
                             {
                                 if (_isCalculatingFileSize)
                                 {
                                     CalculatedBytesOfItem?.Invoke(item, (ulong)new FileInfo(latestFile.FullName).Length);
                                 }
                                 else
                                 {
                                     var outputBackupDirectory = Path.Combine(outputDirectoryPath, Path.GetFileName(item.Path));
                                     // create directory if needed in backup path
                                     if (!Directory.Exists(outputBackupDirectory))
                                     {
                                         Directory.CreateDirectory(outputBackupDirectory);
                                     }
                                     if (HasBeenCanceled)
                                     {
                                         break;
                                     }
                                     var outputPath = Path.Combine(outputBackupDirectory, Path.GetFileName(latestFile.FullName));
                                     CopySingleFile(item, latestFile.FullName, outputPath);
                                 }
                             }
                         }
                         else
                         {
                             if (HasBeenCanceled)
                             {
                                 break;
                             }
                             _currentDirectorySize = 0;
                             var outputPath = Path.Combine(outputDirectoryPath, Path.GetFileName(item.Path));
                             CopyDirectory(item, item.Path, outputPath, item.IsRecursive, item.ExcludedPaths);
                             if (_isCalculatingFileSize)
                             {
                                 CalculatedBytesOfItem?.Invoke(item, _currentDirectorySize);
                             }
                         }
                     }
                     else
                     {
                         if (_isCalculatingFileSize)
                         {
                             CalculatedBytesOfItem?.Invoke(item, (ulong)new FileInfo(item.Path).Length);
                         }
                         else
                         {
                             var outputPath = Path.Combine(outputDirectoryPath, Path.GetFileName(item.Path));
                             CopySingleFile(item, item.Path, outputPath);
                         }
                     }
                     if (!HasBeenCanceled && !_isCalculatingFileSize)
                     {
                         FinishedCopyingItem?.Invoke(item);
                     }
                 }
             }
             else
             {
                 // first, figure out each file that needs to be copied into the 7z file. this way we can optimize
                 // the copy to 1 single Process start.
                 var filePaths             = new List <string>();
                 var pathsToFolderFileItem = new Dictionary <string, FolderFileItem>();
                 var pathToFileSize        = new Dictionary <string, ulong>();
                 foreach (FolderFileItem item in paths)
                 {
                     if (HasBeenCanceled)
                     {
                         break;
                     }
                     if (item.IsDirectory && Directory.Exists(item.Path))
                     {
                         if (item.OnlyCopiesLatestFile && item.CanEnableOnlyCopiesLatestFile)
                         {
                             // scan directory and copy only the latest file out of it
                             var directoryInfo = new DirectoryInfo(item.Path);
                             var latestFile    = directoryInfo.GetFiles().OrderByDescending(x => x.LastWriteTimeUtc).FirstOrDefault();
                             if (latestFile != null)
                             {
                                 if (HasBeenCanceled)
                                 {
                                     break;
                                 }
                                 pathsToFolderFileItem.Add(latestFile.FullName, item);
                                 filePaths.Add(latestFile.FullName);
                                 pathToFileSize.Add(item.Path, (ulong)new FileInfo(latestFile.FullName).Length);
                             }
                         }
                         else
                         {
                             if (HasBeenCanceled)
                             {
                                 break;
                             }
                             var filesWithSizesInDirectory = GetFilePathsAndSizesInDirectory(item.Path, item.IsRecursive, item.ExcludedPaths);
                             foreach (KeyValuePair <string, ulong> entry in filesWithSizesInDirectory)
                             {
                                 pathsToFolderFileItem.Add(entry.Key, item);
                                 pathToFileSize.Add(entry.Key, entry.Value);
                                 filePaths.Add(entry.Key);
                             }
                         }
                     }
                     else
                     {
                         pathsToFolderFileItem.Add(item.Path, item);
                         pathToFileSize.Add(item.Path, (ulong)new FileInfo(item.Path).Length);
                         filePaths.Add(item.Path);
                     }
                 }
                 _directoryPathsSeen.Clear();
                 if (!HasBeenCanceled)
                 {
                     // ok, we can do le copy now
                     BackupToCompressedFile(Path.Combine(backupDirectory, backupName + ".7z"), filePaths, pathsToFolderFileItem, pathToFileSize);
                     if (HasBeenCanceled)
                     {
                         try
                         {
                             // not a huge deal if this fails
                             Directory.Delete(backupDirectory);
                         }
                         catch (Exception) { }
                     }
                 }
             }
         }
         else
         {
             throw new Exception("Backup directory doesn't exist");
         }
         IsRunning = false;
     }
     catch (Exception e)
     {
         HadError = true;
         BackupFailed?.Invoke(e);
     }
     finally
     {
         IsRunning = false;
     }
 }