mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-06-02 23:59:50 -04:00
Refactor
This commit is contained in:
parent
9583e2684d
commit
9601e0acea
3 changed files with 41 additions and 34 deletions
|
@ -39,11 +39,17 @@ public partial record Channel(
|
|||
_ => "Default"
|
||||
};
|
||||
|
||||
public bool IsEmpty => LastMessageId is null;
|
||||
|
||||
// Only needed for WPF data binding. Don't use anywhere else.
|
||||
public bool IsVoice => Kind.IsVoice();
|
||||
|
||||
// Only needed for WPF data binding. Don't use anywhere else.
|
||||
public bool IsThread => Kind.IsThread();
|
||||
|
||||
public bool MayHaveMessagesAfter(Snowflake messageId) => !IsEmpty && messageId < LastMessageId;
|
||||
|
||||
public bool MayHaveMessagesBefore(Snowflake messageId) => !IsEmpty && messageId > Id;
|
||||
}
|
||||
|
||||
public partial record Channel
|
||||
|
|
|
@ -286,23 +286,25 @@ public class DiscordClient
|
|||
yield break;
|
||||
|
||||
var tokenKind = _resolvedTokenKind ??= await GetTokenKindAsync(cancellationToken);
|
||||
var channels = await GetGuildChannelsAsync(guildId, cancellationToken);
|
||||
|
||||
var filteredChannels = channels
|
||||
var channels = (await GetGuildChannelsAsync(guildId, cancellationToken))
|
||||
// Categories cannot have threads
|
||||
.Where(c => c.Kind != ChannelKind.GuildCategory)
|
||||
// Voice channels cannot have threads
|
||||
.Where(c => !c.Kind.IsVoice())
|
||||
// Ordinary channel or forum channel without LastMessageId cannot have threads
|
||||
.Where(c => c.LastMessageId != null)
|
||||
// Ff --before is specified, skip channels created after the specified date
|
||||
.Where(c => before == null || before > c.Id);
|
||||
// Empty channels cannot have threads
|
||||
.Where(c => !c.IsEmpty)
|
||||
// If the 'before' boundary is specified, skip channels that don't have messages
|
||||
// for that range, because thread-start event should always be accompanied by a message.
|
||||
// Note that we don't perform a similar check for the 'after' boundary, because
|
||||
// threads may have messages in range, even if the parent channel doesn't.
|
||||
.Where(c => before is null || c.MayHaveMessagesBefore(before.Value))
|
||||
.ToArray();
|
||||
|
||||
// User accounts can only fetch threads using the search endpoint
|
||||
if (tokenKind == TokenKind.User)
|
||||
{
|
||||
// Active threads
|
||||
foreach (var channel in filteredChannels)
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
var currentOffset = 0;
|
||||
while (true)
|
||||
|
@ -320,7 +322,7 @@ public class DiscordClient
|
|||
if (response is null)
|
||||
break;
|
||||
|
||||
var containsOlder = false;
|
||||
var breakOuter = false;
|
||||
|
||||
foreach (
|
||||
var threadJson in response.Value.GetProperty("threads").EnumerateArray()
|
||||
|
@ -328,19 +330,19 @@ public class DiscordClient
|
|||
{
|
||||
var thread = Channel.Parse(threadJson, channel);
|
||||
|
||||
// if --after is specified, we can break early, because the threads are sorted by last message time
|
||||
if (after is not null && after > thread.LastMessageId)
|
||||
// If the 'after' boundary is specified, we can break early,
|
||||
// because threads are sorted by last message time.
|
||||
if (after is not null && !thread.MayHaveMessagesAfter(after.Value))
|
||||
{
|
||||
containsOlder = true;
|
||||
breakOuter = true;
|
||||
break;
|
||||
}
|
||||
|
||||
yield return thread;
|
||||
|
||||
currentOffset++;
|
||||
}
|
||||
|
||||
if (containsOlder)
|
||||
if (breakOuter)
|
||||
break;
|
||||
|
||||
if (!response.Value.GetProperty("has_more").GetBoolean())
|
||||
|
@ -351,7 +353,7 @@ public class DiscordClient
|
|||
// Archived threads
|
||||
if (includeArchived)
|
||||
{
|
||||
foreach (var channel in filteredChannels)
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
var currentOffset = 0;
|
||||
while (true)
|
||||
|
@ -369,7 +371,7 @@ public class DiscordClient
|
|||
if (response is null)
|
||||
break;
|
||||
|
||||
var containsOlder = false;
|
||||
var breakOuter = false;
|
||||
|
||||
foreach (
|
||||
var threadJson in response.Value.GetProperty("threads").EnumerateArray()
|
||||
|
@ -377,19 +379,19 @@ public class DiscordClient
|
|||
{
|
||||
var thread = Channel.Parse(threadJson, channel);
|
||||
|
||||
// if --after is specified, we can break early, because the threads are sorted by last message time
|
||||
if (after is not null && after > thread.LastMessageId)
|
||||
// If the 'after' boundary is specified, we can break early,
|
||||
// because threads are sorted by last message time.
|
||||
if (after is not null && !thread.MayHaveMessagesAfter(after.Value))
|
||||
{
|
||||
containsOlder = true;
|
||||
breakOuter = true;
|
||||
break;
|
||||
}
|
||||
|
||||
yield return thread;
|
||||
|
||||
currentOffset++;
|
||||
}
|
||||
|
||||
if (containsOlder)
|
||||
if (breakOuter)
|
||||
break;
|
||||
|
||||
if (!response.Value.GetProperty("has_more").GetBoolean())
|
||||
|
@ -403,7 +405,7 @@ public class DiscordClient
|
|||
{
|
||||
// Active threads
|
||||
{
|
||||
var parentsById = filteredChannels.ToDictionary(c => c.Id);
|
||||
var parentsById = channels.ToDictionary(c => c.Id);
|
||||
|
||||
var response = await GetJsonResponseAsync(
|
||||
$"guilds/{guildId}/threads/active",
|
||||
|
@ -425,7 +427,7 @@ public class DiscordClient
|
|||
// Archived threads
|
||||
if (includeArchived)
|
||||
{
|
||||
foreach (var channel in filteredChannels)
|
||||
foreach (var channel in channels)
|
||||
{
|
||||
// Public archived threads
|
||||
{
|
||||
|
|
|
@ -20,14 +20,16 @@ public class ChannelExporter
|
|||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
// Forum channels don't have messages, they are just a list of threads
|
||||
if (request.Channel.Kind == ChannelKind.GuildForum)
|
||||
throw new DiscordChatExporterException("Channel is a forum.");
|
||||
|
||||
// Check if the channel is empty
|
||||
if (request.Channel.LastMessageId is null)
|
||||
{
|
||||
if (request.Channel.IsEmpty)
|
||||
throw new DiscordChatExporterException("Channel does not contain any messages.");
|
||||
}
|
||||
|
||||
// Check if the 'after' boundary is valid
|
||||
if (request.After is not null && request.Channel.LastMessageId < request.After)
|
||||
if (request.After is not null && !request.Channel.MayHaveMessagesAfter(request.After.Value))
|
||||
{
|
||||
throw new DiscordChatExporterException(
|
||||
"Channel does not contain any messages within the specified period."
|
||||
|
@ -35,19 +37,16 @@ public class ChannelExporter
|
|||
}
|
||||
|
||||
// Check if the 'before' boundary is valid
|
||||
if (request.Before is not null && request.Channel.Id > request.Before)
|
||||
if (
|
||||
request.Before is not null
|
||||
&& !request.Channel.MayHaveMessagesBefore(request.Before.Value)
|
||||
)
|
||||
{
|
||||
throw new DiscordChatExporterException(
|
||||
"Channel does not contain any messages within the specified period."
|
||||
);
|
||||
}
|
||||
|
||||
// Skip forum channels, they are exported as threads
|
||||
if (request.Channel.Kind == ChannelKind.GuildForum)
|
||||
{
|
||||
throw new DiscordChatExporterException("Channel is a forum.");
|
||||
}
|
||||
|
||||
// Build context
|
||||
var context = new ExportContext(_discord, request);
|
||||
await context.PopulateChannelsAndRolesAsync(cancellationToken);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue