|
|
|
@ -11,6 +11,7 @@ using DiscordChatExporter.Cli.Commands.Converters;
|
|
|
|
|
using DiscordChatExporter.Cli.Utils.Extensions;
|
|
|
|
|
using DiscordChatExporter.Core.Discord;
|
|
|
|
|
using DiscordChatExporter.Core.Discord.Data;
|
|
|
|
|
using DiscordChatExporter.Core.Discord.Data.Common;
|
|
|
|
|
using DiscordChatExporter.Core.Exceptions;
|
|
|
|
|
using DiscordChatExporter.Core.Exporting;
|
|
|
|
|
using DiscordChatExporter.Core.Exporting.Filtering;
|
|
|
|
@ -136,7 +137,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
|
|
|
|
private ChannelExporter? _channelExporter;
|
|
|
|
|
protected ChannelExporter Exporter => _channelExporter ??= new ChannelExporter(Discord);
|
|
|
|
|
|
|
|
|
|
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Channel> channels)
|
|
|
|
|
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<IChannel> channels)
|
|
|
|
|
{
|
|
|
|
|
// Asset reuse can only be enabled if the download assets option is set
|
|
|
|
|
// https://github.com/Tyrrrz/DiscordChatExporter/issues/425
|
|
|
|
@ -175,9 +176,9 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Export
|
|
|
|
|
// Export channels
|
|
|
|
|
var cancellationToken = console.RegisterCancellationHandler();
|
|
|
|
|
var errors = new ConcurrentDictionary<Channel, string>();
|
|
|
|
|
var channelErrors = new ConcurrentDictionary<IChannel, string>();
|
|
|
|
|
|
|
|
|
|
await console.Output.WriteLineAsync($"Exporting {channels.Count} channel(s)...");
|
|
|
|
|
await console.CreateProgressTicker().StartAsync(async progressContext =>
|
|
|
|
@ -194,7 +195,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await progressContext.StartTaskAsync(
|
|
|
|
|
$"{channel.Category.Name} / {channel.Name}",
|
|
|
|
|
$"{channel.ParentName} / {channel.Name}",
|
|
|
|
|
async progress =>
|
|
|
|
|
{
|
|
|
|
|
var guild = await Discord.GetGuildAsync(channel.GuildId, innerCancellationToken);
|
|
|
|
@ -225,7 +226,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
|
|
|
|
}
|
|
|
|
|
catch (DiscordChatExporterException ex) when (!ex.IsFatal)
|
|
|
|
|
{
|
|
|
|
|
errors[channel] = ex.Message;
|
|
|
|
|
channelErrors[channel] = ex.Message;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
@ -235,25 +236,25 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
|
|
|
|
using (console.WithForegroundColor(ConsoleColor.White))
|
|
|
|
|
{
|
|
|
|
|
await console.Output.WriteLineAsync(
|
|
|
|
|
$"Successfully exported {channels.Count - errors.Count} channel(s)."
|
|
|
|
|
$"Successfully exported {channels.Count - channelErrors.Count} channel(s)."
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Print errors
|
|
|
|
|
if (errors.Any())
|
|
|
|
|
if (channelErrors.Any())
|
|
|
|
|
{
|
|
|
|
|
await console.Output.WriteLineAsync();
|
|
|
|
|
|
|
|
|
|
using (console.WithForegroundColor(ConsoleColor.Red))
|
|
|
|
|
{
|
|
|
|
|
await console.Error.WriteLineAsync(
|
|
|
|
|
$"Failed to export {errors.Count} channel(s):"
|
|
|
|
|
$"Failed to export {channelErrors.Count} channel(s):"
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var (channel, error) in errors)
|
|
|
|
|
foreach (var (channel, error) in channelErrors)
|
|
|
|
|
{
|
|
|
|
|
await console.Error.WriteAsync($"{channel.Category.Name} / {channel.Name}: ");
|
|
|
|
|
await console.Error.WriteAsync($"{channel.ParentName} / {channel.Name}: ");
|
|
|
|
|
|
|
|
|
|
using (console.WithForegroundColor(ConsoleColor.Red))
|
|
|
|
|
await console.Error.WriteLineAsync(error);
|
|
|
|
@ -264,7 +265,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
|
|
|
|
|
|
|
|
|
|
// Fail the command only if ALL channels failed to export.
|
|
|
|
|
// If only some channels failed to export, it's okay.
|
|
|
|
|
if (errors.Count >= channels.Count)
|
|
|
|
|
if (channelErrors.Count >= channels.Count)
|
|
|
|
|
throw new CommandException("Export failed.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|