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 url = json.GetProperty("url").GetNonWhiteSpaceString();
var width = json.GetPropertyOrNull("width")?.GetInt32();
var height = json.GetPropertyOrNull("height")?.GetInt32();
var width = json.GetPropertyOrNull("width")?.GetInt32OrNull();
var height = json.GetPropertyOrNull("height")?.GetInt32OrNull();
var fileName = json.GetProperty("filename").GetNonWhiteSpaceString();
var fileSize = json.GetProperty("size").GetInt64().Pipe(FileSize.FromBytes);

@ -42,16 +42,16 @@ public partial record Channel
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 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 kind = (ChannelKind)json.GetProperty("type").GetInt32();
var name =
// Guild channel
json.GetPropertyOrNull("name")?.GetStringOrNull() ??
json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull() ??
// DM channel
json.GetPropertyOrNull("recipients")?
@ -63,13 +63,15 @@ public partial record Channel
// Fallback
id.ToString();
var position = positionHint ?? json.GetPropertyOrNull("position")?.GetInt32OrNull();
return new Channel(
id,
kind,
guildId ?? Guild.DirectMessages.Id,
category ?? GetFallbackCategory(kind),
name,
position ?? json.GetPropertyOrNull("position")?.GetInt32(),
position,
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 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 position = positionHint ?? json.GetPropertyOrNull("position")?.GetInt32OrNull();
var name =
json.GetPropertyOrNull("name")?.GetStringOrNull() ??
json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull() ??
id.ToString();
return new ChannelCategory(
id,
name,
position ?? json.GetPropertyOrNull("position")?.GetInt32()
);
return new ChannelCategory(id, name, position);
}
}

@ -36,9 +36,9 @@ public partial record Embed
public static Embed Parse(JsonElement json)
{
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 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 author = json.GetPropertyOrNull("author")?.Pipe(EmbedAuthor.Parse);

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

@ -1,5 +1,4 @@
using System.Text.Json;
using DiscordChatExporter.Core.Utils.Extensions;
using JsonExtensions.Reading;
namespace DiscordChatExporter.Core.Discord.Data.Embeds;
@ -14,7 +13,7 @@ public record EmbedField(
{
var name = json.GetProperty("name").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);
}

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

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

@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using System.Text.Json;
using DiscordChatExporter.Core.Utils;
using DiscordChatExporter.Core.Utils.Extensions;
@ -31,29 +32,41 @@ public partial record Emoji
.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
if (!string.IsNullOrWhiteSpace(id))
{
return isAnimated
? $"https://cdn.discordapp.com/emojis/{id}.gif"
: $"https://cdn.discordapp.com/emojis/{id}.png";
}
return GetImageUrl(id, isAnimated);
// Standard emoji
var twemojiName = GetTwemojiName(name);
return $"https://twemoji.maxcdn.com/2/svg/{twemojiName}.svg";
if (!string.IsNullOrWhiteSpace(name))
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)
{
var id = json.GetPropertyOrNull("id")?.GetStringOrNull();
var name = json.GetProperty("name").GetNonWhiteSpaceString();
var isAnimated = json.GetPropertyOrNull("animated")?.GetBoolean() ?? false;
var id = json.GetPropertyOrNull("id")?.GetNonWhiteSpaceStringOrNull();
var name = json.GetPropertyOrNull("name")?.GetNonWhiteSpaceStringOrNull();
var isAnimated = json.GetPropertyOrNull("animated")?.GetBooleanOrNull() ?? false;
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 name = json.GetProperty("name").GetNonWhiteSpaceString();
var iconHash = json.GetPropertyOrNull("icon")?.GetStringOrNull();
var iconHash = json.GetPropertyOrNull("icon")?.GetNonWhiteSpaceStringOrNull();
var iconUrl = !string.IsNullOrWhiteSpace(iconHash)
? GetIconUrl(id, iconHash)

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

@ -35,7 +35,7 @@ public record Message(
var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp")
?.GetDateTimeOffset();
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 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)
{
var messageId = json.GetPropertyOrNull("message_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse);
var channelId = json.GetPropertyOrNull("channel_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse);
var guildId = json.GetPropertyOrNull("guild_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse);
var messageId = json.GetPropertyOrNull("message_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
var channelId = json.GetPropertyOrNull("channel_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
var guildId = json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceStringOrNull()?.Pipe(Snowflake.Parse);
return new MessageReference(messageId, channelId, guildId);
}

@ -36,10 +36,10 @@ public partial record User
public static User Parse(JsonElement json)
{
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 name = json.GetProperty("username").GetNonWhiteSpaceString();
var avatarHash = json.GetPropertyOrNull("avatar")?.GetStringOrNull();
var avatarHash = json.GetPropertyOrNull("avatar")?.GetNonWhiteSpaceStringOrNull();
var avatarUrl = !string.IsNullOrWhiteSpace(avatarHash)
? GetAvatarUrl(id, avatarHash)

@ -142,7 +142,7 @@ public class DiscordClient
foreach (var channelJson in responseOrdered)
{
var parentId = channelJson.GetPropertyOrNull("parent_id")?.GetStringOrNull();
var parentId = channelJson.GetPropertyOrNull("parent_id")?.GetNonWhiteSpaceStringOrNull();
var category = !string.IsNullOrWhiteSpace(parentId)
? categories.GetValueOrDefault(parentId)
@ -205,7 +205,7 @@ public class DiscordClient
{
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
? await GetChannelCategoryAsync(parentId.Value, cancellationToken)

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