From 3861dba60ccf896b0dc2958edef775c7ccbd521a Mon Sep 17 00:00:00 2001 From: Tyrrrz Date: Thu, 17 Dec 2020 17:49:35 +0200 Subject: [PATCH] Refactor last PR --- .../Exporting/MediaDownloader.cs | 26 +++++++++++++++--- .../Extensions/HttpClientExtensions.cs | 27 ------------------- .../Internal/Extensions/HttpExtensions.cs | 12 +++++++++ 3 files changed, 35 insertions(+), 30 deletions(-) delete mode 100644 DiscordChatExporter.Domain/Internal/Extensions/HttpClientExtensions.cs create mode 100644 DiscordChatExporter.Domain/Internal/Extensions/HttpExtensions.cs diff --git a/DiscordChatExporter.Domain/Exporting/MediaDownloader.cs b/DiscordChatExporter.Domain/Exporting/MediaDownloader.cs index 4750b37..c39ee80 100644 --- a/DiscordChatExporter.Domain/Exporting/MediaDownloader.cs +++ b/DiscordChatExporter.Domain/Exporting/MediaDownloader.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Net.Http; using System.Security.Cryptography; @@ -42,12 +43,31 @@ namespace DiscordChatExporter.Domain.Exporting if (_reuseMedia && File.Exists(filePath)) return _pathCache[url] = filePath; - // Download it Directory.CreateDirectory(_workingDirPath); + + // This catches IOExceptions which is dangerous as we're working also with files await Http.ExceptionPolicy.ExecuteAsync(async () => { - // This catches IOExceptions which is dangerous as we're working also with files - await _httpClient.DownloadAsync(url, filePath); + // Download the file + using var response = await _httpClient.GetAsync(url); + await using (var output = File.Create(filePath)) + { + await response.Content.CopyToAsync(output); + } + + // Try to set the file date according to the last-modified header + var lastModified = response.Content.Headers.TryGetValue("Last-Modified")?.Pipe(s => + DateTimeOffset.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) + ? date + : (DateTimeOffset?) null + ); + + if (lastModified != null) + { + File.SetCreationTimeUtc(filePath, lastModified.Value.UtcDateTime); + File.SetLastWriteTimeUtc(filePath, lastModified.Value.UtcDateTime); + File.SetLastAccessTimeUtc(filePath, lastModified.Value.UtcDateTime); + } }); return _pathCache[url] = filePath; diff --git a/DiscordChatExporter.Domain/Internal/Extensions/HttpClientExtensions.cs b/DiscordChatExporter.Domain/Internal/Extensions/HttpClientExtensions.cs deleted file mode 100644 index f230891..0000000 --- a/DiscordChatExporter.Domain/Internal/Extensions/HttpClientExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; - -namespace DiscordChatExporter.Domain.Internal.Extensions -{ - internal static class HttpClientExtensions - { - public static async ValueTask DownloadAsync(this HttpClient httpClient, string uri, string outputFilePath) - { - using var response = await httpClient.GetAsync(uri); - var output = File.Create(outputFilePath); - - await response.Content.CopyToAsync(output); - - IEnumerable lastModifiedHeaderValues; - if (response.Content.Headers.TryGetValues("Last-Modified", out lastModifiedHeaderValues)) - { - await output.DisposeAsync(); - File.SetLastWriteTime(outputFilePath, DateTime.Parse(lastModifiedHeaderValues.First())); - } - } - } -} \ No newline at end of file diff --git a/DiscordChatExporter.Domain/Internal/Extensions/HttpExtensions.cs b/DiscordChatExporter.Domain/Internal/Extensions/HttpExtensions.cs new file mode 100644 index 0000000..e42a132 --- /dev/null +++ b/DiscordChatExporter.Domain/Internal/Extensions/HttpExtensions.cs @@ -0,0 +1,12 @@ +using System.Net.Http.Headers; + +namespace DiscordChatExporter.Domain.Internal.Extensions +{ + internal static class HttpExtensions + { + public static string? TryGetValue(this HttpContentHeaders headers, string name) => + headers.TryGetValues(name, out var values) + ? string.Concat(values) + : null; + } +} \ No newline at end of file