From 5626e9432ae27cdbc7442eb87eee17bd40d6cacc Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 4 Aug 2024 18:02:29 +0200 Subject: [PATCH] add ToLocalUFile feature --- src/UniversalFiles/IUFileProvider.cs | 8 +++++++ src/UniversalFiles/UFileProvider.cs | 33 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/UniversalFiles/IUFileProvider.cs b/src/UniversalFiles/IUFileProvider.cs index 4cef673..2c4ec5c 100644 --- a/src/UniversalFiles/IUFileProvider.cs +++ b/src/UniversalFiles/IUFileProvider.cs @@ -12,10 +12,18 @@ // You should have received a copy of the GNU Lesser General Public License along with UniversalFiles. // If not, see . +using System.Threading.Tasks; + namespace Etherna.UniversalFiles { public interface IUFileProvider { UFile BuildNewUFile(UUri uuri); + + Task ToLocalUFileAsync( + UFile inputUFile, + UUriKind allowedUriKinds = UUriKind.All, + string? baseDirectory = null, + BasicUUri? outputUUri = null); } } \ No newline at end of file diff --git a/src/UniversalFiles/UFileProvider.cs b/src/UniversalFiles/UFileProvider.cs index 4799d7b..95f7fc8 100644 --- a/src/UniversalFiles/UFileProvider.cs +++ b/src/UniversalFiles/UFileProvider.cs @@ -14,7 +14,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net.Http; +using System.Threading.Tasks; namespace Etherna.UniversalFiles { @@ -39,5 +41,36 @@ public UFile BuildNewUFile(UUri uuri) public void RegisterUUriType(Func builder) where TUUri : UUri => uFileBuilders[typeof(TUUri)] = uuri => builder((TUUri)uuri); + + public async Task ToLocalUFileAsync( + UFile inputUFile, + UUriKind allowedUriKinds = UUriKind.All, + string? baseDirectory = null, + BasicUUri? outputUUri = null) + { + ArgumentNullException.ThrowIfNull(inputUFile, nameof(inputUFile)); + + // If it's already a local file, skip file retrieve. + if (inputUFile is BasicUFile basicUFile && + (basicUFile.FileUri.UriKind & allowedUriKinds & UUriKind.Local) != 0) + return basicUFile; + + if (outputUUri != null && outputUUri.UriKind != UUriKind.LocalAbsolute) + throw new InvalidOperationException("If provided, output uuri must be local and absolute"); + + if (outputUUri is null) + { + var fileName = await inputUFile.TryGetFileNameAsync().ConfigureAwait(false); + outputUUri = fileName is null ? + new BasicUUri(Path.GetTempFileName()) : + new BasicUUri(Path.Join(Path.GetTempPath(), fileName)); + } + + using var inputFileStream = (await inputUFile.ReadToStreamAsync(allowedUriKinds, baseDirectory).ConfigureAwait(false)).Stream; + using var outputFileStream = new FileStream(outputUUri.ToAbsoluteUri().Item1, FileMode.Create); + await inputFileStream.CopyToAsync(outputFileStream).ConfigureAwait(false); + + return (BasicUFile)BuildNewUFile(outputUUri); + } } } \ No newline at end of file