Compare commits

...

7 Commits
1.5.10 ... main

Author SHA1 Message Date
3051fa69a8 fix bucket clear check 2024-05-18 17:01:10 -04:00
d4776b578a update mirror list info 2024-05-18 15:18:00 -04:00
84dd270f25 update example settings json 2024-05-15 11:09:43 -04:00
a2e8c67dbd Merge pull request 'impl/r2' (#10) from impl/r2 into main
Reviewed-on: #10
2024-05-04 14:49:53 +00:00
d9d8f49808 add check to mirror upload 2024-05-04 10:48:45 -04:00
67203037a1 do the thing 2024-05-02 19:50:39 -04:00
ec8ddeb513 r2-rework WIP 2024-04-26 21:17:08 -04:00
18 changed files with 367 additions and 202 deletions

View File

@ -5,11 +5,12 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AssemblyVersion>1.5.10</AssemblyVersion> <AssemblyVersion>1.6.1</AssemblyVersion>
<FileVersion>1.5.10</FileVersion> <FileVersion>1.6.1</FileVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AWSSDK.S3" Version="3.7.307.24" />
<PackageReference Include="FubarCoder.RestSharp.Portable.Core" Version="4.0.8" /> <PackageReference Include="FubarCoder.RestSharp.Portable.Core" Version="4.0.8" />
<PackageReference Include="FubarCoder.RestSharp.Portable.HttpClient" Version="4.0.8" /> <PackageReference Include="FubarCoder.RestSharp.Portable.HttpClient" Version="4.0.8" />
<PackageReference Include="GoFileSharp" Version="1.0.2" /> <PackageReference Include="GoFileSharp" Version="1.0.2" />
@ -23,9 +24,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Gitea">
<HintPath>Resources\Gitea.dll</HintPath>
</Reference>
<Reference Include="WinSCPnet"> <Reference Include="WinSCPnet">
<HintPath>Resources\WinSCPnet.dll</HintPath> <HintPath>Resources\WinSCPnet.dll</HintPath>
</Reference> </Reference>

View File

@ -0,0 +1,122 @@
using System.Net;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using EftPatchHelper.Model;
using Spectre.Console;
namespace EftPatchHelper.Helpers;
public class R2Helper
{
private readonly AmazonS3Client? _client;
public string ConnectedDomain { get; private set; }
public string BucketName { get; private set; }
public R2Helper(Settings settings, Options options)
{
ConnectedDomain = settings.R2ConnectedDomainUrl;
BucketName = settings.R2BucketName;
if (settings.UsingR2())
{
var creds = new BasicAWSCredentials(settings.R2AccessKeyId, settings.R2SecretKeyId);
_client = new AmazonS3Client(creds, new AmazonS3Config
{
ServiceURL = settings.R2ServiceUrl,
});
}
}
/// <summary>
/// Deletes all content in the bucket
/// </summary>
/// <returns>True if all contents of the bucket were deleted, otherwise false</returns>
public async Task<bool> ClearBucketAsync()
{
if (_client == null)
{
AnsiConsole.MarkupLine("[red]Client is unavailable[/]");
return false;
}
AnsiConsole.MarkupLine($"[blue]Getting bucket contents: {BucketName}[/]");
var listBucketResponse = await _client.ListObjectsAsync(BucketName);
if (listBucketResponse.HttpStatusCode != HttpStatusCode.OK)
{
AnsiConsole.MarkupLine("[red]failed to get bucket contents[/]");
return false;
}
if (listBucketResponse.S3Objects.Count == 0)
{
AnsiConsole.MarkupLine("[green]bucket is empty[/]");
return true;
}
AnsiConsole.MarkupLine("[blue]Removing old content[/]");
foreach (var s3Object in listBucketResponse.S3Objects)
{
var deleteResponse = await _client.DeleteObjectAsync(BucketName, s3Object.Key);
if ((int)deleteResponse.HttpStatusCode < 200 || (int)deleteResponse.HttpStatusCode > 299)
{
AnsiConsole.MarkupLine($"[red]failed to delete {BucketName}::{s3Object.Key}[/]");
return false;
}
AnsiConsole.MarkupLine($"[green]{BucketName}::{s3Object.Key} removed[/]");
}
return true;
}
/// <summary>
/// Upload a file into the bucket
/// </summary>
/// <param name="file">The file to upload</param>
/// <param name="progress">A progress object to track upload progress</param>
/// <returns>True if the file was uploaded successfully, otherwise false</returns>
public async Task<bool> UploadToBucketAsync(FileInfo file, IProgress<double>? progress = null)
{
if (_client == null)
{
AnsiConsole.MarkupLine("[red]Client is unavailable[/]");
return false;
}
file.Refresh();
if (!file.Exists)
{
AnsiConsole.MarkupLine($"[red]File '{file.Name}' does not exist[/]");
return false;
}
var request = new PutObjectRequest
{
BucketName = BucketName,
FilePath = file.FullName,
DisablePayloadSigning = true,
};
if (progress != null)
{
request.StreamTransferProgress = (sender, progressArgs) =>
{
progress.Report(progressArgs.PercentDone);
};
}
var uploadResponse = await _client.PutObjectAsync(request);
if (uploadResponse.HttpStatusCode != HttpStatusCode.OK)
{
AnsiConsole.MarkupLine("[red]failed to upload file[/]");
return false;
}
return true;
}
}

View File

@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace EftPatchHelper.Interfaces namespace EftPatchHelper.Interfaces
{ {
public interface IReleaseCreator : ITaskable public interface IMirrorUploader : ITaskable
{ {
} }
} }

View File

@ -24,21 +24,21 @@ namespace EftPatchHelper.Model
/// </summary> /// </summary>
public string OutputPatchPath = null; public string OutputPatchPath = null;
/// <summary>
/// Whether or not the user opted to create a release on gitea
/// </summary>
public bool CreateRelease = false;
/// <summary> /// <summary>
/// Whether or not to upload the patcher to gofile.io /// Whether or not to upload the patcher to gofile.io
/// </summary> /// </summary>
public bool UploadToGoFile = false; public bool UploadToGoFile = false;
/// <summary> /// <summary>
/// Whether or not to upload the pather to mega.io /// Whether or not to upload the patcher to mega.io
/// </summary> /// </summary>
public bool UploadToMega = false; public bool UploadToMega = false;
/// <summary>
/// Whether or not to upload the patcher and mirror list to r2
/// </summary>
public bool UplaodToR2 = false;
/// <summary> /// <summary>
/// Whether or not to upload to all sftp site listing /// Whether or not to upload to all sftp site listing
/// </summary> /// </summary>

View File

@ -0,0 +1,8 @@
namespace EftPatchHelper.Model;
public class PatchInfo
{
public int SourceClientVersion { get; set; }
public int TargetClientVersion { get; set; }
public List<DownloadMirror> Mirrors { get; set; }
}

View File

@ -0,0 +1,35 @@
using EftPatchHelper.Helpers;
using EftPatchHelper.Interfaces;
namespace EftPatchHelper.Model;
public class R2Upload : IFileUpload
{
public string DisplayName { get; set; }
public string ServiceName { get; set; }
public string HubEntryText { get; set; }
public FileInfo UploadFileInfo { get; }
public bool AddHubEntry { get; }
private readonly R2Helper _r2;
public R2Upload(FileInfo file, R2Helper r2)
{
_r2 = r2;
UploadFileInfo = file;
ServiceName = $"R2::{_r2.BucketName} Upload";
DisplayName = $"{ServiceName} Upload";
HubEntryText = $"Download from {ServiceName}";
AddHubEntry = false;
}
public string GetLink()
{
return $"{_r2.ConnectedDomain}/{UploadFileInfo.Name}";
}
public async Task<bool> UploadAsync(IProgress<double>? progress = null)
{
return await _r2.UploadToBucketAsync(UploadFileInfo, progress);
}
}

View File

@ -0,0 +1,8 @@
namespace EftPatchHelper.Model;
public class ReleaseInfo
{
public string AkiVersion { get; set; }
public string ClientVersion { get; set; }
public List<ReleaseInfoMirror> Mirrors { get; set; }
}

View File

@ -0,0 +1,7 @@
namespace EftPatchHelper.Model;
public class ReleaseInfoMirror
{
public string DownloadUrl { get; set; }
public string Hash { get; set; }
}

View File

@ -30,17 +30,8 @@ namespace EftPatchHelper.Model
[JsonPropertyName("patcherExePath")] [JsonPropertyName("patcherExePath")]
public string PatcherEXEPath { get; set; } = ""; public string PatcherEXEPath { get; set; } = "";
[JsonPropertyName("giteaApiBasePath")] [JsonPropertyName("latestReleaseUrl")]
public string GiteaApiBasePath { get; set; } = ""; public string LatestReleaseUrl { get; set; } = "";
[JsonPropertyName("giteaApiKey")]
public string GiteaApiKey { get; set; } = "";
[JsonPropertyName("giteaReleaseRepoOwner")]
public string GiteaReleaseRepoOwner { get; set; } = "";
[JsonPropertyName("giteaReleaseRepoName")]
public string GiteaReleaseRepoName { get; set; } = "";
[JsonPropertyName("megaEmail")] [JsonPropertyName("megaEmail")]
public string MegaEmail { get; set; } = ""; public string MegaEmail { get; set; } = "";
@ -57,6 +48,21 @@ namespace EftPatchHelper.Model
[JsonPropertyName("goFileFolderId")] [JsonPropertyName("goFileFolderId")]
public string GoFileFolderId { get; set; } = ""; public string GoFileFolderId { get; set; } = "";
[JsonPropertyName("r2ConnectedDomainUrl")]
public string R2ConnectedDomainUrl { get; set; } = "";
[JsonPropertyName("r2ServiceUrl")]
public string R2ServiceUrl { get; set; } = "";
[JsonPropertyName("r2BucketName")]
public string R2BucketName { get; set; } = "";
[JsonPropertyName("r2AccessKeyId")]
public string R2AccessKeyId { get; set; } = "";
[JsonPropertyName("r2SecretKeyId")]
public string R2SecretKeyId { get; set; } = "";
[JsonPropertyName("sftpUploads")] [JsonPropertyName("sftpUploads")]
public List<SftpUploadInfo> SftpUploads { get; set; } = new(); public List<SftpUploadInfo> SftpUploads { get; set; } = new();
@ -83,19 +89,6 @@ namespace EftPatchHelper.Model
} }
} }
public bool UsingGitea()
{
if (string.IsNullOrWhiteSpace(GiteaApiBasePath)) return false;
if (string.IsNullOrWhiteSpace(GiteaReleaseRepoOwner)) return false;
if (string.IsNullOrWhiteSpace(GiteaReleaseRepoName)) return false;
if (string.IsNullOrWhiteSpace(GiteaApiKey)) return false;
return true;
}
public bool UsingMega() public bool UsingMega()
{ {
if (string.IsNullOrWhiteSpace(MegaEmail)) return false; if (string.IsNullOrWhiteSpace(MegaEmail)) return false;
@ -114,6 +107,17 @@ namespace EftPatchHelper.Model
return true; return true;
} }
public bool UsingR2()
{
if (string.IsNullOrWhiteSpace(R2ConnectedDomainUrl)) return false;
if (string.IsNullOrWhiteSpace(R2ServiceUrl)) return false;
if (string.IsNullOrWhiteSpace(R2BucketName)) return false;
if (string.IsNullOrWhiteSpace(R2AccessKeyId)) return false;
if (string.IsNullOrWhiteSpace(R2SecretKeyId)) return false;
return true;
}
public bool Validate() public bool Validate()
{ {
if (string.IsNullOrWhiteSpace(TargetEftVersion)) return false; if (string.IsNullOrWhiteSpace(TargetEftVersion)) return false;

View File

@ -32,7 +32,7 @@ public class SftpUpload : IFileUpload
ServiceName = _sftpInfo.Hostname; ServiceName = _sftpInfo.Hostname;
DisplayName = $"{ServiceName} Upload"; DisplayName = $"{ServiceName} Upload";
HubEntryText = $"Download from {ServiceName}"; HubEntryText = $"Download from {ServiceName}";
AddHubEntry = false; AddHubEntry = sftpInfo.AllowHubEntry;
} }
public string GetLink() public string GetLink()

