Handle null `name` in `Emoji.Parse(...)`

pull/811/head
Tyrrrz 3 years ago
parent 7a9e25c1f0
commit bfa5d10761

@ -34,8 +34,8 @@ public partial record Attachment
{ {
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var url = json.GetProperty("url").GetNonWhiteSpaceString(); var url = json.GetProperty("url").GetNonWhiteSpaceString();
var width = json.GetPropertyOrNull("width")?.GetInt32(); var width = json.GetPropertyOrNull("width")?.GetInt32OrNull();
var height = json.GetPropertyOrNull("height")?.GetInt32(); var height = json.GetPropertyOrNull("height")?.GetInt32OrNull();
var fileName = json.GetProperty("filename").GetNonWhiteSpaceString(); var fileName = json.GetProperty("filename").GetNonWhiteSpaceString();
var fileSize = json.GetProperty("size").GetInt64().Pipe(FileSize.FromBytes); var fileSize = json.GetProperty("size").GetInt64().Pipe(FileSize.FromBytes);

@ -42,16 +42,16 @@ public partial record Channel
null null
); );
public static Channel Parse(JsonElement json, ChannelCategory? category = null, int? position = null) public static Channel Parse(JsonElement json, ChannelCategory? category = null, int? positionHint = null)
{ {
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var guildId = json.GetPropertyOrNull("guild_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); var guildId = json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
var topic = json.GetPropertyOrNull("topic")?.GetStringOrNull(); var topic = json.GetPropertyOrNull("topic")?.GetStringOrNull();
var kind = (ChannelKind)json.GetProperty("type").GetInt32(); var kind = (ChannelKind)json.GetProperty("type").GetInt32();
var name = var name =
// Guild channel // Guild channel
json.GetPropertyOrNull("name")?.GetStringOrNull() ?? json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull() ??
// DM channel // DM channel
json.GetPropertyOrNull("recipients")? json.GetPropertyOrNull("recipients")?
@ -63,13 +63,15 @@ public partial record Channel
// Fallback // Fallback
id.ToString(); id.ToString();
var position = positionHint ?? json.GetPropertyOrNull("position")?.GetInt32OrNull();
return new Channel( return new Channel(
id, id,
kind, kind,
guildId ?? Guild.DirectMessages.Id, guildId ?? Guild.DirectMessages.Id,
category ?? GetFallbackCategory(kind), category ?? GetFallbackCategory(kind),
name, name,
position ?? json.GetPropertyOrNull("position")?.GetInt32(), position,
topic topic
); );
} }

@ -9,18 +9,15 @@ public record ChannelCategory(Snowflake Id, string Name, int? Position) : IHasId
{ {
public static ChannelCategory Unknown { get; } = new(Snowflake.Zero, "<unknown category>", 0); 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? positionHint = null)
{ {
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var position = positionHint ?? json.GetPropertyOrNull("position")?.GetInt32OrNull();
var name = var name =
json.GetPropertyOrNull("name")?.GetStringOrNull() ?? json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull() ??
id.ToString(); id.ToString();
return new ChannelCategory( return new ChannelCategory(id, name, position);
id,
name,
position ?? json.GetPropertyOrNull("position")?.GetInt32()
);
} }
} }

@ -36,9 +36,9 @@ public partial record Embed
public static Embed Parse(JsonElement json) public static Embed Parse(JsonElement json)
{ {
var title = json.GetPropertyOrNull("title")?.GetStringOrNull(); var title = json.GetPropertyOrNull("title")?.GetStringOrNull();
var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset(); var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset();
var color = json.GetPropertyOrNull("color")?.GetInt32().Pipe(System.Drawing.Color.FromArgb).ResetAlpha(); var color = json.GetPropertyOrNull("color")?.GetInt32OrNull()?.Pipe(System.Drawing.Color.FromArgb).ResetAlpha();
var description = json.GetPropertyOrNull("description")?.GetStringOrNull(); var description = json.GetPropertyOrNull("description")?.GetStringOrNull();
var author = json.GetPropertyOrNull("author")?.Pipe(EmbedAuthor.Parse); var author = json.GetPropertyOrNull("author")?.Pipe(EmbedAuthor.Parse);

@ -13,9 +13,9 @@ public record EmbedAuthor(
public static EmbedAuthor Parse(JsonElement json) public static EmbedAuthor Parse(JsonElement json)
{ {
var name = json.GetPropertyOrNull("name")?.GetStringOrNull(); var name = json.GetPropertyOrNull("name")?.GetStringOrNull();
var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
var iconUrl = json.GetPropertyOrNull("icon_url")?.GetStringOrNull(); var iconUrl = json.GetPropertyOrNull("icon_url")?.GetNonWhiteSpaceStringOrNull();
var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetStringOrNull(); var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetNonWhiteSpaceStringOrNull();
return new EmbedAuthor(name, url, iconUrl, iconProxyUrl); return new EmbedAuthor(name, url, iconUrl, iconProxyUrl);
} }

@ -1,5 +1,4 @@
using System.Text.Json; using System.Text.Json;
using DiscordChatExporter.Core.Utils.Extensions;
using JsonExtensions.Reading; using JsonExtensions.Reading;
namespace DiscordChatExporter.Core.Discord.Data.Embeds; namespace DiscordChatExporter.Core.Discord.Data.Embeds;
@ -14,7 +13,7 @@ public record EmbedField(
{ {
var name = json.GetProperty("name").GetNonWhiteSpaceString(); var name = json.GetProperty("name").GetNonWhiteSpaceString();
var value = json.GetProperty("value").GetNonWhiteSpaceString(); var value = json.GetProperty("value").GetNonWhiteSpaceString();
var isInline = json.GetPropertyOrNull("inline")?.GetBoolean() ?? false; var isInline = json.GetPropertyOrNull("inline")?.GetBooleanOrNull() ?? false;
return new EmbedField(name, value, isInline); return new EmbedField(name, value, isInline);
} }

@ -1,5 +1,4 @@
using System.Text.Json; using System.Text.Json;
using DiscordChatExporter.Core.Utils.Extensions;
using JsonExtensions.Reading; using JsonExtensions.Reading;
namespace DiscordChatExporter.Core.Discord.Data.Embeds; namespace DiscordChatExporter.Core.Discord.Data.Embeds;
@ -12,9 +11,9 @@ public record EmbedFooter(
{ {
public static EmbedFooter Parse(JsonElement json) public static EmbedFooter Parse(JsonElement json)
{ {
var text = json.GetProperty("text").GetNonWhiteSpaceString(); var text = json.GetProperty("text").GetNonNullString();
var iconUrl = json.GetPropertyOrNull("icon_url")?.GetStringOrNull(); var iconUrl = json.GetPropertyOrNull("icon_url")?.GetNonWhiteSpaceStringOrNull();
var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetStringOrNull(); var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetNonWhiteSpaceStringOrNull();
return new EmbedFooter(text, iconUrl, iconProxyUrl); return new EmbedFooter(text, iconUrl, iconProxyUrl);
} }

@ -12,10 +12,10 @@ public record EmbedImage(
{ {
public static EmbedImage Parse(JsonElement json) public static EmbedImage Parse(JsonElement json)
{ {
var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); var url = json.GetPropertyOrNull("url")?.GetNonWhiteSpaceStringOrNull();
var proxyUrl = json.GetPropertyOrNull("proxy_url")?.GetStringOrNull(); var proxyUrl = json.GetPropertyOrNull("proxy_url")?.GetNonWhiteSpaceStringOrNull();
var width = json.GetPropertyOrNull("width")?.GetInt32(); var width = json.GetPropertyOrNull("width")?.GetInt32OrNull();
var height = json.GetPropertyOrNull("height")?.GetInt32(); var height = json.GetPropertyOrNull("height")?.GetInt32OrNull();
return new EmbedImage(url, proxyUrl, width, height); return new EmbedImage(url, proxyUrl, width, height);
} }

@ -1,4 +1,5 @@
using System.Linq; using System;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using DiscordChatExporter.Core.Utils; using DiscordChatExporter.Core.Utils;
using DiscordChatExporter.Core.Utils.Extensions; using DiscordChatExporter.Core.Utils.Extensions;
@ -31,29 +32,41 @@ public partial record Emoji
.Select(r => r.Value.ToString("x")) .Select(r => r.Value.ToString("x"))
); );
public static string GetImageUrl(string? id, string name, bool isAnimated) private static string GetImageUrl(string id, bool isAnimated) => isAnimated
? $"https://cdn.discordapp.com/emojis/{id}.gif"
: $"https://cdn.discordapp.com/emojis/{id}.png";
private static string GetImageUrl(string name) =>
$"https://twemoji.maxcdn.com/2/svg/{GetTwemojiName(name)}.svg";
public static string GetImageUrl(string? id, string? name, bool isAnimated)
{ {
// Custom emoji // Custom emoji
if (!string.IsNullOrWhiteSpace(id)) if (!string.IsNullOrWhiteSpace(id))
{ return GetImageUrl(id, isAnimated);
return isAnimated
? $"https://cdn.discordapp.com/emojis/{id}.gif"
: $"https://cdn.discordapp.com/emojis/{id}.png";
}
// Standard emoji // Standard emoji
var twemojiName = GetTwemojiName(name); if (!string.IsNullOrWhiteSpace(name))
return $"https://twemoji.maxcdn.com/2/svg/{twemojiName}.svg"; return GetImageUrl(name);
// Either ID or name should be set
throw new ApplicationException("Emoji has neither ID nor name set.");
} }
public static Emoji Parse(JsonElement json) public static Emoji Parse(JsonElement json)
{ {
var id = json.GetPropertyOrNull("id")?.GetStringOrNull(); var id = json.GetPropertyOrNull("id")?.GetNonWhiteSpaceStringOrNull();
var name = json.GetProperty("name").GetNonWhiteSpaceString(); var name = json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull();
var isAnimated = json.GetPropertyOrNull("animated")?.GetBoolean() ?? false; var isAnimated = json.GetPropertyOrNull("animated")?.GetBooleanOrNull() ?? false;
var imageUrl = GetImageUrl(id, name, isAnimated); var imageUrl = GetImageUrl(id, name, isAnimated);
return new Emoji(id, name, isAnimated, imageUrl); return new Emoji(
id,
// Name may be missing if it's an emoji inside a reaction
name ?? "<unknown emoji>",
isAnimated,
imageUrl
);
} }
} }

@ -24,7 +24,7 @@ public record Guild(Snowflake Id, string Name, string IconUrl) : IHasId
{ {
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var name = json.GetProperty("name").GetNonWhiteSpaceString(); var name = json.GetProperty("name").GetNonWhiteSpaceString();
var iconHash = json.GetPropertyOrNull("icon")?.GetStringOrNull(); var iconHash = json.GetPropertyOrNull("icon")?.GetNonWhiteSpaceStringOrNull();
var iconUrl = !string.IsNullOrWhiteSpace(iconHash) var iconUrl = !string.IsNullOrWhiteSpace(iconHash)
? GetIconUrl(id, iconHash) ? GetIconUrl(id, iconHash)

@ -28,7 +28,7 @@ public partial record Member
public static Member Parse(JsonElement json) public static Member Parse(JsonElement json)
{ {
var user = json.GetProperty("user").Pipe(User.Parse); var user = json.GetProperty("user").Pipe(User.Parse);
var nick = json.GetPropertyOrNull("nick")?.GetStringOrNull(); var nick = json.GetPropertyOrNull("nick")?.GetNonWhiteSpaceStringOrNull();
var roleIds = json var roleIds = json
.GetPropertyOrNull("roles")? .GetPropertyOrNull("roles")?

@ -35,7 +35,7 @@ public record Message(
var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp") var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp")
?.GetDateTimeOffset(); ?.GetDateTimeOffset();
var kind = (MessageKind)json.GetProperty("type").GetInt32(); var kind = (MessageKind)json.GetProperty("type").GetInt32();
var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false; var isPinned = json.GetPropertyOrNull("pinned")?.GetBooleanOrNull() ?? false;
var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse); var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse);
var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse); var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse);

@ -9,9 +9,9 @@ public record MessageReference(Snowflake? MessageId, Snowflake? ChannelId, Snowf
{ {
public static MessageReference Parse(JsonElement json) public static MessageReference Parse(JsonElement json)
{ {
var messageId = json.GetPropertyOrNull("message_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); var messageId = json.GetPropertyOrNull("message_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
var channelId = json.GetPropertyOrNull("channel_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); var channelId = json.GetPropertyOrNull("channel_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
var guildId = json.GetPropertyOrNull("guild_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); var guildId = json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
return new MessageReference(messageId, channelId, guildId); return new MessageReference(messageId, channelId, guildId);
} }

@ -36,10 +36,10 @@ public partial record User
public static User Parse(JsonElement json) public static User Parse(JsonElement json)
{ {
var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse);
var isBot = json.GetPropertyOrNull("bot")?.GetBoolean() ?? false; var isBot = json.GetPropertyOrNull("bot")?.GetBooleanOrNull() ?? false;
var discriminator = json.GetProperty("discriminator").GetNonWhiteSpaceString().Pipe(int.Parse); var discriminator = json.GetProperty("discriminator").GetNonWhiteSpaceString().Pipe(int.Parse);
var name = json.GetProperty("username").GetNonWhiteSpaceString(); var name = json.GetProperty("username").GetNonWhiteSpaceString();
var avatarHash = json.GetPropertyOrNull("avatar")?.GetStringOrNull(); var avatarHash = json.GetPropertyOrNull("avatar")?.GetNonWhiteSpaceStringOrNull();
var avatarUrl = !string.IsNullOrWhiteSpace(avatarHash) var avatarUrl = !string.IsNullOrWhiteSpace(avatarHash)
? GetAvatarUrl(id, avatarHash) ? GetAvatarUrl(id, avatarHash)

@ -142,7 +142,7 @@ public class DiscordClient
foreach (var channelJson in responseOrdered) foreach (var channelJson in responseOrdered)
{ {
var parentId = channelJson.GetPropertyOrNull("parent_id")?.GetStringOrNull(); var parentId = channelJson.GetPropertyOrNull("parent_id")?.GetNonWhiteSpaceStringOrNull();
var category = !string.IsNullOrWhiteSpace(parentId) var category = !string.IsNullOrWhiteSpace(parentId)
? categories.GetValueOrDefault(parentId) ? categories.GetValueOrDefault(parentId)
@ -205,7 +205,7 @@ public class DiscordClient
{ {
var response = await GetJsonResponseAsync($"channels/{channelId}", cancellationToken); var response = await GetJsonResponseAsync($"channels/{channelId}", cancellationToken);
var parentId = response.GetPropertyOrNull("parent_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); var parentId = response.GetPropertyOrNull("parent_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
var category = parentId is not null var category = parentId is not null
? await GetChannelCategoryAsync(parentId.Value, cancellationToken) ? await GetChannelCategoryAsync(parentId.Value, cancellationToken)

@ -5,7 +5,7 @@ namespace DiscordChatExporter.Core.Utils;
public static class FileFormat public static class FileFormat
{ {
private static readonly HashSet<string> ImageFormats = new(StringComparer.OrdinalIgnoreCase) private static readonly HashSet<string> ImageExtensions = new(StringComparer.OrdinalIgnoreCase)
{ {
".jpg", ".jpg",
".jpeg", ".jpeg",
@ -16,18 +16,18 @@ public static class FileFormat
".webp" ".webp"
}; };
public static bool IsImage(string format) => ImageFormats.Contains(format); public static bool IsImage(string format) => ImageExtensions.Contains(format);
private static readonly HashSet<string> VideoFormats = new(StringComparer.OrdinalIgnoreCase) private static readonly HashSet<string> VideoExtensions = new(StringComparer.OrdinalIgnoreCase)
{ {
".mp4", ".mp4",
".webm", ".webm",
".mov" ".mov"
}; };
public static bool IsVideo(string format) => VideoFormats.Contains(format); public static bool IsVideo(string format) => VideoExtensions.Contains(format);
private static readonly HashSet<string> AudioFormats = new(StringComparer.OrdinalIgnoreCase) private static readonly HashSet<string> AudioExtensions = new(StringComparer.OrdinalIgnoreCase)
{ {
".mp3", ".mp3",
".wav", ".wav",
@ -36,5 +36,5 @@ public static class FileFormat
".m4a" ".m4a"
}; };
public static bool IsAudio(string format) => AudioFormats.Contains(format); public static bool IsAudio(string format) => AudioExtensions.Contains(format);
} }
Loading…
Cancel
Save