mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2026-07-07 14:44:39 +02:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 921f348769 | |||
| a25e809671 | |||
| fa80c82468 | |||
| 91f4f02a35 | |||
| 6d2880ce26 | |||
| 355b8cb8cf | |||
| 82945ac3cf | |||
| 5009b90a3e |
Binary file not shown.
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 27 KiB |
@@ -1,3 +1,9 @@
|
||||
### v2.23 (14-Sep-2020)
|
||||
|
||||
- [CLI] Added a command to export all channels across all servers. Use `exportall` to do it. (Thanks [@wyattscarpenter](https://github.com/wyattscarpenter))
|
||||
- [HTML] Fixed an issue where Whitney fonts were not being loaded properly, causing the browser to fall back to Helvetica.
|
||||
- Fixed an issue where self-contained export crashed occasionally. This usually happened when the server hosting the file did not serve the stream properly. Such files are now ignored after the first failed attempt.
|
||||
|
||||
### v2.22 (12-Aug-2020)
|
||||
|
||||
- [GUI] Improved the channel list by adding collapsible category groups. (Thanks [@CarJem Generations](https://github.com/CarJem))
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using CliFx;
|
||||
using CliFx.Attributes;
|
||||
using DiscordChatExporter.Cli.Commands.Base;
|
||||
using DiscordChatExporter.Domain.Discord.Models;
|
||||
|
||||
namespace DiscordChatExporter.Cli.Commands
|
||||
{
|
||||
[Command("exportall", Description = "Export all accessible channels.")]
|
||||
public class ExportAllCommand : ExportMultipleCommandBase
|
||||
{
|
||||
[CommandOption("include-dm", Description = "Whether to also export direct message channels.")]
|
||||
public bool IncludeDirectMessages { get; set; } = true;
|
||||
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
{
|
||||
var channels = new List<Channel>();
|
||||
|
||||
// Aggregate channels from all guilds
|
||||
await foreach (var guild in GetDiscordClient().GetUserGuildsAsync())
|
||||
{
|
||||
// Skip DMs if instructed to
|
||||
if (!IncludeDirectMessages && guild.Id == Guild.DirectMessages.Id)
|
||||
continue;
|
||||
|
||||
await foreach (var channel in GetDiscordClient().GetGuildChannelsAsync(guild.Id))
|
||||
{
|
||||
channels.Add(channel);
|
||||
}
|
||||
}
|
||||
|
||||
await ExportMultipleAsync(console, channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,8 @@ namespace DiscordChatExporter.Cli.Commands
|
||||
{
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
{
|
||||
var dmChannels = await GetDiscordClient().GetGuildChannelsAsync(Guild.DirectMessages.Id);
|
||||
await ExportMultipleAsync(console, dmChannels);
|
||||
var channels = await GetDiscordClient().GetGuildChannelsAsync(Guild.DirectMessages.Id);
|
||||
await ExportMultipleAsync(console, channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,8 @@ namespace DiscordChatExporter.Cli.Commands
|
||||
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
{
|
||||
var guildChannels = await GetDiscordClient().GetGuildChannelsAsync(GuildId);
|
||||
await ExportMultipleAsync(console, guildChannels);
|
||||
var channels = await GetDiscordClient().GetGuildChannelsAsync(GuildId);
|
||||
await ExportMultipleAsync(console, channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ using DiscordChatExporter.Domain.Utilities;
|
||||
|
||||
namespace DiscordChatExporter.Cli.Commands
|
||||
{
|
||||
[Command("channels", Description = "Get the list of channels in specified guild.")]
|
||||
[Command("channels", Description = "Get the list of channels in a guild.")]
|
||||
public class GetChannelsCommand : TokenCommandBase
|
||||
{
|
||||
[CommandOption("guild", 'g', IsRequired = true, Description = "Guild ID.")]
|
||||
@@ -15,9 +15,9 @@ namespace DiscordChatExporter.Cli.Commands
|
||||
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
{
|
||||
var guildChannels = await GetDiscordClient().GetGuildChannelsAsync(GuildId);
|
||||
var channels = await GetDiscordClient().GetGuildChannelsAsync(GuildId);
|
||||
|
||||
foreach (var channel in guildChannels.OrderBy(c => c.Category).ThenBy(c => c.Name))
|
||||
foreach (var channel in channels.OrderBy(c => c.Category).ThenBy(c => c.Name))
|
||||
console.Output.WriteLine($"{channel.Id} | {channel.Category} / {channel.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace DiscordChatExporter.Cli.Commands
|
||||
{
|
||||
public override async ValueTask ExecuteAsync(IConsole console)
|
||||
{
|
||||
var dmChannels = await GetDiscordClient().GetGuildChannelsAsync(Guild.DirectMessages.Id);
|
||||
var channels = await GetDiscordClient().GetGuildChannelsAsync(Guild.DirectMessages.Id);
|
||||
|
||||
foreach (var channel in dmChannels.OrderBy(c => c.Category).ThenBy(c => c.Name))
|
||||
foreach (var channel in channels.OrderBy(c => c.Category).ThenBy(c => c.Name))
|
||||
console.Output.WriteLine($"{channel.Id} | {channel.Category} / {channel.Name}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace DiscordChatExporter.Domain.Discord.Models
|
||||
|
||||
public DateTimeOffset? EditedTimestamp { get; }
|
||||
|
||||
public DateTimeOffset? CallEndedTimestamp { get; }
|
||||
|
||||
public bool IsPinned { get; }
|
||||
|
||||
public string Content { get; }
|
||||
@@ -51,6 +53,7 @@ namespace DiscordChatExporter.Domain.Discord.Models
|
||||
User author,
|
||||
DateTimeOffset timestamp,
|
||||
DateTimeOffset? editedTimestamp,
|
||||
DateTimeOffset? callEndedTimestamp,
|
||||
bool isPinned,
|
||||
string content,
|
||||
IReadOnlyList<Attachment> attachments,
|
||||
@@ -63,6 +66,7 @@ namespace DiscordChatExporter.Domain.Discord.Models
|
||||
Author = author;
|
||||
Timestamp = timestamp;
|
||||
EditedTimestamp = editedTimestamp;
|
||||
CallEndedTimestamp = callEndedTimestamp;
|
||||
IsPinned = isPinned;
|
||||
Content = content;
|
||||
Attachments = attachments;
|
||||
@@ -82,6 +86,7 @@ namespace DiscordChatExporter.Domain.Discord.Models
|
||||
var author = json.GetProperty("author").Pipe(User.Parse);
|
||||
var timestamp = json.GetProperty("timestamp").GetDateTimeOffset();
|
||||
var editedTimestamp = json.GetPropertyOrNull("edited_timestamp")?.GetDateTimeOffset();
|
||||
var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp")?.GetDateTimeOffset();
|
||||
var type = (MessageType) json.GetProperty("type").GetInt32();
|
||||
var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false;
|
||||
|
||||
@@ -89,7 +94,8 @@ namespace DiscordChatExporter.Domain.Discord.Models
|
||||
{
|
||||
MessageType.RecipientAdd => "Added a recipient.",
|
||||
MessageType.RecipientRemove => "Removed a recipient.",
|
||||
MessageType.Call => "Started a call.",
|
||||
MessageType.Call =>
|
||||
$"Started a call that lasted {callEndedTimestamp?.Pipe(t => t - timestamp).Pipe(t => (int) t.TotalMinutes) ?? 0} minutes.",
|
||||
MessageType.ChannelNameChange => "Changed the channel name.",
|
||||
MessageType.ChannelIconChange => "Changed the channel icon.",
|
||||
MessageType.ChannelPinnedMessage => "Pinned a message.",
|
||||
@@ -119,6 +125,7 @@ namespace DiscordChatExporter.Domain.Discord.Models
|
||||
author,
|
||||
timestamp,
|
||||
editedTimestamp,
|
||||
callEndedTimestamp,
|
||||
isPinned,
|
||||
content,
|
||||
attachments,
|
||||
|
||||
@@ -84,7 +84,10 @@ namespace DiscordChatExporter.Domain.Exporting
|
||||
|
||||
return relativeFilePath;
|
||||
}
|
||||
catch (HttpRequestException)
|
||||
// Try to catch only exceptions related to failed HTTP requests
|
||||
// https://github.com/Tyrrrz/DiscordChatExporter/issues/332
|
||||
// https://github.com/Tyrrrz/DiscordChatExporter/issues/372
|
||||
catch (Exception ex) when (ex is HttpRequestException || ex is OperationCanceledException)
|
||||
{
|
||||
// We don't want this to crash the exporting process in case of failure
|
||||
return url;
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
|
||||
@font-face {
|
||||
font-family: Whitney;
|
||||
src: url(https://discord.com/assets/6c6374bad0b0b6d204d8d6dc4a18d820.woff);
|
||||
src: url(https://cdn.jsdelivr.net/gh/Tyrrrz/DiscordFonts@master/whitney-300.woff);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Whitney;
|
||||
src: url(https://discord.com/assets/e8acd7d9bf6207f99350ca9f9e23b168.woff);
|
||||
src: url(https://cdn.jsdelivr.net/gh/Tyrrrz/DiscordFonts@master/whitney-400.woff);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Whitney;
|
||||
src: url(https://discord.com/assets/3bdef1251a424500c1b3a78dea9b7e57.woff);
|
||||
src: url(https://cdn.jsdelivr.net/gh/Tyrrrz/DiscordFonts@master/whitney-500.woff);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Whitney;
|
||||
src: url(https://discord.com/assets/be0060dafb7a0e31d2a1ca17c0708636.woff);
|
||||
src: url(https://cdn.jsdelivr.net/gh/Tyrrrz/DiscordFonts@master/whitney-600.woff);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Whitney;
|
||||
src: url(https://discord.com/assets/8e12fb4f14d9c4592eb8ec9f22337b04.woff);
|
||||
src: url(https://cdn.jsdelivr.net/gh/Tyrrrz/DiscordFonts@master/whitney-700.woff);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
||||
@@ -197,6 +197,7 @@ namespace DiscordChatExporter.Domain.Exporting.Writers
|
||||
_writer.WriteString("type", message.Type.ToString());
|
||||
_writer.WriteString("timestamp", message.Timestamp);
|
||||
_writer.WriteString("timestampEdited", message.EditedTimestamp);
|
||||
_writer.WriteString("callEndedTimestamp", message.CallEndedTimestamp);
|
||||
_writer.WriteBoolean("isPinned", message.IsPinned);
|
||||
|
||||
// Content
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<Version>2.22</Version>
|
||||
<Version>2.23</Version>
|
||||
<Company>Tyrrrz</Company>
|
||||
<Copyright>Copyright (c) Alexey Golub</Copyright>
|
||||
<LangVersion>latest</LangVersion>
|
||||
|
||||
Reference in New Issue
Block a user