mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Implement mod list maintainer
This commit is contained in:
parent
9a13413472
commit
bf5d092f43
@ -13,6 +13,7 @@ using System.Windows.Input;
|
|||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Alphaleonis.Win32.Filesystem;
|
using Alphaleonis.Win32.Filesystem;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Wabbajack.Common;
|
using Wabbajack.Common;
|
||||||
@ -23,7 +24,9 @@ using Wabbajack.Lib.Downloaders;
|
|||||||
using Wabbajack.Lib.Extensions;
|
using Wabbajack.Lib.Extensions;
|
||||||
using Wabbajack.Lib.ModListRegistry;
|
using Wabbajack.Lib.ModListRegistry;
|
||||||
using Wabbajack.Paths;
|
using Wabbajack.Paths;
|
||||||
|
using Wabbajack.Paths.IO;
|
||||||
using Wabbajack.RateLimiter;
|
using Wabbajack.RateLimiter;
|
||||||
|
using Wabbajack.Services.OSIntegrated.Services;
|
||||||
|
|
||||||
namespace Wabbajack
|
namespace Wabbajack
|
||||||
{
|
{
|
||||||
@ -84,12 +87,17 @@ namespace Wabbajack
|
|||||||
public bool LoadingImage => _LoadingImage.Value;
|
public bool LoadingImage => _LoadingImage.Value;
|
||||||
|
|
||||||
private Subject<bool> IsLoadingIdle;
|
private Subject<bool> IsLoadingIdle;
|
||||||
|
private readonly ILogger<ModListMetadataVM> _logger;
|
||||||
|
private readonly ModListDownloadMaintainer _maintainer;
|
||||||
|
|
||||||
public ModListMetadataVM(ModListGalleryVM parent, ModlistMetadata metadata)
|
public ModListMetadataVM(ILogger<ModListMetadataVM> logger, ModListGalleryVM parent, ModlistMetadata metadata,
|
||||||
|
ModListDownloadMaintainer maintainer)
|
||||||
{
|
{
|
||||||
|
_logger = logger;
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
_maintainer = maintainer;
|
||||||
Metadata = metadata;
|
Metadata = metadata;
|
||||||
Location = LauncherUpdater.CommonFolder.Value.Combine("downloaded_mod_lists", Metadata.Links.MachineURL + (string)Consts.ModListExtension);
|
Location = LauncherUpdater.CommonFolder.Value.Combine("downloaded_mod_lists", Metadata.Links.MachineURL).WithExtension(Ext.Wabbajack);
|
||||||
ModListTagList = new List<ModListTag>();
|
ModListTagList = new List<ModListTag>();
|
||||||
|
|
||||||
Metadata.tags.ForEach(tag =>
|
Metadata.tags.ForEach(tag =>
|
||||||
@ -103,7 +111,7 @@ namespace Wabbajack
|
|||||||
VersionText = "Modlist version : " + Metadata.Version;
|
VersionText = "Modlist version : " + Metadata.Version;
|
||||||
IsBroken = metadata.ValidationSummary.HasFailures || metadata.ForceDown;
|
IsBroken = metadata.ValidationSummary.HasFailures || metadata.ForceDown;
|
||||||
//https://www.wabbajack.org/#/modlists/info?machineURL=eldersouls
|
//https://www.wabbajack.org/#/modlists/info?machineURL=eldersouls
|
||||||
OpenWebsiteCommand = ReactiveCommand.Create(() => Utils.OpenWebsite(new Uri($"https://www.wabbajack.org/#/modlists/info?machineURL={Metadata.Links.MachineURL}")));
|
OpenWebsiteCommand = ReactiveCommand.Create(() => UIUtils.OpenWebsite(new Uri($"https://www.wabbajack.org/#/modlists/info?machineURL={Metadata.Links.MachineURL}")));
|
||||||
|
|
||||||
IsLoadingIdle = new Subject<bool>();
|
IsLoadingIdle = new Subject<bool>();
|
||||||
|
|
||||||
@ -152,7 +160,7 @@ namespace Wabbajack
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Return an updated check on exists
|
// Return an updated check on exists
|
||||||
return Location.Exists;
|
return Location.FileExists();
|
||||||
}
|
}
|
||||||
return exists;
|
return exists;
|
||||||
})
|
})
|
||||||
@ -175,7 +183,7 @@ namespace Wabbajack
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Utils.Error(ex);
|
_logger.LogError(ex, "While opening modlist README");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -190,7 +198,7 @@ namespace Wabbajack
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return !IsDownloading && !(await metadata.NeedsDownload(Location));
|
return !IsDownloading && !(await maintainer.HaveModList(metadata));
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
@ -200,7 +208,7 @@ namespace Wabbajack
|
|||||||
.ToGuiProperty(this, nameof(Exists));
|
.ToGuiProperty(this, nameof(Exists));
|
||||||
|
|
||||||
var imageObs = Observable.Return(Metadata.Links.ImageUri)
|
var imageObs = Observable.Return(Metadata.Links.ImageUri)
|
||||||
.DownloadBitmapImage((ex) => Utils.Log($"Error downloading modlist image {Metadata.Title}"));
|
.DownloadBitmapImage((ex) => _logger.LogError("Error downloading modlist image {Title}", Metadata.Title));
|
||||||
|
|
||||||
_Image = imageObs
|
_Image = imageObs
|
||||||
.ToGuiProperty(this, nameof(Image));
|
.ToGuiProperty(this, nameof(Image));
|
||||||
@ -227,8 +235,8 @@ namespace Wabbajack
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
IsDownloading = true;
|
IsDownloading = true;
|
||||||
Utils.Log($"Starting Download of {Metadata.Links.MachineURL}");
|
_logger.LogInformation("Starting Download of {MachineUrl}", Metadata.Links.MachineURL);
|
||||||
var downloader = DownloadDispatcher.ResolveArchive(Metadata.Links.Download);
|
var downloader = await DownloadDispatcher.ResolveArchive(Metadata.Links.Download);
|
||||||
var result = await downloader.Download(
|
var result = await downloader.Download(
|
||||||
new Archive(state: null!)
|
new Archive(state: null!)
|
||||||
{
|
{
|
||||||
|
@ -27,10 +27,14 @@ public class Job<T> : IJob, IDisposable
|
|||||||
{
|
{
|
||||||
await Resource.Report(this, processedSize, token);
|
await Resource.Report(this, processedSize, token);
|
||||||
Current += processedSize;
|
Current += processedSize;
|
||||||
|
OnUpdate?.Invoke(this, (Percent.FactoryPutInRange(Current, Size ?? 1), Current));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportNoWait(int processedSize)
|
public void ReportNoWait(int processedSize)
|
||||||
{
|
{
|
||||||
Resource.ReportNoWait(this, processedSize);
|
Resource.ReportNoWait(this, processedSize);
|
||||||
|
OnUpdate?.Invoke(this, (Percent.FactoryPutInRange(Current, Size ?? 1), Current));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event EventHandler<(Percent Progress, long Processed)> OnUpdate;
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ using Wabbajack.Networking.WabbajackClientApi;
|
|||||||
using Wabbajack.Paths;
|
using Wabbajack.Paths;
|
||||||
using Wabbajack.Paths.IO;
|
using Wabbajack.Paths.IO;
|
||||||
using Wabbajack.RateLimiter;
|
using Wabbajack.RateLimiter;
|
||||||
|
using Wabbajack.Services.OSIntegrated.Services;
|
||||||
using Wabbajack.Services.OSIntegrated.TokenProviders;
|
using Wabbajack.Services.OSIntegrated.TokenProviders;
|
||||||
using Wabbajack.VFS;
|
using Wabbajack.VFS;
|
||||||
|
|
||||||
@ -99,6 +100,8 @@ public static class ServiceExtensions
|
|||||||
service.AddScoped<Context>();
|
service.AddScoped<Context>();
|
||||||
service.AddSingleton<FileExtractor.FileExtractor>();
|
service.AddSingleton<FileExtractor.FileExtractor>();
|
||||||
|
|
||||||
|
service.AddSingleton<ModListDownloadMaintainer>();
|
||||||
|
|
||||||
// Networking
|
// Networking
|
||||||
service.AddSingleton<HttpClient>();
|
service.AddSingleton<HttpClient>();
|
||||||
service.AddAllSingleton<IHttpDownloader, SingleThreadedDownloader>();
|
service.AddAllSingleton<IHttpDownloader, SingleThreadedDownloader>();
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Wabbajack.Common;
|
||||||
|
using Wabbajack.Downloaders;
|
||||||
|
using Wabbajack.DTOs;
|
||||||
|
using Wabbajack.Paths;
|
||||||
|
using Wabbajack.Paths.IO;
|
||||||
|
using Wabbajack.RateLimiter;
|
||||||
|
using Wabbajack.VFS;
|
||||||
|
|
||||||
|
namespace Wabbajack.Services.OSIntegrated.Services;
|
||||||
|
|
||||||
|
public class ModListDownloadMaintainer
|
||||||
|
{
|
||||||
|
private readonly ILogger<ModListDownloadMaintainer> _logger;
|
||||||
|
private readonly Configuration _configuration;
|
||||||
|
private readonly DownloadDispatcher _dispatcher;
|
||||||
|
private readonly FileHashCache _hashCache;
|
||||||
|
private readonly IResource<DownloadDispatcher> _rateLimiter;
|
||||||
|
|
||||||
|
public ModListDownloadMaintainer(ILogger<ModListDownloadMaintainer> logger, Configuration configuration,
|
||||||
|
DownloadDispatcher dispatcher, FileHashCache hashCache, IResource<DownloadDispatcher> rateLimiter)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_configuration = configuration;
|
||||||
|
_dispatcher = dispatcher;
|
||||||
|
_hashCache = hashCache;
|
||||||
|
_rateLimiter = rateLimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbsolutePath ModListPath(ModlistMetadata metadata)
|
||||||
|
{
|
||||||
|
return _configuration.ModListsDownloadLocation.Combine(metadata.Links.MachineURL).WithExtension(Ext.Wabbajack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> HaveModList(ModlistMetadata metadata, CancellationToken? token = null)
|
||||||
|
{
|
||||||
|
token ??= CancellationToken.None;
|
||||||
|
var path = ModListPath(metadata);
|
||||||
|
if (!path.FileExists()) return false;
|
||||||
|
|
||||||
|
return await _hashCache.FileHashCachedAsync(path, token.Value) == metadata.DownloadMetadata!.Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (IObservable<Percent> Progress, Task Task) DownloadModlist(ModlistMetadata metadata, CancellationToken? token = null)
|
||||||
|
{
|
||||||
|
var path = ModListPath(metadata);
|
||||||
|
|
||||||
|
token ??= CancellationToken.None;
|
||||||
|
|
||||||
|
var progress = new Subject<Percent>();
|
||||||
|
progress.OnNext(Percent.Zero);
|
||||||
|
|
||||||
|
var tsk = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
var job = await _rateLimiter.Begin($"Downloading {metadata.Title}", metadata.DownloadMetadata!.Size, token.Value);
|
||||||
|
|
||||||
|
job.OnUpdate += (_, pr) =>
|
||||||
|
{
|
||||||
|
progress.OnNext(pr.Progress);
|
||||||
|
};
|
||||||
|
|
||||||
|
var hash = await _dispatcher.Download(new Archive()
|
||||||
|
{
|
||||||
|
State = _dispatcher.Parse(new Uri(metadata.Links.Download))!,
|
||||||
|
Size = metadata.DownloadMetadata.Size,
|
||||||
|
Hash = metadata.DownloadMetadata.Hash
|
||||||
|
}, path, job, token.Value);
|
||||||
|
|
||||||
|
_hashCache.FileHashWriteCache(path, hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (progress, tsk);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user