diff --git a/API/Interfaces/Services/IDirectoryService.cs b/API/Interfaces/Services/IDirectoryService.cs index 19aba03dd..abd83dd36 100644 --- a/API/Interfaces/Services/IDirectoryService.cs +++ b/API/Interfaces/Services/IDirectoryService.cs @@ -27,5 +27,7 @@ namespace API.Interfaces.Services /// /// bool ExistOrCreate(string directoryPath); + + void ClearAndDeleteDirectory(string directoryPath); } } \ No newline at end of file diff --git a/API/Services/BackupService.cs b/API/Services/BackupService.cs index 7ab168712..17b9cfb94 100644 --- a/API/Services/BackupService.cs +++ b/API/Services/BackupService.cs @@ -16,6 +16,7 @@ namespace API.Services private readonly IUnitOfWork _unitOfWork; private readonly ILogger _logger; private readonly IDirectoryService _directoryService; + private readonly string _tempDirectory = Path.Join(Directory.GetCurrentDirectory(), "temp"); private readonly IList _backupFiles = new List() { @@ -39,6 +40,7 @@ namespace API.Services { _logger.LogInformation("Beginning backup of Database at {BackupTime}", DateTime.Now); var backupDirectory = Task.Run(() => _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.BackupDirectory)).Result.Value; + _logger.LogDebug("Backing up to {BackupDirectory}", backupDirectory); if (!_directoryService.ExistOrCreate(backupDirectory)) { @@ -46,19 +48,36 @@ namespace API.Services return; } - var fileInfos = _backupFiles.Select(file => new FileInfo(Path.Join(Directory.GetCurrentDirectory(), file))).ToList(); - - var zipPath = Path.Join(backupDirectory, $"kavita_backup_{DateTime.Now}.zip"); - using (var zipArchive = ZipFile.Open(zipPath, ZipArchiveMode.Create)) - { - foreach (var fileInfo in fileInfos) - { - zipArchive.CreateEntryFromFile(fileInfo.FullName, fileInfo.Name); - } - } + var dateString = DateTime.Now.ToShortDateString().Replace("/", "_"); + var zipPath = Path.Join(backupDirectory, $"kavita_backup_{dateString}.zip"); + if (File.Exists(zipPath)) + { + _logger.LogInformation("{ZipFile} already exists, aborting", zipPath); + return; + } + + var tempDirectory = Path.Join(_tempDirectory, dateString); + _directoryService.ExistOrCreate(tempDirectory); + + + foreach (var file in _backupFiles) + { + var originalFile = new FileInfo(Path.Join(Directory.GetCurrentDirectory(), file)); + originalFile.CopyTo(Path.Join(tempDirectory, originalFile.Name)); + } + + try + { + ZipFile.CreateFromDirectory(tempDirectory, zipPath); + } + catch (AggregateException ex) + { + _logger.LogError(ex, "There was an issue when archiving library backup"); + } + + _directoryService.ClearAndDeleteDirectory(tempDirectory); _logger.LogInformation("Database backup completed"); - throw new System.NotImplementedException(); } } } \ No newline at end of file diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index e6410cd1c..9481302bd 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -66,6 +66,22 @@ namespace API.Services return true; } + public void ClearAndDeleteDirectory(string directoryPath) + { + DirectoryInfo di = new DirectoryInfo(directoryPath); + + foreach (var file in di.EnumerateFiles()) + { + file.Delete(); + } + foreach (var dir in di.EnumerateDirectories()) + { + dir.Delete(true); + } + + di.Delete(true); + } + public IEnumerable ListDirectory(string rootPath) { if (!Directory.Exists(rootPath)) return ImmutableList.Empty;