diff --git a/DiscordChatExporter.Core/Exporting/ExportAssetDownloader.cs b/DiscordChatExporter.Core/Exporting/ExportAssetDownloader.cs index 7e23be66..18c500f2 100644 --- a/DiscordChatExporter.Core/Exporting/ExportAssetDownloader.cs +++ b/DiscordChatExporter.Core/Exporting/ExportAssetDownloader.cs @@ -23,7 +23,8 @@ internal partial class ExportAssetDownloader(string workingDirPath, bool reuse) public async ValueTask DownloadAsync( string url, - CancellationToken cancellationToken = default + CancellationToken cancellationToken = default, + DateTimeOffset? timestamp = null ) { var fileName = GetFileNameFromUrl(url); @@ -48,34 +49,12 @@ internal partial class ExportAssetDownloader(string workingDirPath, bool reuse) await using (var output = File.Create(filePath)) await response.Content.CopyToAsync(output, innerCancellationToken); - // Try to set the file date according to the last-modified header - try + // Try to set the file date according to the message timestamp + if (timestamp is not null) { - var lastModified = response - .Content.Headers.TryGetValue("Last-Modified") - ?.Pipe(s => - DateTimeOffset.TryParse( - s, - CultureInfo.InvariantCulture, - DateTimeStyles.None, - out var instant - ) - ? instant - : (DateTimeOffset?)null - ); - - if (lastModified is not null) - { - File.SetCreationTimeUtc(filePath, lastModified.Value.UtcDateTime); - File.SetLastWriteTimeUtc(filePath, lastModified.Value.UtcDateTime); - File.SetLastAccessTimeUtc(filePath, lastModified.Value.UtcDateTime); - } - } - catch - { - // This can apparently fail for some reason. - // Updating the file date is not a critical task, so we'll just ignore exceptions thrown here. - // https://github.com/Tyrrrz/DiscordChatExporter/issues/585 + File.SetCreationTimeUtc(filePath, timestamp.Value.UtcDateTime); + File.SetLastWriteTimeUtc(filePath, timestamp.Value.UtcDateTime); + File.SetLastAccessTimeUtc(filePath, timestamp.Value.UtcDateTime); } }, cancellationToken diff --git a/DiscordChatExporter.Core/Exporting/ExportContext.cs b/DiscordChatExporter.Core/Exporting/ExportContext.cs index c3d43f62..76c3e5a9 100644 --- a/DiscordChatExporter.Core/Exporting/ExportContext.cs +++ b/DiscordChatExporter.Core/Exporting/ExportContext.cs @@ -103,7 +103,8 @@ internal class ExportContext(DiscordClient discord, ExportRequest request) public async ValueTask ResolveAssetUrlAsync( string url, - CancellationToken cancellationToken = default + CancellationToken cancellationToken = default, + DateTimeOffset? timestamp = null ) { if (!Request.ShouldDownloadAssets) @@ -111,7 +112,7 @@ internal class ExportContext(DiscordClient discord, ExportRequest request) try { - var filePath = await _assetDownloader.DownloadAsync(url, cancellationToken); + var filePath = await _assetDownloader.DownloadAsync(url, cancellationToken, timestamp); var relativeFilePath = Path.GetRelativePath(Request.OutputDirPath, filePath); // Prefer the relative path so that the export package can be copied around without breaking references. diff --git a/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs b/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs index 78a42b98..8894bafc 100644 --- a/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/JsonMessageWriter.cs @@ -436,7 +436,7 @@ internal class JsonMessageWriter(Stream stream, ExportContext context) _writer.WriteString("id", attachment.Id.ToString()); _writer.WriteString( "url", - await Context.ResolveAssetUrlAsync(attachment.Url, cancellationToken) + await Context.ResolveAssetUrlAsync(attachment.Url, cancellationToken, message.Timestamp) ); _writer.WriteString("fileName", attachment.FileName); _writer.WriteNumber("fileSizeBytes", attachment.FileSize.TotalBytes); @@ -466,7 +466,7 @@ internal class JsonMessageWriter(Stream stream, ExportContext context) _writer.WriteString("format", sticker.Format.ToString()); _writer.WriteString( "sourceUrl", - await Context.ResolveAssetUrlAsync(sticker.SourceUrl, cancellationToken) + await Context.ResolveAssetUrlAsync(sticker.SourceUrl, cancellationToken, message.Timestamp) ); _writer.WriteEndObject();