diff --git a/.docs/Troubleshooting.md b/.docs/Troubleshooting.md index 024a8dbb..cc9662d8 100644 --- a/.docs/Troubleshooting.md +++ b/.docs/Troubleshooting.md @@ -60,7 +60,9 @@ No, DCE is an exporter. ### Can DCE add new messages to an existing export? -No. +Yes, existing exports can be appended. +In this case, the existing export file won't be changed, but a new partition file will be created, which will contain +all newer messages. ## First steps @@ -82,7 +84,10 @@ Check the following pages to learn how to schedule **DiscordChatExporter.CLI** r ### The exported file is too large, I can't open it -Try opening it with a different program, try partitioning or use a different file format, like `PlainText`. +Re-export the channel using a partition size; this will cause the exporter to split up the export into multiple smaller +files you can open. + +Alternatively, you could also try to open it with a different program or use a different file format, like `PlainText`. ### I see messages in the export, but they have no content @@ -146,6 +151,18 @@ Red Hat: `cert-sync --user /etc/pki/tls/certs/ca-bundle.crt` If it still doesn't work, try mozroots: `mozroots --import --ask-remove` +```yml +System.InvalidOperationException: Error: The target export file already exists. This should never happen. +``` + +↳ This means that a file with the export target path somehow exists despite not having been detected. +It's a failsafe implemented to prevent unintentionally overwriting a file. + +It might occur if you try to export the same channel multiple times in parallel, or if you've manually deleted some +partition files. + +In that case, double-check the command, manually delete the respective export files and try again. + ## macOS-specific ### DiscordChatExporter is damaged and can’t be opened. You should move it to the Trash. diff --git a/.docs/Using-the-CLI.md b/.docs/Using-the-CLI.md index 20c6315e..4ca255af 100644 --- a/.docs/Using-the-CLI.md +++ b/.docs/Using-the-CLI.md @@ -175,6 +175,32 @@ providing a path that ends with a slash. All of the exported media will be store ./DiscordChatExporter.Cli export -t "mfa.Ifrn" -c 53555 --media --media-dir "C:\Discord Media" ``` +#### Handling existing exports + +By default, the exporter aborts the current channel export if it had previously been exported to prevent accidental +overwrites. +But it also has the options to either overwrite or append the existing export. +You can specify the desired behaviour by using `--export-exists` with one of the possible values `abort`, `append` +and `overwrite`. + +```console +./DiscordChatExporter.Cli export -t "mfa.Ifrn" -c 53555 --export-exists append +``` + +#### Search for existing exports + +By default, the exporter only tests whether there is an existing export at the target file path. +But the exporter can also search in the entire target directory to determine whether one of the current channels had +previously been exported. +This is necessary to detect an existing export if the name of the channel, the channel parent or the guild has changed +or if the default file formatting has changed. +The `--search-existing-exports` option enables this. + +```console +./DiscordChatExporter.Cli export -t "mfa.Ifrn" -c 53555 --search-existing-exports +``` + + #### Changing the date format You can customize how dates are formatted in the exported files by using `--locale` and inserting one of Discord's diff --git a/.docs/Using-the-GUI.md b/.docs/Using-the-GUI.md index d175765b..2b2b6bfe 100644 --- a/.docs/Using-the-GUI.md +++ b/.docs/Using-the-GUI.md @@ -103,3 +103,12 @@ Default: 1 - **Normalize to UTC** - Convert all dates to UTC before exporting. +- **Export exists** Controls what the exporter should do if the current channel had previously been exported. +Default: Abort + +- **Search for existing export** Whether the exporter should search in the entire target directory to determine whether +one of the current channels had previously been exported. +This is necessary to detect an existing export if the name of the channel, the channel parent or the guild has changed +or if the default file formatting has changed. +Default: Disabled + diff --git a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs index f311dc87..7e011784 100644 --- a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs +++ b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs @@ -127,7 +127,7 @@ public class ConsoleProgressLogger(IAnsiConsole console) : ProgressLogger /// /// Prints a summary on all previously logged exports and their respective results to the console. /// - /// The file exists handling of the export whose summary should be printed. + /// The export exists handling of the export whose summary should be printed. public void PrintExportSummary(ExportExistsHandling updateType) { var exportSummary = GetExportSummary(updateType); diff --git a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs index ae3a30db..08f5166c 100644 --- a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs +++ b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs @@ -228,7 +228,7 @@ public class ChannelExporter(DiscordClient discord) } /// - /// Handles the existing export files of the current request according to the set file exists handling. + /// Handles the existing export files of the current request according to the set export exists handling. /// /// The request specifying the current channel export. /// The logger that's used to log progress updates about the export. @@ -268,6 +268,12 @@ public class ChannelExporter(DiscordClient discord) case ExportExistsHandling.Overwrite: logger.LogWarning(request, "Removing existing export files"); MessageExporter.RemoveExistingExport(existingExportFile); + var possibleExistingExportDir = $"{existingExportFile}_Files{Path.DirectorySeparatorChar}"; + if (Directory.Exists(possibleExistingExportDir)) + { + logger.LogWarning(request, "Removing existing export asset files"); + Directory.Delete(possibleExistingExportDir, true); + } currentPartitionIndex = 0; return true; case ExportExistsHandling.Append: @@ -275,6 +281,7 @@ public class ChannelExporter(DiscordClient discord) { logger.LogInfo(request, "Moving existing export files to the new file names"); MessageExporter.MoveExistingExport(existingExportFile, request.OutputFilePath); + // The asset directory isn't renamed as the file contents still point to the old name } var lastMessageSnowflake = MessageExporter.GetLastMessageSnowflake( diff --git a/DiscordChatExporter.Core/Exporting/Logging/ProgressLogger.cs b/DiscordChatExporter.Core/Exporting/Logging/ProgressLogger.cs index c638c3d0..817f2306 100644 --- a/DiscordChatExporter.Core/Exporting/Logging/ProgressLogger.cs +++ b/DiscordChatExporter.Core/Exporting/Logging/ProgressLogger.cs @@ -25,7 +25,7 @@ public abstract class ProgressLogger /// Generates and returns a summary on all previously logged exports and their respective results. /// The summary is returned as one string for each export result that occurred at least once. /// - /// The file exists handling of the export whose summary should be returned. + /// The export exists handling of the export whose summary should be returned. /// A summary on all previously logged exports and their respective results. protected Dictionary GetExportSummary(ExportExistsHandling updateType) { diff --git a/DiscordChatExporter.Gui/Framework/SnackbarManager.cs b/DiscordChatExporter.Gui/Framework/SnackbarManager.cs index 0e502c26..f7d5ae0a 100644 --- a/DiscordChatExporter.Gui/Framework/SnackbarManager.cs +++ b/DiscordChatExporter.Gui/Framework/SnackbarManager.cs @@ -103,7 +103,7 @@ public class SnackbarProgressLogger(SnackbarManager snackbarManager) : ProgressL /// /// Prints a summary on all previously logged exports and their respective results in the GUI snackbar. /// - /// The file exists handling of the export whose summary should be printed. + /// The export exists handling of the export whose summary should be printed. public void PrintExportSummary(ExportExistsHandling updateType) { var exportSummary = GetExportSummary(updateType); diff --git a/Readme.md b/Readme.md index 653a4953..000d4bf6 100644 --- a/Readme.md +++ b/Readme.md @@ -68,6 +68,7 @@ To learn more about the war and how you can help, [click here](https://tyrrrz.me - Multiple output formats: HTML (dark/light), TXT, CSV, JSON - Support for markdown, attachments, embeds, emoji, and other rich media features - File partitioning, date ranges, message filtering, and other export options +- Automatic detection and appending of existing exports - Self-contained exports that can be viewed offline ## Screenshots