mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-25 20:24:22 -04:00
Refactor
This commit is contained in:
parent
af11064a85
commit
ea31b1b270
19 changed files with 67 additions and 98 deletions
|
@ -40,12 +40,10 @@ namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
|
||||||
Snowflake.Parse("867886632203976775")
|
Snowflake.Parse("867886632203976775")
|
||||||
);
|
);
|
||||||
|
|
||||||
var iframe = message.QuerySelector("iframe");
|
var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
iframe.Should().NotBeNull();
|
iframeSrc.Should().StartWithEquivalentOf("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP");
|
||||||
iframe?.GetAttribute("src").Should()
|
|
||||||
.StartWithEquivalentOf("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -57,12 +55,10 @@ namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting
|
||||||
Snowflake.Parse("866472508588294165")
|
Snowflake.Parse("866472508588294165")
|
||||||
);
|
);
|
||||||
|
|
||||||
var iframe = message.QuerySelector("iframe");
|
var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
iframe.Should().NotBeNull();
|
iframeSrc.Should().StartWithEquivalentOf("https://www.youtube.com/embed/qOWW4OlgbvE");
|
||||||
iframe?.GetAttribute("src").Should()
|
|
||||||
.StartWithEquivalentOf("https://www.youtube.com/embed/qOWW4OlgbvE");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -54,18 +54,21 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
||||||
private ChannelExporter? _channelExporter;
|
private ChannelExporter? _channelExporter;
|
||||||
protected ChannelExporter Exporter => _channelExporter ??= new ChannelExporter(Discord);
|
protected ChannelExporter Exporter => _channelExporter ??= new ChannelExporter(Discord);
|
||||||
|
|
||||||
protected async ValueTask ExportAsync(IConsole console, IReadOnlyList<Channel> channels)
|
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Channel> channels)
|
||||||
{
|
{
|
||||||
await console.Output.WriteLineAsync($"Exporting {channels.Count} channel(s)...");
|
if (ShouldReuseMedia && !ShouldDownloadMedia)
|
||||||
|
{
|
||||||
|
throw new CommandException("Option --reuse-media cannot be used without --media.");
|
||||||
|
}
|
||||||
|
|
||||||
var errors = new ConcurrentDictionary<Channel, string>();
|
var errors = new ConcurrentDictionary<Channel, string>();
|
||||||
|
|
||||||
// Wrap everything in a progress ticker
|
// Export
|
||||||
|
await console.Output.WriteLineAsync($"Exporting {channels.Count} channel(s)...");
|
||||||
await console.CreateProgressTicker().StartAsync(async progressContext =>
|
await console.CreateProgressTicker().StartAsync(async progressContext =>
|
||||||
{
|
{
|
||||||
await channels.ParallelForEachAsync(async channel =>
|
await channels.ParallelForEachAsync(async channel =>
|
||||||
{
|
{
|
||||||
// Export
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await progressContext.StartTaskAsync($"{channel.Category} / {channel.Name}", async progress =>
|
await progressContext.StartTaskAsync($"{channel.Category} / {channel.Name}", async progress =>
|
||||||
|
@ -89,7 +92,7 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
||||||
await Exporter.ExportChannelAsync(request, progress);
|
await Exporter.ExportChannelAsync(request, progress);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
catch (DiscordChatExporterException ex) when (!ex.IsFatal)
|
||||||
{
|
{
|
||||||
errors[channel] = ex.Message;
|
errors[channel] = ex.Message;
|
||||||
}
|
}
|
||||||
|
@ -127,22 +130,25 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
||||||
await console.Output.WriteLineAsync();
|
await console.Output.WriteLineAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fail the command if ALL channels failed to export.
|
// Fail the command only if ALL channels failed to export.
|
||||||
// Having some of the channels fail to export is fine and expected.
|
// Having some of the channels fail to export is expected.
|
||||||
if (errors.Count >= channels.Count)
|
if (errors.Count >= channels.Count)
|
||||||
{
|
{
|
||||||
throw new CommandException("Export failed.");
|
throw new CommandException("Export failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ValueTask ExecuteAsync(IConsole console)
|
protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList<Snowflake> channelIds)
|
||||||
{
|
{
|
||||||
if (ShouldReuseMedia && !ShouldDownloadMedia)
|
var channels = new List<Channel>();
|
||||||
|
|
||||||
|
foreach (var channelId in channelIds)
|
||||||
{
|
{
|
||||||
throw new CommandException("Option --reuse-media cannot be used without --media.");
|
var channel = await Discord.GetChannelAsync(channelId);
|
||||||
|
channels.Add(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return default;
|
await ExecuteAsync(console, channels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,8 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
||||||
[CommandOption("bot", 'b', EnvironmentVariable = "DISCORD_TOKEN_BOT", Description = "Authenticate as a bot.")]
|
[CommandOption("bot", 'b', EnvironmentVariable = "DISCORD_TOKEN_BOT", Description = "Authenticate as a bot.")]
|
||||||
public bool IsBotToken { get; init; }
|
public bool IsBotToken { get; init; }
|
||||||
|
|
||||||
private AuthToken GetAuthToken() => new(
|
private AuthToken? _authToken;
|
||||||
|
private AuthToken AuthToken => _authToken ??= new AuthToken(
|
||||||
IsBotToken
|
IsBotToken
|
||||||
? AuthTokenKind.Bot
|
? AuthTokenKind.Bot
|
||||||
: AuthTokenKind.User,
|
: AuthTokenKind.User,
|
||||||
|
@ -22,7 +23,7 @@ namespace DiscordChatExporter.Cli.Commands.Base
|
||||||
);
|
);
|
||||||
|
|
||||||
private DiscordClient? _discordClient;
|
private DiscordClient? _discordClient;
|
||||||
protected DiscordClient Discord => _discordClient ??= new DiscordClient(GetAuthToken());
|
protected DiscordClient Discord => _discordClient ??= new DiscordClient(AuthToken);
|
||||||
|
|
||||||
public abstract ValueTask ExecuteAsync(IConsole console);
|
public abstract ValueTask ExecuteAsync(IConsole console);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,9 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
|
|
||||||
public override async ValueTask ExecuteAsync(IConsole console)
|
public override async ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
await base.ExecuteAsync(console);
|
|
||||||
|
|
||||||
// Get channel metadata
|
|
||||||
await console.Output.WriteLineAsync("Fetching channels...");
|
|
||||||
|
|
||||||
var channels = new List<Channel>();
|
var channels = new List<Channel>();
|
||||||
|
|
||||||
// Aggregate channels from all guilds
|
await console.Output.WriteLineAsync("Fetching channels...");
|
||||||
await foreach (var guild in Discord.GetUserGuildsAsync())
|
await foreach (var guild in Discord.GetUserGuildsAsync())
|
||||||
{
|
{
|
||||||
// Skip DMs if instructed to
|
// Skip DMs if instructed to
|
||||||
|
@ -39,8 +34,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export
|
await base.ExecuteAsync(console, channels);
|
||||||
await ExportAsync(console, channels);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,6 @@ using CliFx.Attributes;
|
||||||
using CliFx.Infrastructure;
|
using CliFx.Infrastructure;
|
||||||
using DiscordChatExporter.Cli.Commands.Base;
|
using DiscordChatExporter.Cli.Commands.Base;
|
||||||
using DiscordChatExporter.Core.Discord;
|
using DiscordChatExporter.Core.Discord;
|
||||||
using DiscordChatExporter.Core.Discord.Data;
|
|
||||||
|
|
||||||
namespace DiscordChatExporter.Cli.Commands
|
namespace DiscordChatExporter.Cli.Commands
|
||||||
{
|
{
|
||||||
|
@ -16,23 +15,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
[CommandOption("channel", 'c', IsRequired = true, Description = "Channel ID(s).")]
|
[CommandOption("channel", 'c', IsRequired = true, Description = "Channel ID(s).")]
|
||||||
public IReadOnlyList<Snowflake> ChannelIds { get; init; } = Array.Empty<Snowflake>();
|
public IReadOnlyList<Snowflake> ChannelIds { get; init; } = Array.Empty<Snowflake>();
|
||||||
|
|
||||||
public override async ValueTask ExecuteAsync(IConsole console)
|
public override async ValueTask ExecuteAsync(IConsole console) =>
|
||||||
{
|
await base.ExecuteAsync(console, ChannelIds);
|
||||||
await base.ExecuteAsync(console);
|
|
||||||
|
|
||||||
// Get channel metadata
|
|
||||||
await console.Output.WriteLineAsync("Fetching channel(s)...");
|
|
||||||
|
|
||||||
var channels = new List<Channel>();
|
|
||||||
|
|
||||||
foreach (var channelId in ChannelIds)
|
|
||||||
{
|
|
||||||
var channel = await Discord.GetChannelAsync(channelId);
|
|
||||||
channels.Add(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export
|
|
||||||
await ExportAsync(console, channels);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,15 +13,11 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
{
|
{
|
||||||
public override async ValueTask ExecuteAsync(IConsole console)
|
public override async ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
await base.ExecuteAsync(console);
|
|
||||||
|
|
||||||
// Get channel metadata
|
|
||||||
await console.Output.WriteLineAsync("Fetching channels...");
|
await console.Output.WriteLineAsync("Fetching channels...");
|
||||||
var channels = await Discord.GetGuildChannelsAsync(Guild.DirectMessages.Id);
|
var channels = await Discord.GetGuildChannelsAsync(Guild.DirectMessages.Id);
|
||||||
var textChannels = channels.Where(c => c.IsTextChannel).ToArray();
|
var textChannels = channels.Where(c => c.IsTextChannel).ToArray();
|
||||||
|
|
||||||
// Export
|
await base.ExecuteAsync(console, textChannels);
|
||||||
await ExportAsync(console, textChannels);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,15 +16,11 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
|
|
||||||
public override async ValueTask ExecuteAsync(IConsole console)
|
public override async ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
await base.ExecuteAsync(console);
|
|
||||||
|
|
||||||
// Get channel metadata
|
|
||||||
await console.Output.WriteLineAsync("Fetching channels...");
|
await console.Output.WriteLineAsync("Fetching channels...");
|
||||||
var channels = await Discord.GetGuildChannelsAsync(GuildId);
|
var channels = await Discord.GetGuildChannelsAsync(GuildId);
|
||||||
var textChannels = channels.Where(c => c.IsTextChannel).ToArray();
|
var textChannels = channels.Where(c => c.IsTextChannel).ToArray();
|
||||||
|
|
||||||
// Export
|
await base.ExecuteAsync(console, textChannels);
|
||||||
await ExportAsync(console, textChannels);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,9 +36,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
|
|
||||||
// Channel category / name
|
// Channel category / name
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
await console.Output.WriteAsync($"{channel.Category} / {channel.Name}");
|
await console.Output.WriteLineAsync($"{channel.Category} / {channel.Name}");
|
||||||
|
|
||||||
await console.Output.WriteLineAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
|
|
||||||
// Channel category / name
|
// Channel category / name
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
await console.Output.WriteAsync($"{channel.Category} / {channel.Name}");
|
await console.Output.WriteLineAsync($"{channel.Category} / {channel.Name}");
|
||||||
|
|
||||||
await console.Output.WriteLineAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
|
|
||||||
// Guild name
|
// Guild name
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
await console.Output.WriteAsync(guild.Name);
|
await console.Output.WriteLineAsync(guild.Name);
|
||||||
|
|
||||||
await console.Output.WriteLineAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
{
|
{
|
||||||
public ValueTask ExecuteAsync(IConsole console)
|
public ValueTask ExecuteAsync(IConsole console)
|
||||||
{
|
{
|
||||||
|
// User token
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
console.Output.WriteLine("To get user token:");
|
console.Output.WriteLine("To get user token:");
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
console.Output.WriteLine(" * Automating user accounts is technically against TOS, use at your own risk.");
|
console.Output.WriteLine(" * Automating user accounts is technically against TOS, use at your own risk.");
|
||||||
console.Output.WriteLine();
|
console.Output.WriteLine();
|
||||||
|
|
||||||
|
// Bot token
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
console.Output.WriteLine("To get bot token:");
|
console.Output.WriteLine("To get bot token:");
|
||||||
|
|
||||||
|
@ -34,6 +36,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
console.Output.WriteLine(" 4. Under Token click Copy");
|
console.Output.WriteLine(" 4. Under Token click Copy");
|
||||||
console.Output.WriteLine();
|
console.Output.WriteLine();
|
||||||
|
|
||||||
|
// Guild or channel ID
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
console.Output.WriteLine("To get guild ID or guild channel ID:");
|
console.Output.WriteLine("To get guild ID or guild channel ID:");
|
||||||
|
|
||||||
|
@ -44,6 +47,7 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
console.Output.WriteLine(" 5. Right click on the desired guild or channel and click Copy ID");
|
console.Output.WriteLine(" 5. Right click on the desired guild or channel and click Copy ID");
|
||||||
console.Output.WriteLine();
|
console.Output.WriteLine();
|
||||||
|
|
||||||
|
// Direct message channel ID
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
console.Output.WriteLine("To get direct message channel ID:");
|
console.Output.WriteLine("To get direct message channel ID:");
|
||||||
|
|
||||||
|
@ -55,9 +59,9 @@ namespace DiscordChatExporter.Cli.Commands
|
||||||
console.Output.WriteLine(" 6. Copy the first long sequence of numbers inside the URL");
|
console.Output.WriteLine(" 6. Copy the first long sequence of numbers inside the URL");
|
||||||
console.Output.WriteLine();
|
console.Output.WriteLine();
|
||||||
|
|
||||||
|
// Wiki link
|
||||||
using (console.WithForegroundColor(ConsoleColor.White))
|
using (console.WithForegroundColor(ConsoleColor.White))
|
||||||
console.Output.WriteLine("For more information, check out the wiki:");
|
console.Output.WriteLine("For more information, check out the wiki:");
|
||||||
|
|
||||||
using (console.WithForegroundColor(ConsoleColor.DarkCyan))
|
using (console.WithForegroundColor(ConsoleColor.DarkCyan))
|
||||||
console.Output.WriteLine("https://github.com/Tyrrrz/DiscordChatExporter/wiki");
|
console.Output.WriteLine("https://github.com/Tyrrrz/DiscordChatExporter/wiki");
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ namespace DiscordChatExporter.Core.Discord.Data
|
||||||
|
|
||||||
public partial class ChannelCategory
|
public partial class ChannelCategory
|
||||||
{
|
{
|
||||||
|
public static ChannelCategory Unknown { get; } = new(Snowflake.Zero, "<unknown category>", 0);
|
||||||
|
|
||||||
public static ChannelCategory Parse(JsonElement json, int? position = null)
|
public static ChannelCategory Parse(JsonElement json, int? position = null)
|
||||||
{
|
{
|
||||||
var id = json.GetProperty("id").GetString().Pipe(Snowflake.Parse);
|
var id = json.GetProperty("id").GetString().Pipe(Snowflake.Parse);
|
||||||
|
@ -41,7 +43,5 @@ namespace DiscordChatExporter.Core.Discord.Data
|
||||||
position ?? json.GetPropertyOrNull("position")?.GetInt32()
|
position ?? json.GetPropertyOrNull("position")?.GetInt32()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChannelCategory Empty { get; } = new(Snowflake.Zero, "<unknown category>", 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,20 +10,6 @@ using JsonExtensions.Reading;
|
||||||
|
|
||||||
namespace DiscordChatExporter.Core.Discord.Data
|
namespace DiscordChatExporter.Core.Discord.Data
|
||||||
{
|
{
|
||||||
// https://discord.com/developers/docs/resources/channel#message-object-message-types
|
|
||||||
public enum MessageKind
|
|
||||||
{
|
|
||||||
Default = 0,
|
|
||||||
RecipientAdd = 1,
|
|
||||||
RecipientRemove = 2,
|
|
||||||
Call = 3,
|
|
||||||
ChannelNameChange = 4,
|
|
||||||
ChannelIconChange = 5,
|
|
||||||
ChannelPinnedMessage = 6,
|
|
||||||
GuildMemberJoin = 7,
|
|
||||||
Reply = 19
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://discord.com/developers/docs/resources/channel#message-object
|
// https://discord.com/developers/docs/resources/channel#message-object
|
||||||
public partial class Message : IHasId
|
public partial class Message : IHasId
|
||||||
{
|
{
|
||||||
|
|
16
DiscordChatExporter.Core/Discord/Data/MessageKind.cs
Normal file
16
DiscordChatExporter.Core/Discord/Data/MessageKind.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
namespace DiscordChatExporter.Core.Discord.Data
|
||||||
|
{
|
||||||
|
// https://discord.com/developers/docs/resources/channel#message-object-message-types
|
||||||
|
public enum MessageKind
|
||||||
|
{
|
||||||
|
Default = 0,
|
||||||
|
RecipientAdd = 1,
|
||||||
|
RecipientRemove = 2,
|
||||||
|
Call = 3,
|
||||||
|
ChannelNameChange = 4,
|
||||||
|
ChannelIconChange = 5,
|
||||||
|
ChannelPinnedMessage = 6,
|
||||||
|
GuildMemberJoin = 7,
|
||||||
|
Reply = 19
|
||||||
|
}
|
||||||
|
}
|
|
@ -160,13 +160,13 @@ namespace DiscordChatExporter.Core.Discord
|
||||||
yield return Role.Parse(roleJson);
|
yield return Role.Parse(roleJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<Member?> TryGetGuildMemberAsync(Snowflake guildId, User user)
|
public async ValueTask<Member> GetGuildMemberAsync(Snowflake guildId, User user)
|
||||||
{
|
{
|
||||||
if (guildId == Guild.DirectMessages.Id)
|
if (guildId == Guild.DirectMessages.Id)
|
||||||
return Member.CreateForUser(user);
|
return Member.CreateForUser(user);
|
||||||
|
|
||||||
var response = await TryGetJsonResponseAsync($"guilds/{guildId}/members/{user.Id}");
|
var response = await TryGetJsonResponseAsync($"guilds/{guildId}/members/{user.Id}");
|
||||||
return response?.Pipe(Member.Parse);
|
return response?.Pipe(Member.Parse) ?? Member.CreateForUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<ChannelCategory> GetChannelCategoryAsync(Snowflake channelId)
|
public async ValueTask<ChannelCategory> GetChannelCategoryAsync(Snowflake channelId)
|
||||||
|
@ -180,7 +180,7 @@ namespace DiscordChatExporter.Core.Discord
|
||||||
// Instead, we use an empty channel category as a fallback.
|
// Instead, we use an empty channel category as a fallback.
|
||||||
catch (DiscordChatExporterException)
|
catch (DiscordChatExporterException)
|
||||||
{
|
{
|
||||||
return ChannelCategory.Empty;
|
return ChannelCategory.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ namespace DiscordChatExporter.Core.Exceptions
|
||||||
{
|
{
|
||||||
public partial class DiscordChatExporterException : Exception
|
public partial class DiscordChatExporterException : Exception
|
||||||
{
|
{
|
||||||
public bool IsCritical { get; }
|
public bool IsFatal { get; }
|
||||||
|
|
||||||
public DiscordChatExporterException(string message, bool isCritical = false)
|
public DiscordChatExporterException(string message, bool isFatal = false)
|
||||||
: base(message)
|
: base(message)
|
||||||
{
|
{
|
||||||
IsCritical = isCritical;
|
IsFatal = isFatal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ Failed to perform an HTTP request.
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static DiscordChatExporterException Unauthorized() =>
|
internal static DiscordChatExporterException Unauthorized() =>
|
||||||
new("Authentication token is invalid.");
|
new("Authentication token is invalid.", true);
|
||||||
|
|
||||||
internal static DiscordChatExporterException Forbidden() =>
|
internal static DiscordChatExporterException Forbidden() =>
|
||||||
new("Access is forbidden.");
|
new("Access is forbidden.");
|
||||||
|
|
|
@ -49,10 +49,7 @@ namespace DiscordChatExporter.Core.Exporting
|
||||||
if (!encounteredUsers.Add(referencedUser))
|
if (!encounteredUsers.Add(referencedUser))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var member =
|
var member = await _discord.GetGuildMemberAsync(request.Guild.Id, referencedUser);
|
||||||
await _discord.TryGetGuildMemberAsync(request.Guild.Id, referencedUser) ??
|
|
||||||
Member.CreateForUser(referencedUser);
|
|
||||||
|
|
||||||
contextMembers.Add(member);
|
contextMembers.Add(member);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace DiscordChatExporter.Core.Exporting
|
||||||
|
|
||||||
private async ValueTask<MessageWriter> GetWriterAsync()
|
private async ValueTask<MessageWriter> GetWriterAsync()
|
||||||
{
|
{
|
||||||
// Ensure partition limit has not been exceeded
|
// Ensure partition limit has not been reached
|
||||||
if (_writer is not null &&
|
if (_writer is not null &&
|
||||||
_context.Request.PartitionLimit.IsReached(_writer.MessagesWritten, _writer.BytesWritten))
|
_context.Request.PartitionLimit.IsReached(_writer.MessagesWritten, _writer.BytesWritten))
|
||||||
{
|
{
|
||||||
|
|
|
@ -175,7 +175,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
||||||
GuildChannelMap = guildChannelMap;
|
GuildChannelMap = guildChannelMap;
|
||||||
SelectedGuild = guildChannelMap.Keys.FirstOrDefault();
|
SelectedGuild = guildChannelMap.Keys.FirstOrDefault();
|
||||||
}
|
}
|
||||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
catch (DiscordChatExporterException ex) when (!ex.IsFatal)
|
||||||
{
|
{
|
||||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ namespace DiscordChatExporter.Gui.ViewModels
|
||||||
|
|
||||||
Interlocked.Increment(ref successfulExportCount);
|
Interlocked.Increment(ref successfulExportCount);
|
||||||
}
|
}
|
||||||
catch (DiscordChatExporterException ex) when (!ex.IsCritical)
|
catch (DiscordChatExporterException ex) when (!ex.IsFatal)
|
||||||
{
|
{
|
||||||
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
Notifications.Enqueue(ex.Message.TrimEnd('.'));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue