mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-05-21 16:25:08 +00:00
Add 'list unwrap' command; remove category unwrapping from export; add [!IMPORTANT] callouts to pipeline doc sections
Agent-Logs-Url: https://github.com/Tyrrrz/DiscordChatExporter/sessions/d2a03a38-0ed4-45c7-b8e7-615ffb35c971 Co-authored-by: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
7f08641974
commit
f8ab926074
@@ -33,13 +33,14 @@ Type the following command in your terminal of choice, then press ENTER to run i
|
|||||||
|
|
||||||
## CLI commands
|
## CLI commands
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
| ----------------- | ---------------------------------------------------- |
|
| ----------------- | -------------------------------------------------------------------- |
|
||||||
| export | Exports one or more channels |
|
| export | Exports one or more channels |
|
||||||
| list channels | Outputs the list of channels in the given server(s) |
|
| list channels | Outputs the list of channels in the given server(s) |
|
||||||
| list channels dm | Outputs the list of direct message channels |
|
| list channels dm | Outputs the list of direct message channels |
|
||||||
| list servers | Outputs the list of accessible servers |
|
| list servers | Outputs the list of accessible servers |
|
||||||
| guide | Explains how to obtain token, server, and channel ID |
|
| list unwrap | Resolves categories in a channel list to their child channels |
|
||||||
|
| guide | Explains how to obtain token, server, and channel ID |
|
||||||
|
|
||||||
To use the commands, you'll need a token. For the instructions on how to get a token, please refer to [this page](Token-and-IDs.md), or run `./dce guide`.
|
To use the commands, you'll need a token. For the instructions on how to get a token, please refer to [this page](Token-and-IDs.md), or run `./dce guide`.
|
||||||
|
|
||||||
@@ -244,6 +245,9 @@ Documentation on message filter syntax can be found [here](https://github.com/Ty
|
|||||||
|
|
||||||
### Export channels from a specific server
|
### Export channels from a specific server
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> The following examples assume `DISCORD_TOKEN` is already set. See [CLI commands](#cli-commands) for instructions.
|
||||||
|
|
||||||
To export all channels in a specific server, use `list channels` to list channels and pipe the result to `export`.
|
To export all channels in a specific server, use `list channels` to list channels and pipe the result to `export`.
|
||||||
|
|
||||||
**Linux/macOS:**
|
**Linux/macOS:**
|
||||||
@@ -282,6 +286,9 @@ By default, voice channels are included. You can change this behavior by passing
|
|||||||
|
|
||||||
### Export all DMs
|
### Export all DMs
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> The following examples assume `DISCORD_TOKEN` is already set. See [CLI commands](#cli-commands) for instructions.
|
||||||
|
|
||||||
To export all DMs:
|
To export all DMs:
|
||||||
|
|
||||||
**Linux/macOS:**
|
**Linux/macOS:**
|
||||||
@@ -304,7 +311,7 @@ To list the channels available in a specific server, use the `list channels` com
|
|||||||
./dce list channels 21814 -t "mfa.Ifrn"
|
./dce list channels 21814 -t "mfa.Ifrn"
|
||||||
```
|
```
|
||||||
|
|
||||||
When the output is redirected or piped, the `list channels` command prints only channel IDs (one per line). This allows you to pipe the output directly to the `export` command:
|
The `list channels` command outputs a JSON array of channel objects. You can pipe this directly to the `export` command:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
./dce list channels 21814 | ./dce export
|
./dce list channels 21814 | ./dce export
|
||||||
@@ -318,12 +325,20 @@ To list all DM channels accessible to the current account, use the `list channel
|
|||||||
./dce list channels dm -t "mfa.Ifrn"
|
./dce list channels dm -t "mfa.Ifrn"
|
||||||
```
|
```
|
||||||
|
|
||||||
When the output is redirected or piped, the `list channels dm` command prints only channel IDs (one per line). This allows you to pipe the output directly to the `export` command:
|
The `list channels dm` command outputs a JSON array of channel objects. You can pipe this directly to the `export` command:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
./dce list channels dm | ./dce export
|
./dce list channels dm | ./dce export
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Unwrap categories
|
||||||
|
|
||||||
|
To resolve category channels in a list to their child channels, use the `list unwrap` command:
|
||||||
|
|
||||||
|
```console
|
||||||
|
./dce list channels 21814 | ./dce list unwrap | ./dce export
|
||||||
|
```
|
||||||
|
|
||||||
### List servers
|
### List servers
|
||||||
|
|
||||||
To list all servers accessible by the current account, use the `list servers` command:
|
To list all servers accessible by the current account, use the `list servers` command:
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using DiscordChatExporter.Cli.Commands.Base;
|
|||||||
using DiscordChatExporter.Cli.Utils.Extensions;
|
using DiscordChatExporter.Cli.Utils.Extensions;
|
||||||
using DiscordChatExporter.Core.Discord;
|
using DiscordChatExporter.Core.Discord;
|
||||||
using DiscordChatExporter.Core.Discord.Data;
|
using DiscordChatExporter.Core.Discord.Data;
|
||||||
using DiscordChatExporter.Core.Utils.Extensions;
|
|
||||||
|
|
||||||
namespace DiscordChatExporter.Cli.Commands;
|
namespace DiscordChatExporter.Cli.Commands;
|
||||||
|
|
||||||
@@ -19,8 +18,7 @@ public partial class ExportChannelsCommand : ExportCommandBase
|
|||||||
0,
|
0,
|
||||||
Name = "channel-ids",
|
Name = "channel-ids",
|
||||||
Description = "Channel ID(s). "
|
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 or as a JSON array), "
|
||||||
+ "If not provided, channel IDs are read from standard input (one per line), "
|
|
||||||
+ "enabling piping from the 'list channels' or 'list channels dm' commands."
|
+ "enabling piping from the 'list channels' or 'list channels dm' commands."
|
||||||
)]
|
)]
|
||||||
public IReadOnlyList<Snowflake> ChannelIds { get; set; } = [];
|
public IReadOnlyList<Snowflake> ChannelIds { get; set; } = [];
|
||||||
@@ -66,32 +64,11 @@ public partial class ExportChannelsCommand : ExportCommandBase
|
|||||||
await console.Output.WriteLineAsync("Resolving channel(s)...");
|
await console.Output.WriteLineAsync("Resolving channel(s)...");
|
||||||
|
|
||||||
var channels = new List<Channel>();
|
var channels = new List<Channel>();
|
||||||
var channelsByGuild = new Dictionary<Snowflake, IReadOnlyList<Channel>>();
|
|
||||||
|
|
||||||
foreach (var channelId in channelIds)
|
foreach (var channelId in channelIds)
|
||||||
{
|
{
|
||||||
var channel = await Discord.GetChannelAsync(channelId, cancellationToken);
|
var channel = await Discord.GetChannelAsync(channelId, cancellationToken);
|
||||||
|
channels.Add(channel);
|
||||||
// Unwrap categories
|
|
||||||
if (channel.IsCategory)
|
|
||||||
{
|
|
||||||
var guildChannels =
|
|
||||||
channelsByGuild.GetValueOrDefault(channel.GuildId)
|
|
||||||
?? await Discord.GetGuildChannelsAsync(channel.GuildId, cancellationToken);
|
|
||||||
|
|
||||||
foreach (var guildChannel in guildChannels)
|
|
||||||
{
|
|
||||||
if (guildChannel.Parent?.Id == channel.Id)
|
|
||||||
channels.Add(guildChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache the guild channels to avoid redundant work
|
|
||||||
channelsByGuild[channel.GuildId] = guildChannels;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
channels.Add(channel);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await ExportAsync(console, channels);
|
await ExportAsync(console, channels);
|
||||||
|
|||||||
71
DiscordChatExporter.Cli/Commands/UnwrapChannelsCommand.cs
Normal file
71
DiscordChatExporter.Cli/Commands/UnwrapChannelsCommand.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using CliFx.Binding;
|
||||||
|
using CliFx.Infrastructure;
|
||||||
|
using DiscordChatExporter.Cli.Commands.Base;
|
||||||
|
using DiscordChatExporter.Cli.Utils.Extensions;
|
||||||
|
using DiscordChatExporter.Cli.Utils.Json;
|
||||||
|
using DiscordChatExporter.Core.Discord;
|
||||||
|
using DiscordChatExporter.Core.Discord.Data;
|
||||||
|
using DiscordChatExporter.Core.Utils.Extensions;
|
||||||
|
|
||||||
|
namespace DiscordChatExporter.Cli.Commands;
|
||||||
|
|
||||||
|
[Command(
|
||||||
|
"list unwrap",
|
||||||
|
Description = "Resolves categories in a channel list to their child channels."
|
||||||
|
)]
|
||||||
|
public partial class UnwrapChannelsCommand : DiscordCommandBase
|
||||||
|
{
|
||||||
|
public override async ValueTask ExecuteAsync(IConsole console)
|
||||||
|
{
|
||||||
|
await base.ExecuteAsync(console);
|
||||||
|
|
||||||
|
var cancellationToken = console.RegisterCancellationHandler();
|
||||||
|
|
||||||
|
// Read all JSON from stdin (produced by 'list channels' or 'list channels dm')
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
await foreach (var line in console.Input.ReadLinesAsync(cancellationToken))
|
||||||
|
sb.Append(line);
|
||||||
|
|
||||||
|
var channels =
|
||||||
|
JsonSerializer.Deserialize(
|
||||||
|
sb.ToString().Trim(),
|
||||||
|
CliJsonSerializerContext.Instance.ChannelArray
|
||||||
|
) ?? [];
|
||||||
|
|
||||||
|
var result = new List<Channel>();
|
||||||
|
var channelsByGuild = new Dictionary<Snowflake, IReadOnlyList<Channel>>();
|
||||||
|
|
||||||
|
foreach (var channel in channels)
|
||||||
|
{
|
||||||
|
if (channel.IsCategory)
|
||||||
|
{
|
||||||
|
var guildChannels =
|
||||||
|
channelsByGuild.GetValueOrDefault(channel.GuildId)
|
||||||
|
?? await Discord.GetGuildChannelsAsync(channel.GuildId, cancellationToken);
|
||||||
|
|
||||||
|
foreach (var guildChannel in guildChannels)
|
||||||
|
{
|
||||||
|
if (guildChannel.Parent?.Id == channel.Id)
|
||||||
|
result.Add(guildChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
channelsByGuild[channel.GuildId] = guildChannels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Add(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await console.Output.WriteLineAsync(
|
||||||
|
JsonSerializer.Serialize(
|
||||||
|
result.ToArray(),
|
||||||
|
CliJsonSerializerContext.Instance.ChannelArray
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user