diff --git a/Wabbajack.BuildServer/Controllers/IndexedFiles.cs b/Wabbajack.BuildServer/Controllers/IndexedFiles.cs index 126bc259..4328be47 100644 --- a/Wabbajack.BuildServer/Controllers/IndexedFiles.cs +++ b/Wabbajack.BuildServer/Controllers/IndexedFiles.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using DynamicData; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using MongoDB.Bson; @@ -8,6 +10,7 @@ using MongoDB.Driver; using MongoDB.Driver.Linq; using Wabbajack.BuildServer.Models; using Wabbajack.Common; +using Wabbajack.Lib.Downloaders; using Wabbajack.VirtualFileSystem; namespace Wabbajack.BuildServer.Controllers @@ -36,6 +39,48 @@ namespace Wabbajack.BuildServer.Controllers return Ok(string.Join("\r\n", state.FirstOrDefault().State.GetMetaIni())); } + [Authorize] + [HttpDelete] + [Route("/indexed_files/nexus/{Game}/mod/{ModId}")] + public async Task PurgeBySHA256(string Game, string ModId) + { + var files = await Db.DownloadStates.AsQueryable().Where(d => d.State is NexusDownloader.State && + ((NexusDownloader.State)d.State).GameName == Game && + ((NexusDownloader.State)d.State).ModID == ModId) + .ToListAsync(); + + async Task DeleteParentsOf(HashSet acc, string hash) + { + var parents = await Db.IndexedFiles.AsQueryable().Where(f => f.Children.Any(c => c.Hash == hash)) + .ToListAsync(); + + foreach (var parent in parents) + await DeleteThisAndAllChildren(acc, parent.Hash); + } + + async Task DeleteThisAndAllChildren(HashSet acc, string hash) + { + acc.Add(hash); + var children = await Db.IndexedFiles.AsQueryable().Where(f => f.Hash == hash).FirstOrDefaultAsync(); + if (children == null) return; + foreach (var child in children.Children) + { + await DeleteThisAndAllChildren(acc, child.Hash); + } + + } + + var acc = new HashSet(); + foreach (var file in files) + await DeleteThisAndAllChildren(acc, file.Hash); + + var acclst = acc.ToList(); + await Db.DownloadStates.DeleteManyAsync(d => acc.Contains(d.Hash)); + await Db.IndexedFiles.DeleteManyAsync(d => acc.Contains(d.Hash)); + + return Ok(acc.ToList()); + } + [HttpGet] [Route("{xxHashAsBase64}")] public async Task GetFile(string xxHashAsBase64) diff --git a/Wabbajack.Common/FileExtractor.cs b/Wabbajack.Common/FileExtractor.cs index d80aeecd..b4dd7e05 100644 --- a/Wabbajack.Common/FileExtractor.cs +++ b/Wabbajack.Common/FileExtractor.cs @@ -207,7 +207,7 @@ namespace Wabbajack.Common Utils.Status($"Extracting {name} - 100%", 100, alsoLog: true); return; } - Utils.Log(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd())); + Utils.Error(new _7zipReturnError(p.ExitCode, source, dest, p.StandardOutput.ReadToEnd())); } /// diff --git a/Wabbajack.Common/StatusFeed/Errors/7zipReturnError.cs b/Wabbajack.Common/StatusFeed/Errors/7zipReturnError.cs index 6766a38d..fd943c92 100644 --- a/Wabbajack.Common/StatusFeed/Errors/7zipReturnError.cs +++ b/Wabbajack.Common/StatusFeed/Errors/7zipReturnError.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace Wabbajack.Common.StatusFeed.Errors { - public class _7zipReturnError : AStatusMessage, IError + public class _7zipReturnError : AErrorMessage { public string Destination { get; } public string Filename; diff --git a/Wabbajack.Lib/AInstaller.cs b/Wabbajack.Lib/AInstaller.cs index 218a45e9..918f553a 100644 --- a/Wabbajack.Lib/AInstaller.cs +++ b/Wabbajack.Lib/AInstaller.cs @@ -391,7 +391,7 @@ namespace Wabbajack.Lib Directory.EnumerateDirectories(OutputFolder, DirectoryEnumerationOptions.Recursive) .Where(p => !expectedFolders.Contains(p)) .OrderByDescending(p => p.Length) - .Do(p => Directory.Delete(p)); + .Do(Utils.DeleteDirectory); } catch (Exception) {