2022-05-16 22:14:52 +00:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
2022-05-19 03:21:38 +00:00
|
|
|
|
using Wabbajack.Common;
|
2022-05-16 22:14:52 +00:00
|
|
|
|
using Wabbajack.Downloaders.Interfaces;
|
2022-02-27 21:31:13 +00:00
|
|
|
|
using Wabbajack.DTOs;
|
|
|
|
|
using Wabbajack.DTOs.DownloadStates;
|
2022-05-16 22:14:52 +00:00
|
|
|
|
using Wabbajack.DTOs.Interventions;
|
2022-02-27 21:31:13 +00:00
|
|
|
|
using Wabbajack.DTOs.Validation;
|
|
|
|
|
using Wabbajack.Hashing.xxHash64;
|
|
|
|
|
using Wabbajack.Paths;
|
2022-05-16 22:14:52 +00:00
|
|
|
|
using Wabbajack.Paths.IO;
|
2022-02-27 21:31:13 +00:00
|
|
|
|
using Wabbajack.RateLimiter;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.Downloaders.Manual;
|
|
|
|
|
|
2022-06-20 23:21:04 +00:00
|
|
|
|
public class ManualDownloader : ADownloader<DTOs.DownloadStates.Manual>, IProxyable
|
2022-02-27 21:31:13 +00:00
|
|
|
|
{
|
2022-05-16 22:14:52 +00:00
|
|
|
|
private readonly ILogger<ManualDownloader> _logger;
|
|
|
|
|
private readonly IUserInterventionHandler _interventionHandler;
|
|
|
|
|
private readonly IResource<HttpClient> _limiter;
|
|
|
|
|
private readonly HttpClient _client;
|
|
|
|
|
|
|
|
|
|
public ManualDownloader(ILogger<ManualDownloader> logger, IUserInterventionHandler interventionHandler, HttpClient client)
|
|
|
|
|
{
|
|
|
|
|
_logger = logger;
|
|
|
|
|
_interventionHandler = interventionHandler;
|
|
|
|
|
_client = client;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override async Task<Hash> Download(Archive archive, DTOs.DownloadStates.Manual state, AbsolutePath destination, IJob job, CancellationToken token)
|
2022-02-27 21:31:13 +00:00
|
|
|
|
{
|
2022-05-16 22:14:52 +00:00
|
|
|
|
_logger.LogInformation("Starting manual download of {Url}", state.Url);
|
|
|
|
|
|
2022-05-19 03:21:38 +00:00
|
|
|
|
if (state.Url.Host == "mega.nz")
|
2022-05-16 22:14:52 +00:00
|
|
|
|
{
|
2022-05-19 03:21:38 +00:00
|
|
|
|
var intervention = new ManualBlobDownload(archive, destination);
|
|
|
|
|
_interventionHandler.Raise(intervention);
|
|
|
|
|
await intervention.Task;
|
|
|
|
|
if (!destination.FileExists())
|
|
|
|
|
throw new Exception("File does not exist after download");
|
|
|
|
|
_logger.LogInformation("Hashing manually downloaded Mega file {File}", destination.FileName);
|
|
|
|
|
return await destination.Hash(token);
|
2022-05-16 22:14:52 +00:00
|
|
|
|
}
|
2022-05-19 03:21:38 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var intervention = new ManualDownload(archive);
|
|
|
|
|
_interventionHandler.Raise(intervention);
|
|
|
|
|
var browserState = await intervention.Task;
|
2022-05-16 22:14:52 +00:00
|
|
|
|
|
2022-05-19 03:21:38 +00:00
|
|
|
|
var msg = browserState.ToHttpRequestMessage();
|
2022-05-16 22:14:52 +00:00
|
|
|
|
|
2022-05-19 03:21:38 +00:00
|
|
|
|
using var response = await _client.SendAsync(msg, token);
|
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
|
|
|
throw new HttpRequestException(response.ReasonPhrase, null, statusCode: response.StatusCode);
|
|
|
|
|
|
|
|
|
|
await using var strm = await response.Content.ReadAsStreamAsync(token);
|
|
|
|
|
await using var os = destination.Open(FileMode.Create, FileAccess.Write, FileShare.None);
|
|
|
|
|
return await strm.HashingCopy(os, token, job);
|
|
|
|
|
}
|
2022-02-27 21:31:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-16 22:14:52 +00:00
|
|
|
|
|
2022-02-27 21:31:13 +00:00
|
|
|
|
public override async Task<bool> Prepare()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool IsAllowed(ServerAllowList allowList, IDownloadState state)
|
|
|
|
|
{
|
|
|
|
|
return allowList.AllowedPrefixes.Any(p => ((DTOs.DownloadStates.Manual) state).Url.ToString().StartsWith(p));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override IDownloadState? Resolve(IReadOnlyDictionary<string, string> iniData)
|
|
|
|
|
{
|
|
|
|
|
if (iniData.ContainsKey("manualURL") && Uri.TryCreate(iniData["manualURL"], UriKind.Absolute, out var uri))
|
|
|
|
|
{
|
|
|
|
|
iniData.TryGetValue("prompt", out var prompt);
|
|
|
|
|
|
|
|
|
|
var state = new DTOs.DownloadStates.Manual
|
|
|
|
|
{
|
|
|
|
|
Url = uri,
|
|
|
|
|
Prompt = prompt ?? ""
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Priority Priority { get; } = Priority.Lowest;
|
|
|
|
|
public override async Task<bool> Verify(Archive archive, DTOs.DownloadStates.Manual archiveState, IJob job, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override IEnumerable<string> MetaIni(Archive a, DTOs.DownloadStates.Manual state)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
return new[] {$"manualURL={state.Url}", $"prompt={state.Prompt}"};
|
|
|
|
|
}
|
2022-06-20 23:21:04 +00:00
|
|
|
|
|
|
|
|
|
public IDownloadState? Parse(Uri uri)
|
|
|
|
|
{
|
|
|
|
|
return new DTOs.DownloadStates.Manual() {Url = uri};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Uri UnParse(IDownloadState state)
|
|
|
|
|
{
|
|
|
|
|
return (state as DTOs.DownloadStates.Manual)!.Url;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task<T> DownloadStream<T>(Archive archive, Func<Stream, Task<T>> fn, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
2022-02-27 21:31:13 +00:00
|
|
|
|
}
|