-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Direct download in collections (#2195)
* WIP * Add support for direct downloads in collections * Update the collection test files so that they include the new xxHash3 values * Delete src/NexusMods.Library/AddDirectDownloadJob.cs
- Loading branch information
Showing
14 changed files
with
532 additions
and
249 deletions.
There are no files selected for viewing
24 changes: 24 additions & 0 deletions
24
src/Abstractions/NexusMods.Abstractions.Collections/Attributes/Md5Attribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using NexusMods.Abstractions.Collections.Types; | ||
using NexusMods.MnemonicDB.Abstractions; | ||
using NexusMods.MnemonicDB.Abstractions.Attributes; | ||
using NexusMods.MnemonicDB.Abstractions.ElementComparers; | ||
|
||
namespace NexusMods.Abstractions.Collections.Attributes; | ||
|
||
/// <summary> | ||
/// An attribute representing an MD5 hash value. | ||
/// </summary> | ||
public class Md5Attribute(string ns, string name) : ScalarAttribute<Md5HashValue, UInt128>(ValueTag.UInt128, ns, name) | ||
{ | ||
/// <inheritdoc /> | ||
protected override UInt128 ToLowLevel(Md5HashValue value) | ||
{ | ||
return value.Value; | ||
} | ||
|
||
/// <inheritdoc /> | ||
protected override Md5HashValue FromLowLevel(UInt128 value, AttributeResolver resolver) | ||
{ | ||
return Md5HashValue.From(value); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/Abstractions/NexusMods.Abstractions.Collections/DirectDownloadLibraryFile.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using NexusMods.Abstractions.Collections.Attributes; | ||
using NexusMods.Abstractions.Library.Models; | ||
using NexusMods.MnemonicDB.Abstractions.Attributes; | ||
using NexusMods.MnemonicDB.Abstractions.Models; | ||
|
||
namespace NexusMods.Abstractions.Collections; | ||
|
||
/// <summary> | ||
/// A direct downloaded file from a collection | ||
/// </summary> | ||
[Include<LibraryFile>] | ||
public partial class DirectDownloadLibraryFile : IModelDefinition | ||
{ | ||
private const string Namespace = "NexusMods.Abstractions.Collections"; | ||
|
||
/// <summary> | ||
/// The MD5 hash value of the downloaded file. | ||
/// </summary> | ||
public static readonly Md5Attribute Md5 = new(Namespace, nameof(Md5)) { IsIndexed = true }; | ||
|
||
/// <summary> | ||
/// A user-friendly name of the file. | ||
/// </summary> | ||
public static readonly StringAttribute LogicalFileName = new(Namespace, nameof(LogicalFileName)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System.Runtime.InteropServices; | ||
using System.Security.Cryptography; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Logging; | ||
using NexusMods.Abstractions.Collections; | ||
using NexusMods.Abstractions.Collections.Types; | ||
using NexusMods.Abstractions.Jobs; | ||
using NexusMods.Abstractions.Library.Models; | ||
using NexusMods.MnemonicDB.Abstractions; | ||
using NexusMods.Networking.HttpDownloader; | ||
using NexusMods.Paths; | ||
|
||
namespace NexusMods.Collections; | ||
|
||
public record DirectDownloadJob : HttpDownloadJob | ||
{ | ||
/// <summary> | ||
/// The expected MD5 hash value of the downloaded file. | ||
/// </summary> | ||
public required Md5HashValue ExpectedMd5 { get; init; } | ||
|
||
/// <summary> | ||
/// The user-friendly name of the file. | ||
/// </summary> | ||
public required string LogicalFileName { get; init; } | ||
|
||
/// <summary> | ||
/// Create a new download job for the given URL, the job will fail if the downloaded file does not | ||
/// match the expected MD5 hash. | ||
/// </summary> | ||
public static IJobTask<DirectDownloadJob, AbsolutePath> Create(IServiceProvider provider, Uri uri, | ||
Md5HashValue expectedMd5, string logicalFileName) | ||
{ | ||
var monitor = provider.GetRequiredService<IJobMonitor>(); | ||
var tempFileManager = provider.GetRequiredService<TemporaryFileManager>(); | ||
var job = new DirectDownloadJob | ||
{ | ||
Logger = provider.GetRequiredService<ILogger<DirectDownloadJob>>(), | ||
ExpectedMd5 = expectedMd5, | ||
LogicalFileName = logicalFileName, | ||
DownloadPageUri = uri, | ||
Destination = tempFileManager.CreateFile(), | ||
Uri = uri, | ||
}; | ||
|
||
return monitor.Begin<DirectDownloadJob, AbsolutePath>(job); | ||
} | ||
|
||
|
||
/// <inheritdoc /> | ||
public override async ValueTask AddMetadata(ITransaction tx, LibraryFile.New libraryFile) | ||
{ | ||
await using (var fileStream = Destination.Read()) | ||
{ | ||
var algo = MD5.Create(); | ||
var hash = await algo.ComputeHashAsync(fileStream); | ||
var md5Actual = Md5HashValue.From(hash); | ||
if (md5Actual != ExpectedMd5) | ||
throw new InvalidOperationException($"MD5 hash mismatch. Expected: {ExpectedMd5}, Actual: {md5Actual}"); | ||
} | ||
|
||
tx.Add(libraryFile, DirectDownloadLibraryFile.Md5, ExpectedMd5); | ||
tx.Add(libraryFile, DirectDownloadLibraryFile.LogicalFileName, LogicalFileName); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.