View File

@ -25,6 +25,9 @@ public class SftpUploadInfo
[JsonPropertyName("httpPath")] [JsonPropertyName("httpPath")]
public string HttpPath { get; set; } = ""; public string HttpPath { get; set; } = "";
[JsonPropertyName("allowHubEntry")]
public bool AllowHubEntry { get; set; } = false;
public bool IsValid() public bool IsValid()
{ {
if (string.IsNullOrWhiteSpace(Username)) if (string.IsNullOrWhiteSpace(Username))

View File

@ -20,9 +20,9 @@ namespace EftPatchHelper
ITaskable _fileProcessingTasks; ITaskable _fileProcessingTasks;
ITaskable _patchGenTasks; ITaskable _patchGenTasks;
ITaskable _patchTestingTasks; ITaskable _patchTestingTasks;
private ITaskable _compressPatcherTasks; ITaskable _compressPatcherTasks;
ITaskable _createReleaseTasks;
ITaskable _uploadTasks; ITaskable _uploadTasks;
ITaskable _uploadMirrorList;
public static void Main(string[] args) public static void Main(string[] args)
{ {
@ -32,8 +32,15 @@ namespace EftPatchHelper
var version = Assembly.GetExecutingAssembly().GetName().Version; var version = Assembly.GetExecutingAssembly().GetName().Version;
AnsiConsole.Write(new Rule($"[purple]v{version}[/]").Centered().RuleStyle("blue")); AnsiConsole.Write(new Rule($"[purple]v{version}[/]").Centered().RuleStyle("blue"));
var host = ConfigureHost(args); try
host.Services.GetRequiredService<Program>().Run(); {
var host = ConfigureHost(args);
host.Services.GetRequiredService<Program>().Run();
}
catch (Exception ex)
{
AnsiConsole.MarkupLine($"[red]{ex.Message.EscapeMarkup()}[/]");
}
AnsiConsole.MarkupLine("Press [blue]Enter[/] to close ..."); AnsiConsole.MarkupLine("Press [blue]Enter[/] to close ...");
Console.ReadLine(); Console.ReadLine();
@ -48,7 +55,7 @@ namespace EftPatchHelper
IPatchTestingTasks patchTestingTasks, IPatchTestingTasks patchTestingTasks,
ICompressPatcherTasks compressPatcherTasks, ICompressPatcherTasks compressPatcherTasks,
IUploadTasks uploadTasks, IUploadTasks uploadTasks,
IReleaseCreator createReleaseTasks IMirrorUploader uploadMirrorList
) )
{ {
_settingsTasks = settingsTasks; _settingsTasks = settingsTasks;
@ -58,7 +65,7 @@ namespace EftPatchHelper
_patchGenTasks = patchGenTasks; _patchGenTasks = patchGenTasks;
_patchTestingTasks = patchTestingTasks; _patchTestingTasks = patchTestingTasks;
_compressPatcherTasks = compressPatcherTasks; _compressPatcherTasks = compressPatcherTasks;
_createReleaseTasks = createReleaseTasks; _uploadMirrorList = uploadMirrorList;
_uploadTasks = uploadTasks; _uploadTasks = uploadTasks;
} }
@ -72,14 +79,17 @@ namespace EftPatchHelper
_patchTestingTasks.Run(); _patchTestingTasks.Run();
_compressPatcherTasks.Run(); _compressPatcherTasks.Run();
_uploadTasks.Run(); _uploadTasks.Run();
_createReleaseTasks.Run(); _uploadMirrorList.Run();
} }
private static IHost ConfigureHost(string[] args) private static IHost ConfigureHost(string[] args)
{ {
return Host.CreateDefaultBuilder(args).ConfigureServices((_, services) => return Host.CreateDefaultBuilder(args).ConfigureServices((_, services) =>
{ {
HttpClient client = new HttpClient() { Timeout = TimeSpan.FromHours(1) };
services.AddSingleton<Options>(); services.AddSingleton<Options>();
services.AddSingleton(client);
services.AddSingleton<Settings>(serviceProvider => services.AddSingleton<Settings>(serviceProvider =>
{ {
var configuration = serviceProvider.GetRequiredService<IConfiguration>(); var configuration = serviceProvider.GetRequiredService<IConfiguration>();
@ -90,6 +100,7 @@ namespace EftPatchHelper
services.AddSingleton<FileHelper>(); services.AddSingleton<FileHelper>();
services.AddSingleton<ZipHelper>(); services.AddSingleton<ZipHelper>();
services.AddSingleton<R2Helper>();
services.AddScoped<EftClientSelector>(); services.AddScoped<EftClientSelector>();
@ -100,8 +111,8 @@ namespace EftPatchHelper
services.AddTransient<IPatchGenTasks, PatchGenTasks>(); services.AddTransient<IPatchGenTasks, PatchGenTasks>();
services.AddTransient<IPatchTestingTasks, PatchTestingTasks>(); services.AddTransient<IPatchTestingTasks, PatchTestingTasks>();
services.AddTransient<ICompressPatcherTasks, CompressPatcherTasks>(); services.AddTransient<ICompressPatcherTasks, CompressPatcherTasks>();
services.AddTransient<IReleaseCreator, CreateReleaseTasks>();
services.AddTransient<IUploadTasks, UploadTasks>(); services.AddTransient<IUploadTasks, UploadTasks>();
services.AddTransient<IMirrorUploader, UploadMirrorListTasks>();
services.AddTransient<Program>(); services.AddTransient<Program>();
}) })
.ConfigureAppConfiguration((_, config) => .ConfigureAppConfiguration((_, config) =>

View File

@ -1,8 +1,8 @@
using EftPatchHelper.Extensions; using System.Net.Http.Json;
using EftPatchHelper.Extensions;
using EftPatchHelper.Helpers; using EftPatchHelper.Helpers;
using EftPatchHelper.Interfaces; using EftPatchHelper.Interfaces;
using EftPatchHelper.Model; using EftPatchHelper.Model;
using Gitea.Api;
using Spectre.Console; using Spectre.Console;
namespace EftPatchHelper.Tasks namespace EftPatchHelper.Tasks
@ -12,11 +12,13 @@ namespace EftPatchHelper.Tasks
private Settings _settings; private Settings _settings;
private Options _options; private Options _options;
private EftClientSelector _clientSelector; private EftClientSelector _clientSelector;
private HttpClient _http;
public ClientSelectionTask(Settings settings, Options options, EftClientSelector clientSelector) public ClientSelectionTask(Settings settings, Options options, EftClientSelector clientSelector, HttpClient client)
{ {
_settings = settings; _settings = settings;
_options = options; _options = options;
_http = client;
_clientSelector = clientSelector; _clientSelector = clientSelector;
} }
@ -58,22 +60,16 @@ namespace EftPatchHelper.Tasks
private string GetCurrentReleaseVersion() private string GetCurrentReleaseVersion()
{ {
if (!_settings.UsingGitea()) return AnsiConsole.Status().Start("Starting...", async ctx =>
return "";
return AnsiConsole.Status().Start("Starting...", ctx =>
{ {
RepositoryApi repo = new RepositoryApi();
ctx.Spinner = Spinner.Known.Dots8; ctx.Spinner = Spinner.Known.Dots8;
ctx.Status = "Getting latest release ..."; ctx.Status = "Getting latest release ...";
var blah = await _http.GetAsync(_settings.LatestReleaseUrl);
var release = await blah.Content.ReadFromJsonAsync<ReleaseInfo>();
var releases = repo.RepoListReleases("SPT-AKI", "Stable-releases"); return release?.ClientVersion ?? "failed to get version :(";
}).GetAwaiter().GetResult();
var release = releases.First(x => !x.Prerelease).Name.Split('(')[1];
return release.Remove(release.Length - 1);
});
} }
public void Run() public void Run()

View File

@ -1,117 +0,0 @@
using EftPatchHelper.Interfaces;
using EftPatchHelper.Model;
using Gitea.Api;
using Gitea.Model;
using Gitea.Client;
using Spectre.Console;
using EftPatchHelper.Extensions;
using System.Text.Json;
namespace EftPatchHelper.Tasks
{
public class CreateReleaseTasks : IReleaseCreator
{
private Settings _settings;
private Options _options;
public CreateReleaseTasks(Settings settings, Options options)
{
_settings = settings;
_options = options;
}
private bool UploadAsset(FileInfo file, Release release, RepositoryApi repo)
{
return AnsiConsole.Status().Spinner(Spinner.Known.Point).Start("Uploading Asset", (StatusContext context) =>
{
AnsiConsole.MarkupLine($"[blue]Adding release asset: {file.Name.EscapeMarkup()}[/]");
file.Refresh();
if (!file.Exists)
{
AnsiConsole.MarkupLine($"[red]File does not exist: {file.FullName}[/]");
}
using var fileStream = file.OpenRead();
try
{
var attachment = repo.RepoCreateReleaseAttachment(_settings.GiteaReleaseRepoOwner, _settings.GiteaReleaseRepoName, release.Id, fileStream, file.Name);
AnsiConsole.MarkupLine("[green]Upload Complete[/]");
return true;
}
catch (Exception ex)
{
AnsiConsole.MarkupLine("[red]Failed to upload asset[/]");
AnsiConsole.WriteException(ex);
return false;
}
});
}
private Release? MakeRelease(RepositoryApi repo)
{
AnsiConsole.Write("Adding release to gitea ... ");
string sourceTail = _options.SourceClient.Version.Split('.').Last();
string targetTail = _options.TargetClient.Version.Split('.').Last();
string releaseName = $"{sourceTail} to {targetTail}";
string tag = $"{sourceTail}_{new Random().Next(100, 999)}";
try
{
var release = repo.RepoCreateRelease(_settings.GiteaReleaseRepoOwner, _settings.GiteaReleaseRepoName, new CreateReleaseOption(null, false, releaseName, false, tag, null));
AnsiConsole.MarkupLine($"[green]Release added: {release.Name.EscapeMarkup()}[/]");
return release;
}
catch(Exception ex)
{
AnsiConsole.MarkupLine($"[red]Failed to create release[/]");
AnsiConsole.WriteException(ex);
return null;
}
}
public bool CreateMirrorList(FileInfo mirrorListFileInfo)
{
List<DownloadMirror> mirrors = _options.MirrorList.Values.ToList();
string json = JsonSerializer.Serialize(mirrors, new JsonSerializerOptions() { WriteIndented = true });
File.WriteAllText(mirrorListFileInfo.FullName, json);
mirrorListFileInfo.Refresh();
return mirrorListFileInfo.Exists;
}
public void Run()
{
AnsiConsole.WriteLine();
var fileInfo = new FileInfo(Path.Join(Environment.CurrentDirectory, "mirrors.json"));
CreateMirrorList(fileInfo);
if (!_options.CreateRelease) return;
var repo = new RepositoryApi(Configuration.Default);
var release = MakeRelease(repo).ValidateOrExit<Release>();
UploadAsset(fileInfo, release, repo);
}
}
}

View File

@ -1,7 +1,6 @@
using EftPatchHelper.Extensions; using EftPatchHelper.Extensions;
using EftPatchHelper.Interfaces; using EftPatchHelper.Interfaces;
using EftPatchHelper.Model; using EftPatchHelper.Model;
using Gitea.Client;
using Spectre.Console; using Spectre.Console;
namespace EftPatchHelper.Tasks namespace EftPatchHelper.Tasks
@ -63,14 +62,6 @@ namespace EftPatchHelper.Tasks
{ {
_options.IgnoreExistingDirectories = new ConfirmationPrompt("Skip existing directories? (you will be prompted if no)").Show(AnsiConsole.Console); _options.IgnoreExistingDirectories = new ConfirmationPrompt("Skip existing directories? (you will be prompted if no)").Show(AnsiConsole.Console);
if (_settings.UsingGitea())
{
Configuration.Default.BasePath = _settings.GiteaApiBasePath;
Configuration.Default.AddApiKey("token", _settings.GiteaApiKey);
_options.CreateRelease = new ConfirmationPrompt("Create a release on gitea?").Show(AnsiConsole.Console);
}
if (_settings.UsingMega()) if (_settings.UsingMega())
{ {
_options.UploadToMega = new ConfirmationPrompt("Upload to Mega?").Show(AnsiConsole.Console); _options.UploadToMega = new ConfirmationPrompt("Upload to Mega?").Show(AnsiConsole.Console);
@ -81,6 +72,11 @@ namespace EftPatchHelper.Tasks
_options.UploadToGoFile = new ConfirmationPrompt("Upload to GoFile?").Show(AnsiConsole.Console); _options.UploadToGoFile = new ConfirmationPrompt("Upload to GoFile?").Show(AnsiConsole.Console);
} }
if (_settings.UsingR2())
{
_options.UplaodToR2 = new ConfirmationPrompt($"Upload to R2 ({_settings.R2BucketName})?").Show(AnsiConsole.Console);
}
if (_settings.SftpUploads.Count > 0) if (_settings.SftpUploads.Count > 0)
{ {
_options.UploadToSftpSites = _options.UploadToSftpSites =

View File

@ -0,0 +1,78 @@
using EftPatchHelper.Interfaces;
using EftPatchHelper.Model;
using Spectre.Console;
using System.Text.Json;
using EftPatchHelper.Helpers;
namespace EftPatchHelper.Tasks
{
public class UploadMirrorListTasks : IMirrorUploader
{
private Settings _settings;
private Options _options;
private R2Helper _r2;
public UploadMirrorListTasks(Settings settigns, Options options, R2Helper r2)
{
_settings = settigns;
_options = options;
_r2 = r2;
}
private async Task<bool> UploadMirrorList(FileInfo file)
{
return await AnsiConsole.Progress().Columns(new ProgressColumn[]
{
new TaskDescriptionColumn() { Alignment = Justify.Left },
new ProgressBarColumn(),
new PercentageColumn(),
new RemainingTimeColumn(),
new SpinnerColumn(Spinner.Known.Dots2),
})
.StartAsync(async ctx =>
{
var uploadTask = ctx.AddTask("mirrors.json upload");
var progress = new Progress<double>((p) => { uploadTask.Value = p; });
return await _r2.UploadToBucketAsync(file, progress);
});
}
public bool CreateMirrorList(FileInfo mirrorListFileInfo)
{
var sourcePatchVersion = _options.SourceClient.Version.Split('.').Last();
var targetPatchVersion = _options.TargetClient.Version.Split('.').Last();
var mirrorInfo = new PatchInfo
{
SourceClientVersion = int.Parse(sourcePatchVersion),
TargetClientVersion = int.Parse(targetPatchVersion),
Mirrors = _options.MirrorList.Values.ToList()
};
string json = JsonSerializer.Serialize(mirrorInfo, new JsonSerializerOptions() { WriteIndented = true });
File.WriteAllText(mirrorListFileInfo.FullName, json);
mirrorListFileInfo.Refresh();
return mirrorListFileInfo.Exists;
}
public void Run()
{
if (!_settings.UsingR2() || !_options.UplaodToR2)
{
return;
}
AnsiConsole.WriteLine();
var fileInfo = new FileInfo(Path.Join(Environment.CurrentDirectory, "mirrors.json"));
CreateMirrorList(fileInfo);
UploadMirrorList(fileInfo).GetAwaiter().GetResult();
}
}
}

View File

@ -3,20 +3,23 @@ using EftPatchHelper.Interfaces;
using EftPatchHelper.Model; using EftPatchHelper.Model;
using Spectre.Console; using Spectre.Console;
using System.Security.Cryptography; using System.Security.Cryptography;
using EftPatchHelper.Helpers;
namespace EftPatchHelper.Tasks namespace EftPatchHelper.Tasks
{ {
public class UploadTasks : IUploadTasks public class UploadTasks : IUploadTasks
{ {
private Options _options; private readonly Options _options;
private Settings _settings; private readonly Settings _settings;
private List<IFileUpload> _fileUploads = new List<IFileUpload>(); private readonly R2Helper _r2;
private Dictionary<IFileUpload, ProgressTask> uploadTasks = new Dictionary<IFileUpload, ProgressTask>(); private readonly List<IFileUpload> _fileUploads = new();
private readonly Dictionary<IFileUpload, ProgressTask> _uploadTasks = new();
public UploadTasks(Options options, Settings settings) public UploadTasks(Options options, Settings settings, R2Helper r2)
{ {
_options = options; _options = options;
_settings = settings; _settings = settings;
_r2 = r2;
} }
private static string GetFileHash(FileInfo file) private static string GetFileHash(FileInfo file)
@ -48,6 +51,18 @@ namespace EftPatchHelper.Tasks
AnsiConsole.WriteLine("Added GoFile"); AnsiConsole.WriteLine("Added GoFile");
} }
if (_settings.UsingR2() && _options.UplaodToR2)
{
if (!await _r2.ClearBucketAsync())
{
return false;
}
var r2 = new R2Upload(patcherFile, _r2);
_fileUploads.Add(r2);
AnsiConsole.WriteLine($"Added R2::{_r2.BucketName}");
}
if (_settings.SftpUploads.Count > 0 && _options.UploadToSftpSites) if (_settings.SftpUploads.Count > 0 && _options.UploadToSftpSites)
{ {
foreach (var sftpInfo in _settings.SftpUploads) foreach (var sftpInfo in _settings.SftpUploads)
@ -149,10 +164,10 @@ namespace EftPatchHelper.Tasks
{ {
var task = context.AddTask($"[purple][[Pending]][/] {file.DisplayName} - [blue]{BytesToString(file.UploadFileInfo.Length)}[/]"); var task = context.AddTask($"[purple][[Pending]][/] {file.DisplayName} - [blue]{BytesToString(file.UploadFileInfo.Length)}[/]");
task.IsIndeterminate = true; task.IsIndeterminate = true;
uploadTasks.Add(file, task); _uploadTasks.Add(file, task);
} }
foreach(var pair in uploadTasks) foreach(var pair in _uploadTasks)
{ {
// set the value of the progress task object // set the value of the progress task object
var progress = new System.Progress<double>((d) => pair.Value.Value = d); var progress = new System.Progress<double>((d) => pair.Value.Value = d);
@ -185,7 +200,7 @@ namespace EftPatchHelper.Tasks
public void Run() public void Run()
{ {
if (!_options.UploadToGoFile && !_options.UploadToMega && !_options.UploadToSftpSites) return; if (!_options.UploadToGoFile && !_options.UploadToMega && !_options.UploadToSftpSites && !_options.UplaodToR2) return;
UploadAllFiles().GetAwaiter().GetResult().ValidateOrExit(); UploadAllFiles().GetAwaiter().GetResult().ValidateOrExit();

View File

@ -6,15 +6,17 @@
"patcherExePath": "", "patcherExePath": "",
"autoZip": true, "autoZip": true,
"autoClose": false, "autoClose": false,
"giteaApiBasePath": "", //You can leave the gitea settings blank if you don't need to create releases on gitea "latestReleaseUrl": "",
"giteaApiKey": "",
"giteaReleaseRepoOwner": "",
"giteaReleaseRepoName": "",
"megaEmail": "", "megaEmail": "",
"megaPassword": "", "megaPassword": "",
"megaUploadFolder": "", "megaUploadFolder": "",
"goFileApiKey": "", "goFileApiKey": "",
"goFileFolderId": "", "goFileFolderId": "",
"r2ConnectedDomainUrl": "",
"r2ServiceUrl": "",
"r2BucketName": "",
"r2AccessKeyId": "",
"r2SecretKeyId": "",
"sftpUploads": [ "sftpUploads": [
{ {
"username": "example-remove-before-using", "username": "example-remove-before-using",
@ -23,9 +25,8 @@
"hostname": "sftp.slugma-ligma.com", "hostname": "sftp.slugma-ligma.com",
"port": 12345, "port": 12345,
"uploadPath": "/public/patchers", "uploadPath": "/public/patchers",
"httpPath": "https://mirror.slugma-ligma.com/patchers" "httpPath": "https://mirror.slugma-ligma.com/patchers",
"allowHubEntry": true
} }
] ]
} }