This commit is contained in:
Tyrrrz
2023-05-20 07:09:19 +03:00
parent 03c5c1bc5e
commit 31c7ae9312
50 changed files with 181 additions and 198 deletions

View File

@@ -30,8 +30,8 @@ public abstract class ExportCommandBase : DiscordCommandBase
'o',
Description =
"Output file or directory path. " +
"If a directory is specified, file names will be generated automatically based on the channel names and other parameters. " +
"Directory path should end with a slash to avoid ambiguity. " +
"Directory path must end with a slash to avoid ambiguity. " +
"If a directory is specified, file names will be generated automatically. " +
"Supports template tokens, see the documentation for more info."
)]
public string OutputPath
@@ -65,13 +65,16 @@ public abstract class ExportCommandBase : DiscordCommandBase
"partition",
'p',
Description =
"Split output into partitions, each limited to this number of messages (e.g. '100') or file size (e.g. '10mb')."
"Split the output into partitions, each limited to the specified " +
"number of messages (e.g. '100') or file size (e.g. '10mb')."
)]
public PartitionLimit PartitionLimit { get; init; } = PartitionLimit.Null;
[CommandOption(
"filter",
Description = "Only include messages that satisfy this filter (e.g. 'from:foo#1234' or 'has:image')."
Description =
"Only include messages that satisfy this filter. " +
"See the documentation for more info."
)]
public MessageFilter MessageFilter { get; init; } = MessageFilter.Null;
@@ -103,7 +106,9 @@ public abstract class ExportCommandBase : DiscordCommandBase
[CommandOption(
"media-dir",
Description = "Download assets to this directory. If not specified, the asset directory path will be derived from the output path."
Description =
"Download assets to this directory. " +
"If not specified, the asset directory path will be derived from the output path."
)]
public string? AssetsDirPath
{
@@ -123,6 +128,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
"fuck-russia",
EnvironmentVariable = "FUCK_RUSSIA",
Description = "Don't print the Support Ukraine message to the console.",
// Use a converter to accept '1' as 'true' to reuse the existing environment variable
Converter = typeof(TruthyBooleanBindingConverter)
)]
public bool IsUkraineSupportMessageDisabled { get; init; }
@@ -132,7 +138,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Channel> channels)
{
// Reuse assets option should only be used when the download assets option is set.
// Asset reuse can only be enabled if the download assets option is set
// https://github.com/Tyrrrz/DiscordChatExporter/issues/425
if (ShouldReuseAssets && !ShouldDownloadAssets)
{
@@ -141,7 +147,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
);
}
// Assets directory should only be specified when the download assets option is set
// Assets directory can only be specified if the download assets option is set
if (!string.IsNullOrWhiteSpace(AssetsDirPath) && !ShouldDownloadAssets)
{
throw new CommandException(
@@ -149,8 +155,8 @@ public abstract class ExportCommandBase : DiscordCommandBase
);
}
// Make sure the user does not try to export all channels into a single file.
// Output path must either be a directory, or contain template tokens.
// Make sure the user does not try to export multiple channels into one file.
// Output path must either be a directory or contain template tokens for this to work.
// https://github.com/Tyrrrz/DiscordChatExporter/issues/799
// https://github.com/Tyrrrz/DiscordChatExporter/issues/917
var isValidOutputPath =
@@ -225,7 +231,7 @@ public abstract class ExportCommandBase : DiscordCommandBase
);
});
// Print result
// Print the result
using (console.WithForegroundColor(ConsoleColor.White))
{
await console.Output.WriteLineAsync(
@@ -240,28 +246,26 @@ public abstract class ExportCommandBase : DiscordCommandBase
using (console.WithForegroundColor(ConsoleColor.Red))
{
await console.Output.WriteLineAsync(
await console.Error.WriteLineAsync(
$"Failed to export {errors.Count} channel(s):"
);
}
foreach (var (channel, error) in errors)
{
await console.Output.WriteAsync($"{channel.Category.Name} / {channel.Name}: ");
await console.Error.WriteAsync($"{channel.Category.Name} / {channel.Name}: ");
using (console.WithForegroundColor(ConsoleColor.Red))
await console.Output.WriteLineAsync(error);
await console.Error.WriteLineAsync(error);
}
await console.Output.WriteLineAsync();
await console.Error.WriteLineAsync();
}
// Fail the command only if ALL channels failed to export.
// Having some of the channels fail to export is expected.
// If only some channels failed to export, it's okay.
if (errors.Count >= channels.Count)
{
throw new CommandException("Export failed.");
}
}
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Snowflake> channelIds)

View File

@@ -13,7 +13,7 @@ using JsonExtensions.Reading;
namespace DiscordChatExporter.Cli.Commands;
[Command("exportall", Description = "Export all accessible channels.")]
[Command("exportall", Description = "Exports all accessible channels.")]
public class ExportAllCommand : ExportCommandBase
{
[CommandOption(
@@ -30,7 +30,9 @@ public class ExportAllCommand : ExportCommandBase
[CommandOption(
"data-package",
Description = "Path to the personal data package (ZIP file) requested from Discord. If provided, only channels referenced in the dump will be exported."
Description =
"Path to the personal data package (ZIP file) requested from Discord. " +
"If provided, only channels referenced in the dump will be exported."
)]
public string? DataPackageFilePath { get; init; }
@@ -62,7 +64,7 @@ public class ExportAllCommand : ExportCommandBase
var entry = archive.GetEntry("messages/index.json");
if (entry is null)
throw new CommandException("Cannot find channel index inside the data package.");
throw new CommandException("Could not find channel index inside the data package.");
await using var stream = entry.Open();
using var document = await JsonDocument.ParseAsync(stream, default, cancellationToken);
@@ -85,7 +87,7 @@ public class ExportAllCommand : ExportCommandBase
}
catch (DiscordChatExporterException)
{
await console.Output.WriteLineAsync($"Channel '{channelName}' ({channelId}) is inaccessible.");
await console.Error.WriteLineAsync($"Channel '{channelName}' ({channelId}) is inaccessible.");
}
}
}

View File

@@ -7,14 +7,16 @@ using DiscordChatExporter.Core.Discord;
namespace DiscordChatExporter.Cli.Commands;
[Command("export", Description = "Export one or multiple channels.")]
[Command("export", Description = "Exports one or multiple channels.")]
public class ExportChannelsCommand : ExportCommandBase
{
// TODO: change this to plural (breaking change)
[CommandOption(
"channel",
'c',
Description = "Channel ID(s). If provided with category IDs, all channels inside those categories will be exported."
Description =
"Channel ID(s). " +
"If provided with category ID(s), all channels inside those categories will be exported."
)]
public required IReadOnlyList<Snowflake> ChannelIds { get; init; }

View File

@@ -7,7 +7,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("exportdm", Description = "Export all direct message channels.")]
[Command("exportdm", Description = "Exports all direct message channels.")]
public class ExportDirectMessagesCommand : ExportCommandBase
{
public override async ValueTask ExecuteAsync(IConsole console)

View File

@@ -9,7 +9,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("exportguild", Description = "Export all channels within specified guild.")]
[Command("exportguild", Description = "Exports all channels within the specified guild.")]
public class ExportGuildCommand : ExportCommandBase
{
[CommandOption(

View File

@@ -22,7 +22,7 @@ public class GetChannelsCommand : DiscordCommandBase
[CommandOption(
"include-threads",
Description = "Display threads alongside channels."
Description = "Include threads in the output."
)]
public bool IncludeThreads { get; init; }

View File

@@ -9,7 +9,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("dm", Description = "Get the list of direct message channels.")]
[Command("dm", Description = "Gets the list of all direct message channels.")]
public class GetDirectChannelsCommand : DiscordCommandBase
{
public override async ValueTask ExecuteAsync(IConsole console)

View File

@@ -9,7 +9,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
namespace DiscordChatExporter.Cli.Commands;
[Command("guilds", Description = "Get the list of accessible guilds.")]
[Command("guilds", Description = "Gets the list of accessible guilds.")]
public class GetGuildsCommand : DiscordCommandBase
{
public override async ValueTask ExecuteAsync(IConsole console)

View File

@@ -6,7 +6,7 @@ using CliFx.Infrastructure;
namespace DiscordChatExporter.Cli.Commands;
[Command("guide", Description = "Explains how to obtain token, guild or channel ID.")]
[Command("guide", Description = "Explains how to obtain the token, guild or channel ID.")]
public class GuideCommand : ICommand
{
public ValueTask ExecuteAsync(IConsole console)