mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-05-11 22:54:09 +00:00
Restructure commands: list channels/guilds subcommands with positional parameters
Agent-Logs-Url: https://github.com/Tyrrrz/DiscordChatExporter/sessions/27f23ff6-5b39-46d3-a7dc-387749ee63fa Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
16ecb2802a
commit
0e3b455655
@@ -13,14 +13,13 @@ namespace DiscordChatExporter.Cli.Commands;
|
||||
[Command("export", Description = "Exports one or multiple channels.")]
|
||||
public partial class ExportChannelsCommand : ExportCommandBase
|
||||
{
|
||||
// TODO: change this to plural (breaking change)
|
||||
[CommandOption(
|
||||
"channel",
|
||||
'c',
|
||||
[CommandParameter(
|
||||
0,
|
||||
Name = "channel-ids",
|
||||
Description = "Channel ID(s). "
|
||||
+ "If provided with category ID(s), all channels inside those categories will be exported. "
|
||||
+ "If not provided, channel IDs are read from standard input (one per line), "
|
||||
+ "enabling piping from the 'channels' or 'dm' commands."
|
||||
+ "enabling piping from the 'list channels' or 'list channels dm' commands."
|
||||
)]
|
||||
public IReadOnlyList<Snowflake> ChannelIds { get; set; } = [];
|
||||
|
||||
@@ -60,7 +59,7 @@ public partial class ExportChannelsCommand : ExportCommandBase
|
||||
{
|
||||
throw new CommandException(
|
||||
"No channel IDs provided. "
|
||||
+ "Specify channel IDs via the '--channel' option or pipe them from the 'channels' or 'dm' commands."
|
||||
+ "Specify channel IDs as arguments or pipe them from the 'list channels' or 'list channels dm' commands."
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using CliFx.Binding;
|
||||
@@ -7,15 +8,16 @@ using DiscordChatExporter.Cli.Commands.Base;
|
||||
using DiscordChatExporter.Cli.Commands.Converters;
|
||||
using DiscordChatExporter.Cli.Commands.Shared;
|
||||
using DiscordChatExporter.Core.Discord;
|
||||
using DiscordChatExporter.Core.Discord.Data;
|
||||
using DiscordChatExporter.Core.Utils.Extensions;
|
||||
|
||||
namespace DiscordChatExporter.Cli.Commands;
|
||||
|
||||
[Command("channels", Description = "Get the list of channels in a server.")]
|
||||
[Command("list channels", Description = "Gets the list of channels in one or more servers.")]
|
||||
public partial class GetChannelsCommand : DiscordCommandBase
|
||||
{
|
||||
[CommandOption("guild", 'g', Description = "Server ID.")]
|
||||
public required Snowflake GuildId { get; set; }
|
||||
[CommandParameter(0, Name = "guild-ids", Description = "Server ID(s).")]
|
||||
public required IReadOnlyList<Snowflake> GuildIds { get; set; }
|
||||
|
||||
[CommandOption("include-vc", Description = "Include voice channels.")]
|
||||
public bool IncludeVoiceChannels { get; set; } = true;
|
||||
@@ -33,94 +35,109 @@ public partial class GetChannelsCommand : DiscordCommandBase
|
||||
|
||||
var cancellationToken = console.RegisterCancellationHandler();
|
||||
|
||||
var channels = (await Discord.GetGuildChannelsAsync(GuildId, cancellationToken))
|
||||
.Where(c => !c.IsCategory)
|
||||
.Where(c => IncludeVoiceChannels || !c.IsVoice)
|
||||
.OrderBy(c => c.Parent?.Position)
|
||||
.ThenBy(c => c.Name)
|
||||
.ToArray();
|
||||
foreach (var guildId in GuildIds)
|
||||
{
|
||||
var channels = (await Discord.GetGuildChannelsAsync(guildId, cancellationToken))
|
||||
.Where(c => !c.IsCategory)
|
||||
.Where(c => IncludeVoiceChannels || !c.IsVoice)
|
||||
.OrderBy(c => c.Parent?.Position)
|
||||
.ThenBy(c => c.Name)
|
||||
.ToArray();
|
||||
|
||||
var channelIdMaxLength = channels
|
||||
.Select(c => c.Id.ToString().Length)
|
||||
.OrderDescending()
|
||||
.FirstOrDefault();
|
||||
|
||||
var threads =
|
||||
ThreadInclusionMode != ThreadInclusionMode.None
|
||||
? (
|
||||
await Discord.GetGuildThreadsAsync(
|
||||
GuildId,
|
||||
ThreadInclusionMode == ThreadInclusionMode.All,
|
||||
null,
|
||||
null,
|
||||
cancellationToken
|
||||
var threads =
|
||||
ThreadInclusionMode != ThreadInclusionMode.None
|
||||
? (
|
||||
await Discord.GetGuildThreadsAsync(
|
||||
guildId,
|
||||
ThreadInclusionMode == ThreadInclusionMode.All,
|
||||
null,
|
||||
null,
|
||||
cancellationToken
|
||||
)
|
||||
)
|
||||
)
|
||||
.OrderBy(c => c.Name)
|
||||
.ToArray()
|
||||
: [];
|
||||
.OrderBy(c => c.Name)
|
||||
.ToArray()
|
||||
: [];
|
||||
|
||||
// If output is redirected, print only channel IDs (one per line) for easy piping
|
||||
if (console.IsOutputRedirected)
|
||||
{
|
||||
foreach (var channel in channels)
|
||||
// If output is redirected, print only channel IDs (one per line) for easy piping
|
||||
if (console.IsOutputRedirected)
|
||||
{
|
||||
await console.Output.WriteLineAsync(channel.Id.ToString());
|
||||
foreach (var channelThread in threads.Where(t => t.Parent?.Id == channel.Id))
|
||||
await console.Output.WriteLineAsync(channelThread.Id.ToString());
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
await console.Output.WriteLineAsync(channel.Id.ToString());
|
||||
foreach (var channelThread in threads.Where(t => t.Parent?.Id == channel.Id))
|
||||
await console.Output.WriteLineAsync(channelThread.Id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var channel in channels)
|
||||
else
|
||||
{
|
||||
// Channel ID
|
||||
await console.Output.WriteAsync(
|
||||
channel.Id.ToString().PadRight(channelIdMaxLength, ' ')
|
||||
);
|
||||
// Show guild header when listing multiple guilds
|
||||
if (GuildIds.Count > 1)
|
||||
{
|
||||
var guild = await Discord.GetGuildAsync(guildId, cancellationToken);
|
||||
|
||||
// Separator
|
||||
using (console.WithForegroundColor(ConsoleColor.DarkGray))
|
||||
await console.Output.WriteAsync(" | ");
|
||||
using (console.WithForegroundColor(ConsoleColor.Cyan))
|
||||
await console.Output.WriteLineAsync($"{guild.Id} | {guild.Name}");
|
||||
}
|
||||
|
||||
// Channel name
|
||||
using (console.WithForegroundColor(ConsoleColor.White))
|
||||
await console.Output.WriteLineAsync(channel.GetHierarchicalName());
|
||||
|
||||
var channelThreads = threads.Where(t => t.Parent?.Id == channel.Id).ToArray();
|
||||
var channelThreadIdMaxLength = channelThreads
|
||||
.Select(t => t.Id.ToString().Length)
|
||||
var channelIdMaxLength = channels
|
||||
.Select(c => c.Id.ToString().Length)
|
||||
.OrderDescending()
|
||||
.FirstOrDefault();
|
||||
|
||||
foreach (var channelThread in channelThreads)
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
// Indent
|
||||
await console.Output.WriteAsync(" * ");
|
||||
|
||||
// Thread ID
|
||||
// Channel ID
|
||||
await console.Output.WriteAsync(
|
||||
channelThread.Id.ToString().PadRight(channelThreadIdMaxLength, ' ')
|
||||
channel.Id.ToString().PadRight(channelIdMaxLength, ' ')
|
||||
);
|
||||
|
||||
// Separator
|
||||
using (console.WithForegroundColor(ConsoleColor.DarkGray))
|
||||
await console.Output.WriteAsync(" | ");
|
||||
|
||||
// Thread name
|
||||
// Channel name
|
||||
using (console.WithForegroundColor(ConsoleColor.White))
|
||||
await console.Output.WriteAsync($"Thread / {channelThread.Name}");
|
||||
await console.Output.WriteLineAsync(channel.GetHierarchicalName());
|
||||
|
||||
// Separator
|
||||
using (console.WithForegroundColor(ConsoleColor.DarkGray))
|
||||
await console.Output.WriteAsync(" | ");
|
||||
var channelThreads = threads.Where(t => t.Parent?.Id == channel.Id).ToArray();
|
||||
var channelThreadIdMaxLength = channelThreads
|
||||
.Select(t => t.Id.ToString().Length)
|
||||
.OrderDescending()
|
||||
.FirstOrDefault();
|
||||
|
||||
// Thread status
|
||||
using (console.WithForegroundColor(ConsoleColor.White))
|
||||
await console.Output.WriteLineAsync(
|
||||
channelThread.IsArchived ? "Archived" : "Active"
|
||||
foreach (var channelThread in channelThreads)
|
||||
{
|
||||
// Indent
|
||||
await console.Output.WriteAsync(" * ");
|
||||
|
||||
// Thread ID
|
||||
await console.Output.WriteAsync(
|
||||
channelThread.Id.ToString().PadRight(channelThreadIdMaxLength, ' ')
|
||||
);
|
||||
|
||||
// Separator
|
||||
using (console.WithForegroundColor(ConsoleColor.DarkGray))
|
||||
await console.Output.WriteAsync(" | ");
|
||||
|
||||
// Thread name
|
||||
using (console.WithForegroundColor(ConsoleColor.White))
|
||||
await console.Output.WriteAsync($"Thread / {channelThread.Name}");
|
||||
|
||||
// Separator
|
||||
using (console.WithForegroundColor(ConsoleColor.DarkGray))
|
||||
await console.Output.WriteAsync(" | ");
|
||||
|
||||
// Thread status
|
||||
using (console.WithForegroundColor(ConsoleColor.White))
|
||||
await console.Output.WriteLineAsync(
|
||||
channelThread.IsArchived ? "Archived" : "Active"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (GuildIds.Count > 1)
|
||||
await console.Output.WriteLineAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
|
||||
|
||||
namespace DiscordChatExporter.Cli.Commands;
|
||||
|
||||
[Command("dm", Description = "Gets the list of all direct message channels.")]
|
||||
[Command("list channels dm", Description = "Gets the list of direct message channels.")]
|
||||
public partial class GetDirectChannelsCommand : DiscordCommandBase
|
||||
{
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
|
||||
@@ -9,7 +9,7 @@ using DiscordChatExporter.Core.Utils.Extensions;
|
||||
|
||||
namespace DiscordChatExporter.Cli.Commands;
|
||||
|
||||
[Command("guilds", Description = "Gets the list of accessible servers.")]
|
||||
[Command("list guilds", Description = "Gets the list of accessible servers.")]
|
||||
public partial class GetGuildsCommand : DiscordCommandBase
|
||||
{
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
|
||||
Reference in New Issue
Block a user