diff --git a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
index 354d9e0e..95acf168 100644
--- a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
+++ b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs
@@ -115,11 +115,18 @@ public abstract class ExportCommandBase : DiscordCommandBase
}
[CommandOption(
- "prev-export",
- Description = "What the exporter should do if the channel had already been exported."
+ "export-exists",
+ Description = "What the exporter should do if a channel had already been exported."
)]
public ExportExistsHandling ExportExistsHandling { get; init; } = ExportExistsHandling.Abort;
+ [CommandOption(
+ "search-existing-exports",
+ Description = "Whether the target directory should be searched for existing export(s) of the channel(s). "
+ + "This is required to find an existing export if the channel, channel parent or guild name has changed."
+ )]
+ public bool SearchForExistingExports { get; init; }
+
[Obsolete("This option doesn't do anything. Kept for backwards compatibility.")]
[CommandOption(
"dateformat",
@@ -272,6 +279,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
After,
Before,
ExportExistsHandling,
+ SearchForExistingExports,
PartitionLimit,
MessageFilter,
ShouldFormatMarkdown,
diff --git a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs
index dd132e8a..f311dc87 100644
--- a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs
+++ b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs
@@ -78,21 +78,21 @@ public class ConsoleProgressLogger(IAnsiConsole console) : ProgressLogger
/// The ConsoleProgressLogger logs the success message to the console.
public override void LogSuccess(ExportRequest request, string message)
{
- LogMessage("SUCCESS", "[green]", request, message);
+ LogMessage("SUCCESS", "green", request, message);
}
///
/// The ConsoleProgressLogger logs the informational message to the console.
public override void LogInfo(ExportRequest request, string message)
{
- LogMessage("INFO", "[default]", request, message);
+ LogMessage("INFO", "default", request, message);
}
///
/// The ConsoleProgressLogger logs the warning message to the console.
public override void LogWarning(ExportRequest request, string message)
{
- LogMessage("WARNING", "[yellow]", request, message);
+ LogMessage("WARNING", "yellow", request, message);
}
///
@@ -100,7 +100,7 @@ public class ConsoleProgressLogger(IAnsiConsole console) : ProgressLogger
public override void LogError(ExportRequest? request, string message)
{
IncrementCounter(ExportResult.ExportError);
- LogMessage("ERROR", "[red]", request, message);
+ LogMessage("ERROR", "red", request, message);
}
///
@@ -120,8 +120,8 @@ public class ConsoleProgressLogger(IAnsiConsole console) : ProgressLogger
channelInfo =
request.Guild.Name + " / " + request.Channel.GetHierarchicalName() + " | ";
- var logMessage = $"{color}{paddedCategory}{channelInfo}{message}[/]";
- console.MarkupLine(logMessage);
+ FormattableString logMessage = $"[{color}]{paddedCategory}{channelInfo}{message}[/]";
+ console.MarkupLineInterpolated(logMessage);
}
///
diff --git a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs
index 2348b5c7..ae3a30db 100644
--- a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs
+++ b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs
@@ -35,13 +35,11 @@ public class ChannelExporter(DiscordClient discord)
return;
}
- // TODO: Add a way for the user to choose the setting
- var searchForExistingExport = true;
if (
!DetectExistingExport(
request,
logger,
- searchForExistingExport,
+ request.SearchForExistingExports,
outputDirFilesDict,
out var existingExportFile
)
@@ -215,7 +213,7 @@ public class ChannelExporter(DiscordClient discord)
logger.LogError(
request,
"Found multiple existing channel exports under different file names: "
- + string.Join(", ", regexFiles)
+ + string.Join(", ", regexFiles.Select(fileName => $"\"{fileName}\""))
+ "."
);
return false;
@@ -223,7 +221,7 @@ public class ChannelExporter(DiscordClient discord)
logger.LogInfo(
request,
- "Found existing channel export under file name " + regexFiles[0] + "."
+ $"Found existing channel export under file name \"{regexFiles[0]}\"."
);
existingExportFile = Path.Combine(request.OutputDirPath, regexFiles[0]);
return true;
diff --git a/DiscordChatExporter.Core/Exporting/ExportRequest.cs b/DiscordChatExporter.Core/Exporting/ExportRequest.cs
index 5abe25fb..248e6754 100644
--- a/DiscordChatExporter.Core/Exporting/ExportRequest.cs
+++ b/DiscordChatExporter.Core/Exporting/ExportRequest.cs
@@ -32,6 +32,8 @@ public partial class ExportRequest
public ExportExistsHandling ExportExistsHandling { get; }
+ public bool SearchForExistingExports { get; }
+
public Snowflake? LastPriorMessage { get; set; }
public PartitionLimit PartitionLimit { get; }
@@ -59,6 +61,7 @@ public partial class ExportRequest
Snowflake? after,
Snowflake? before,
ExportExistsHandling exportExistsHandling,
+ bool searchForExistingExports,
PartitionLimit partitionLimit,
MessageFilter messageFilter,
bool shouldFormatMarkdown,
@@ -74,6 +77,7 @@ public partial class ExportRequest
After = after;
Before = before;
ExportExistsHandling = exportExistsHandling;
+ SearchForExistingExports = searchForExistingExports;
PartitionLimit = partitionLimit;
MessageFilter = messageFilter;
ShouldFormatMarkdown = shouldFormatMarkdown;
diff --git a/DiscordChatExporter.Gui/Services/SettingsService.cs b/DiscordChatExporter.Gui/Services/SettingsService.cs
index a56da7e1..bb2ed219 100644
--- a/DiscordChatExporter.Gui/Services/SettingsService.cs
+++ b/DiscordChatExporter.Gui/Services/SettingsService.cs
@@ -39,6 +39,9 @@ public partial class SettingsService()
[ObservableProperty]
public partial ExportExistsHandling ExportExistsHandling { get; set; }
+ [ObservableProperty]
+ public partial bool SearchForExistingExports { get; set; }
+
[ObservableProperty]
public partial string? Locale { get; set; }
diff --git a/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs
index 2f9761b0..be843c6b 100644
--- a/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs
+++ b/DiscordChatExporter.Gui/ViewModels/Components/DashboardViewModel.cs
@@ -272,6 +272,7 @@ public partial class DashboardViewModel : ViewModelBase
dialog.After?.Pipe(timestamp => Snowflake.FromDate(timestamp, true)),
dialog.Before?.Pipe(timestamp => Snowflake.FromDate(timestamp)),
_settingsService.ExportExistsHandling,
+ _settingsService.SearchForExistingExports,
dialog.PartitionLimit,
dialog.MessageFilter,
dialog.ShouldFormatMarkdown,
diff --git a/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs
index 8d96f0d1..8283703e 100644
--- a/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs
+++ b/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs
@@ -71,6 +71,12 @@ public class SettingsViewModel : DialogViewModelBase
set => _settingsService.ExportExistsHandling = value;
}
+ public bool SearchForExistingExports
+ {
+ get => _settingsService.SearchForExistingExports;
+ set => _settingsService.SearchForExistingExports = value;
+ }
+
// These items have to be non-nullable because Avalonia ComboBox doesn't allow a null value to be selected
public IReadOnlyList AvailableLocales { get; } =
[
diff --git a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.axaml b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.axaml
index b1cc5abf..29f99a82 100644
--- a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.axaml
+++ b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.axaml
@@ -136,14 +136,23 @@
-
+ ToolTip.Tip="What the exporter should do if a channel had already been exported">
+
+
+
+
+
+
+