Short-circuit if trying to export an empty channel or a channel with mismatching boundaries

Closes #1024
pull/1037/head
Tyrrrz 1 year ago
parent faad994332
commit 9048557b17

@ -169,10 +169,10 @@ public abstract class ExportCommandBase : DiscordCommandBase
);
}
// Export
var cancellationToken = console.RegisterCancellationHandler();
var errors = new ConcurrentDictionary<Channel, string>();
// Export
await console.Output.WriteLineAsync($"Exporting {channels.Count} channel(s)...");
await console.CreateProgressTicker().StartAsync(async progressContext =>
{

@ -333,10 +333,9 @@ public class DiscordClient
IProgress<Percentage>? progress = null,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
// Get the last message in the specified range.
// This snapshots the boundaries, which means that messages posted after the export started
// Get the last message in the specified range, so we can later calculate progress based on its date.
// This also snapshots the boundaries, which means that messages posted after the export started
// will not appear in the output.
// Additionally, it provides the date of the last message, which is used to calculate progress.
var lastMessage = await TryGetLastMessageAsync(channelId, before, cancellationToken);
if (lastMessage is null || lastMessage.Timestamp < after?.ToDate())
yield break;

@ -59,4 +59,8 @@ public partial record struct Snowflake : IComparable<Snowflake>, IComparable
return Value.CompareTo(other.Value);
}
public static bool operator >(Snowflake left, Snowflake right) => left.CompareTo(right) > 0;
public static bool operator <(Snowflake left, Snowflake right) => left.CompareTo(right) < 0;
}

@ -18,13 +18,20 @@ public class ChannelExporter
IProgress<Percentage>? progress = null,
CancellationToken cancellationToken = default)
{
// Check if the channel is empty
if (request.Channel.LastMessageId is null)
throw DiscordChatExporterException.ChannelIsEmpty();
// Check if the 'after' boundary is valid
if (request.After is not null && request.Channel.LastMessageId < request.After)
throw DiscordChatExporterException.ChannelIsEmpty();
// Build context
var context = new ExportContext(_discord, request);
await context.PopulateChannelsAndRolesAsync(cancellationToken);
// Export messages
await using var messageExporter = new MessageExporter(context);
await foreach (var message in _discord.GetMessagesAsync(
request.Channel.Id,
request.After,

Loading…
Cancel
Save