mirror of
https://github.com/Tyrrrz/DiscordChatExporter.git
synced 2025-05-28 21:54:11 -04:00
Use snowflakes in more places
This commit is contained in:
parent
2467caac9f
commit
d51d0d4872
7 changed files with 36 additions and 33 deletions
|
@ -10,14 +10,14 @@ namespace DiscordChatExporter.Core.Discord.Data;
|
||||||
// https://discord.com/developers/docs/resources/emoji#emoji-object
|
// https://discord.com/developers/docs/resources/emoji#emoji-object
|
||||||
public partial record Emoji(
|
public partial record Emoji(
|
||||||
// Only present on custom emoji
|
// Only present on custom emoji
|
||||||
string? Id,
|
Snowflake? Id,
|
||||||
// Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂)
|
// Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂)
|
||||||
string Name,
|
string Name,
|
||||||
bool IsAnimated,
|
bool IsAnimated,
|
||||||
string ImageUrl)
|
string ImageUrl)
|
||||||
{
|
{
|
||||||
// Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile)
|
// Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile)
|
||||||
public string Code => !string.IsNullOrWhiteSpace(Id)
|
public string Code => Id is not null
|
||||||
? Name
|
? Name
|
||||||
: EmojiIndex.TryGetCode(Name) ?? Name;
|
: EmojiIndex.TryGetCode(Name) ?? Name;
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,18 @@ public partial record Emoji
|
||||||
.Select(r => r.Value.ToString("x"))
|
.Select(r => r.Value.ToString("x"))
|
||||||
);
|
);
|
||||||
|
|
||||||
private static string GetImageUrl(string id, bool isAnimated) => isAnimated
|
private static string GetImageUrl(Snowflake id, bool isAnimated) => isAnimated
|
||||||
? $"https://cdn.discordapp.com/emojis/{id}.gif"
|
? $"https://cdn.discordapp.com/emojis/{id}.gif"
|
||||||
: $"https://cdn.discordapp.com/emojis/{id}.png";
|
: $"https://cdn.discordapp.com/emojis/{id}.png";
|
||||||
|
|
||||||
private static string GetImageUrl(string name) =>
|
private static string GetImageUrl(string name) =>
|
||||||
$"https://twemoji.maxcdn.com/2/svg/{GetTwemojiName(name)}.svg";
|
$"https://twemoji.maxcdn.com/2/svg/{GetTwemojiName(name)}.svg";
|
||||||
|
|
||||||
public static string GetImageUrl(string? id, string? name, bool isAnimated)
|
public static string GetImageUrl(Snowflake? id, string? name, bool isAnimated)
|
||||||
{
|
{
|
||||||
// Custom emoji
|
// Custom emoji
|
||||||
if (!string.IsNullOrWhiteSpace(id))
|
if (id is not null)
|
||||||
return GetImageUrl(id, isAnimated);
|
return GetImageUrl(id.Value, isAnimated);
|
||||||
|
|
||||||
// Standard emoji
|
// Standard emoji
|
||||||
if (!string.IsNullOrWhiteSpace(name))
|
if (!string.IsNullOrWhiteSpace(name))
|
||||||
|
@ -55,7 +55,7 @@ public partial record Emoji
|
||||||
|
|
||||||
public static Emoji Parse(JsonElement json)
|
public static Emoji Parse(JsonElement json)
|
||||||
{
|
{
|
||||||
var id = json.GetPropertyOrNull("id")?.GetNonWhiteSpaceStringOrNull();
|
var id = json.GetPropertyOrNull("id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
|
||||||
var name = json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull();
|
var name = json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull();
|
||||||
var isAnimated = json.GetPropertyOrNull("animated")?.GetBooleanOrNull() ?? false;
|
var isAnimated = json.GetPropertyOrNull("animated")?.GetBooleanOrNull() ?? false;
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ internal class JsonMessageWriter : MessageWriter
|
||||||
|
|
||||||
// Emoji
|
// Emoji
|
||||||
_writer.WriteStartObject("emoji");
|
_writer.WriteStartObject("emoji");
|
||||||
_writer.WriteString("id", reaction.Emoji.Id);
|
_writer.WriteString("id", reaction.Emoji.Id.ToString());
|
||||||
_writer.WriteString("name", reaction.Emoji.Name);
|
_writer.WriteString("name", reaction.Emoji.Name);
|
||||||
_writer.WriteBoolean("isAnimated", reaction.Emoji.IsAnimated);
|
_writer.WriteBoolean("isAnimated", reaction.Emoji.IsAnimated);
|
||||||
_writer.WriteString("imageUrl", await Context.ResolveMediaUrlAsync(reaction.Emoji.ImageUrl, cancellationToken));
|
_writer.WriteString("imageUrl", await Context.ResolveMediaUrlAsync(reaction.Emoji.ImageUrl, cancellationToken));
|
||||||
|
|
|
@ -3,7 +3,6 @@ using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using DiscordChatExporter.Core.Discord;
|
|
||||||
using DiscordChatExporter.Core.Discord.Data;
|
using DiscordChatExporter.Core.Discord.Data;
|
||||||
using DiscordChatExporter.Core.Markdown;
|
using DiscordChatExporter.Core.Markdown;
|
||||||
using DiscordChatExporter.Core.Markdown.Parsing;
|
using DiscordChatExporter.Core.Markdown.Parsing;
|
||||||
|
@ -108,17 +107,16 @@ internal partial class HtmlMarkdownVisitor : MarkdownVisitor
|
||||||
|
|
||||||
protected override MarkdownNode VisitMention(MentionNode mention)
|
protected override MarkdownNode VisitMention(MentionNode mention)
|
||||||
{
|
{
|
||||||
var mentionId = Snowflake.TryParse(mention.Id);
|
|
||||||
if (mention.Kind == MentionKind.Meta)
|
if (mention.Kind == MentionKind.Meta)
|
||||||
{
|
{
|
||||||
_buffer
|
_buffer
|
||||||
.Append("<span class=\"mention\">")
|
.Append("<span class=\"mention\">")
|
||||||
.Append("@").Append(HtmlEncode(mention.Id))
|
.Append("@").Append(HtmlEncode(mention.Id.ToString()))
|
||||||
.Append("</span>");
|
.Append("</span>");
|
||||||
}
|
}
|
||||||
else if (mention.Kind == MentionKind.User)
|
else if (mention.Kind == MentionKind.User)
|
||||||
{
|
{
|
||||||
var member = mentionId?.Pipe(_context.TryGetMember);
|
var member = _context.TryGetMember(mention.Id);
|
||||||
var fullName = member?.User.FullName ?? "Unknown";
|
var fullName = member?.User.FullName ?? "Unknown";
|
||||||
var nick = member?.Nick ?? "Unknown";
|
var nick = member?.Nick ?? "Unknown";
|
||||||
|
|
||||||
|
@ -129,7 +127,7 @@ internal partial class HtmlMarkdownVisitor : MarkdownVisitor
|
||||||
}
|
}
|
||||||
else if (mention.Kind == MentionKind.Channel)
|
else if (mention.Kind == MentionKind.Channel)
|
||||||
{
|
{
|
||||||
var channel = mentionId?.Pipe(_context.TryGetChannel);
|
var channel = _context.TryGetChannel(mention.Id);
|
||||||
var symbol = channel?.IsVoiceChannel == true ? "🔊" : "#";
|
var symbol = channel?.IsVoiceChannel == true ? "🔊" : "#";
|
||||||
var name = channel?.Name ?? "deleted-channel";
|
var name = channel?.Name ?? "deleted-channel";
|
||||||
|
|
||||||
|
@ -140,7 +138,7 @@ internal partial class HtmlMarkdownVisitor : MarkdownVisitor
|
||||||
}
|
}
|
||||||
else if (mention.Kind == MentionKind.Role)
|
else if (mention.Kind == MentionKind.Role)
|
||||||
{
|
{
|
||||||
var role = mentionId?.Pipe(_context.TryGetRole);
|
var role = _context.TryGetRole(mention.Id);
|
||||||
var name = role?.Name ?? "deleted-role";
|
var name = role?.Name ?? "deleted-role";
|
||||||
var color = role?.Color;
|
var color = role?.Color;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DiscordChatExporter.Core.Discord;
|
|
||||||
using DiscordChatExporter.Core.Markdown;
|
using DiscordChatExporter.Core.Markdown;
|
||||||
using DiscordChatExporter.Core.Markdown.Parsing;
|
using DiscordChatExporter.Core.Markdown.Parsing;
|
||||||
using DiscordChatExporter.Core.Utils.Extensions;
|
|
||||||
|
|
||||||
namespace DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors;
|
namespace DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors;
|
||||||
|
|
||||||
|
@ -36,21 +34,20 @@ internal partial class PlainTextMarkdownVisitor : MarkdownVisitor
|
||||||
|
|
||||||
protected override MarkdownNode VisitMention(MentionNode mention)
|
protected override MarkdownNode VisitMention(MentionNode mention)
|
||||||
{
|
{
|
||||||
var mentionId = Snowflake.TryParse(mention.Id);
|
|
||||||
if (mention.Kind == MentionKind.Meta)
|
if (mention.Kind == MentionKind.Meta)
|
||||||
{
|
{
|
||||||
_buffer.Append($"@{mention.Id}");
|
_buffer.Append($"@{mention.Id}");
|
||||||
}
|
}
|
||||||
else if (mention.Kind == MentionKind.User)
|
else if (mention.Kind == MentionKind.User)
|
||||||
{
|
{
|
||||||
var member = mentionId?.Pipe(_context.TryGetMember);
|
var member = _context.TryGetMember(mention.Id);
|
||||||
var name = member?.User.Name ?? "Unknown";
|
var name = member?.User.Name ?? "Unknown";
|
||||||
|
|
||||||
_buffer.Append($"@{name}");
|
_buffer.Append($"@{name}");
|
||||||
}
|
}
|
||||||
else if (mention.Kind == MentionKind.Channel)
|
else if (mention.Kind == MentionKind.Channel)
|
||||||
{
|
{
|
||||||
var channel = mentionId?.Pipe(_context.TryGetChannel);
|
var channel = _context.TryGetChannel(mention.Id);
|
||||||
var name = channel?.Name ?? "deleted-channel";
|
var name = channel?.Name ?? "deleted-channel";
|
||||||
|
|
||||||
_buffer.Append($"#{name}");
|
_buffer.Append($"#{name}");
|
||||||
|
@ -61,7 +58,7 @@ internal partial class PlainTextMarkdownVisitor : MarkdownVisitor
|
||||||
}
|
}
|
||||||
else if (mention.Kind == MentionKind.Role)
|
else if (mention.Kind == MentionKind.Role)
|
||||||
{
|
{
|
||||||
var role = mentionId?.Pipe(_context.TryGetRole);
|
var role = _context.TryGetRole(mention.Id);
|
||||||
var name = role?.Name ?? "deleted-role";
|
var name = role?.Name ?? "deleted-role";
|
||||||
|
|
||||||
_buffer.Append($"@{name}");
|
_buffer.Append($"@{name}");
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
using DiscordChatExporter.Core.Utils;
|
using DiscordChatExporter.Core.Discord;
|
||||||
|
using DiscordChatExporter.Core.Utils;
|
||||||
|
|
||||||
namespace DiscordChatExporter.Core.Markdown;
|
namespace DiscordChatExporter.Core.Markdown;
|
||||||
|
|
||||||
internal record EmojiNode(
|
internal record EmojiNode(
|
||||||
// Only present on custom emoji
|
// Only present on custom emoji
|
||||||
string? Id,
|
Snowflake? Id,
|
||||||
// Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂)
|
// Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂)
|
||||||
string Name,
|
string Name,
|
||||||
bool IsAnimated) : MarkdownNode
|
bool IsAnimated) : MarkdownNode
|
||||||
{
|
{
|
||||||
|
public bool IsCustomEmoji => Id is not null;
|
||||||
|
|
||||||
// Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile)
|
// Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile)
|
||||||
public string Code => !string.IsNullOrWhiteSpace(Id)
|
public string Code => IsCustomEmoji
|
||||||
? Name
|
? Name
|
||||||
: EmojiIndex.TryGetCode(Name) ?? Name;
|
: EmojiIndex.TryGetCode(Name) ?? Name;
|
||||||
|
|
||||||
public bool IsCustomEmoji => !string.IsNullOrWhiteSpace(Id);
|
|
||||||
|
|
||||||
public EmojiNode(string name)
|
public EmojiNode(string name)
|
||||||
: this(null, name, false)
|
: this(null, name, false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
namespace DiscordChatExporter.Core.Markdown;
|
using DiscordChatExporter.Core.Discord;
|
||||||
|
|
||||||
internal record MentionNode(string Id, MentionKind Kind) : MarkdownNode;
|
namespace DiscordChatExporter.Core.Markdown;
|
||||||
|
|
||||||
|
internal record MentionNode(Snowflake Id, MentionKind Kind) : MarkdownNode;
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using DiscordChatExporter.Core.Discord;
|
||||||
using DiscordChatExporter.Core.Utils;
|
using DiscordChatExporter.Core.Utils;
|
||||||
|
|
||||||
namespace DiscordChatExporter.Core.Markdown.Parsing;
|
namespace DiscordChatExporter.Core.Markdown.Parsing;
|
||||||
|
@ -123,31 +124,31 @@ internal static partial class MarkdownParser
|
||||||
// Capture @everyone
|
// Capture @everyone
|
||||||
private static readonly IMatcher<MarkdownNode> EveryoneMentionNodeMatcher = new StringMatcher<MarkdownNode>(
|
private static readonly IMatcher<MarkdownNode> EveryoneMentionNodeMatcher = new StringMatcher<MarkdownNode>(
|
||||||
"@everyone",
|
"@everyone",
|
||||||
_ => new MentionNode("everyone", MentionKind.Meta)
|
_ => new MentionNode(Snowflake.Zero, MentionKind.Meta)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Capture @here
|
// Capture @here
|
||||||
private static readonly IMatcher<MarkdownNode> HereMentionNodeMatcher = new StringMatcher<MarkdownNode>(
|
private static readonly IMatcher<MarkdownNode> HereMentionNodeMatcher = new StringMatcher<MarkdownNode>(
|
||||||
"@here",
|
"@here",
|
||||||
_ => new MentionNode("here", MentionKind.Meta)
|
_ => new MentionNode(Snowflake.Zero, MentionKind.Meta)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Capture <@123456> or <@!123456>
|
// Capture <@123456> or <@!123456>
|
||||||
private static readonly IMatcher<MarkdownNode> UserMentionNodeMatcher = new RegexMatcher<MarkdownNode>(
|
private static readonly IMatcher<MarkdownNode> UserMentionNodeMatcher = new RegexMatcher<MarkdownNode>(
|
||||||
new Regex("<@!?(\\d+)>", DefaultRegexOptions),
|
new Regex("<@!?(\\d+)>", DefaultRegexOptions),
|
||||||
(_, m) => new MentionNode(m.Groups[1].Value, MentionKind.User)
|
(_, m) => new MentionNode(Snowflake.Parse(m.Groups[1].Value), MentionKind.User)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Capture <#123456>
|
// Capture <#123456>
|
||||||
private static readonly IMatcher<MarkdownNode> ChannelMentionNodeMatcher = new RegexMatcher<MarkdownNode>(
|
private static readonly IMatcher<MarkdownNode> ChannelMentionNodeMatcher = new RegexMatcher<MarkdownNode>(
|
||||||
new Regex("<#!?(\\d+)>", DefaultRegexOptions),
|
new Regex("<#!?(\\d+)>", DefaultRegexOptions),
|
||||||
(_, m) => new MentionNode(m.Groups[1].Value, MentionKind.Channel)
|
(_, m) => new MentionNode(Snowflake.Parse(m.Groups[1].Value), MentionKind.Channel)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Capture <@&123456>
|
// Capture <@&123456>
|
||||||
private static readonly IMatcher<MarkdownNode> RoleMentionNodeMatcher = new RegexMatcher<MarkdownNode>(
|
private static readonly IMatcher<MarkdownNode> RoleMentionNodeMatcher = new RegexMatcher<MarkdownNode>(
|
||||||
new Regex("<@&(\\d+)>", DefaultRegexOptions),
|
new Regex("<@&(\\d+)>", DefaultRegexOptions),
|
||||||
(_, m) => new MentionNode(m.Groups[1].Value, MentionKind.Role)
|
(_, m) => new MentionNode(Snowflake.Parse(m.Groups[1].Value), MentionKind.Role)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Emoji */
|
/* Emoji */
|
||||||
|
@ -177,7 +178,11 @@ internal static partial class MarkdownParser
|
||||||
// Capture <:lul:123456> or <a:lul:123456>
|
// Capture <:lul:123456> or <a:lul:123456>
|
||||||
private static readonly IMatcher<MarkdownNode> CustomEmojiNodeMatcher = new RegexMatcher<MarkdownNode>(
|
private static readonly IMatcher<MarkdownNode> CustomEmojiNodeMatcher = new RegexMatcher<MarkdownNode>(
|
||||||
new Regex("<(a)?:(.+?):(\\d+?)>", DefaultRegexOptions),
|
new Regex("<(a)?:(.+?):(\\d+?)>", DefaultRegexOptions),
|
||||||
(_, m) => new EmojiNode(m.Groups[3].Value, m.Groups[2].Value, !string.IsNullOrWhiteSpace(m.Groups[1].Value))
|
(_, m) => new EmojiNode(
|
||||||
|
Snowflake.Parse(m.Groups[3].Value),
|
||||||
|
m.Groups[2].Value,
|
||||||
|
!string.IsNullOrWhiteSpace(m.Groups[1].Value)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue