From 28b11b1c7fff969bda916427bcdfce1873df16e0 Mon Sep 17 00:00:00 2001
From: Timothy Baldridge <tbaldridge@gmail.com>
Date: Thu, 21 May 2020 15:25:44 -0600
Subject: [PATCH] Version 2.0.6.0 - Hotfix for healing

---
 Wabbajack.Lib/Downloaders/NexusDownloader.cs |  2 +-
 Wabbajack.Server/Services/ListValidator.cs   |  7 ++-
 Wabbajack.Server/Services/PatchBuilder.cs    | 45 ++++++++++++++------
 3 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/Wabbajack.Lib/Downloaders/NexusDownloader.cs b/Wabbajack.Lib/Downloaders/NexusDownloader.cs
index d2955862..11d08438 100644
--- a/Wabbajack.Lib/Downloaders/NexusDownloader.cs
+++ b/Wabbajack.Lib/Downloaders/NexusDownloader.cs
@@ -257,7 +257,7 @@ namespace Wabbajack.Lib.Downloaders
                 
                 var tempFile = new TempFile();
 
-                var newArchive = new Archive(new State {Game = Game, ModID = ModID, FileID = FileID})
+                var newArchive = new Archive(new State {Game = Game, ModID = ModID, FileID = newFile.file_id})
                 {
                     Name = newFile.file_name,
                 };
diff --git a/Wabbajack.Server/Services/ListValidator.cs b/Wabbajack.Server/Services/ListValidator.cs
index b2453a7a..75d61d2d 100644
--- a/Wabbajack.Server/Services/ListValidator.cs
+++ b/Wabbajack.Server/Services/ListValidator.cs
@@ -138,11 +138,15 @@ namespace Wabbajack.Server.Services
             using var _ = await _healLock.WaitAsync();
 
             if (!(archive.State is IUpgradingState))
+            {
+                _logger.Log(LogLevel.Information, $"Cannot heal {archive.State} because it's not a healable state");
                 return (archive, ArchiveStatus.InValid);
-            
+            }
+
             var srcDownload = await _sql.GetArchiveDownload(archive.State.PrimaryKeyString, archive.Hash, archive.Size);
             if (srcDownload == null || srcDownload.IsFailed == true)
             {
+                _logger.Log(LogLevel.Information, $"Cannot heal {archive.State} because it hasn't been previously successfully downloaded");
                 return (archive, ArchiveStatus.InValid);
             }
 
@@ -166,6 +170,7 @@ namespace Wabbajack.Server.Services
             var upgrade = await (archive.State as IUpgradingState)?.FindUpgrade(archive);
             if (upgrade == default)
             {
+                _logger.Log(LogLevel.Information, $"Cannot heal {archive.State} because an alternative wasn't found");
                 return (archive, ArchiveStatus.InValid);
             }
 
diff --git a/Wabbajack.Server/Services/PatchBuilder.cs b/Wabbajack.Server/Services/PatchBuilder.cs
index e9c56470..c36a679d 100644
--- a/Wabbajack.Server/Services/PatchBuilder.cs
+++ b/Wabbajack.Server/Services/PatchBuilder.cs
@@ -10,6 +10,7 @@ using Wabbajack.Common;
 using Wabbajack.Lib.CompilationSteps;
 using Wabbajack.Server.DataLayer;
 using Wabbajack.Server.DTOs;
+using LogLevel = Microsoft.Extensions.Logging.LogLevel;
 
 namespace Wabbajack.Server.Services
 {
@@ -53,24 +54,20 @@ namespace Wabbajack.Server.Services
                     var patchName = $"{Consts.ArchiveUpdatesCDNFolder}\\{patch.Src.Archive.Hash.ToHex()}_{patch.Dest.Archive.Hash.ToHex()}";
 
                     using var sigFile = new TempFile();
+                    using var patchFile = new TempFile();
                     await using var srcStream = srcPath.OpenShared();
                     await using var destStream = destPath.OpenShared();
                     await using var sigStream = sigFile.Path.Create();
-                    using var ftpClient = await GetBunnyCdnFtpClient();
-
-                    if (!await ftpClient.DirectoryExistsAsync(Consts.ArchiveUpdatesCDNFolder)) 
-                        await ftpClient.CreateDirectoryAsync(Consts.ArchiveUpdatesCDNFolder);
-
-                    
-                    await using var patchOutput = await ftpClient.OpenWriteAsync(patchName);
+                    await using var patchOutput = patchFile.Path.Create();
                     OctoDiff.Create(destStream, srcStream, sigStream, patchOutput);
-                    
                     await patchOutput.DisposeAsync();
-                    
-                    var size = await ftpClient.GetFileSizeAsync(patchName);
+                    var size = patchFile.Path.Size;
+
+                    await UploadToCDN(patchFile.Path, patchName);
+                   
                     
                     await patch.Finish(_sql, size);
-                    await _discordWebHook.Send(Channel.Spam,
+                    await _discordWebHook.Send(Channel.Ham,
                         new DiscordMessage
                         {
                             Content =
@@ -95,7 +92,31 @@ namespace Wabbajack.Server.Services
 
             return count;
         }
-        
+
+        private async Task UploadToCDN(AbsolutePath patchFile, string patchName)
+        {
+            for (var times = 0; times < 5; times ++)
+            {
+                try
+                {
+                    _logger.Log(LogLevel.Information,
+                        $"Uploading {patchFile.Size.ToFileSizeString()} patch file to CDN");
+                    using var client = await GetBunnyCdnFtpClient();
+                    
+                    if (!await client.DirectoryExistsAsync(Consts.ArchiveUpdatesCDNFolder)) 
+                        await client.CreateDirectoryAsync(Consts.ArchiveUpdatesCDNFolder);
+                    
+                    await client.UploadFileAsync((string)patchFile, patchName, FtpRemoteExists.Overwrite);
+                    return;
+                }
+                catch (Exception ex)
+                {
+                    _logger.LogError(ex, $"Error uploading {patchFile} to CDN");
+                }
+            }
+            _logger.Log(LogLevel.Error, $"Couldn't upload {patchFile} to {patchName}");
+        }
+
         private async Task<FtpClient> GetBunnyCdnFtpClient()
         {
             var info = Utils.FromEncryptedJson<BunnyCdnFtpInfo>("bunny-cdn-ftp-info");