Add support for Guild Member object & included data (#279)

This commit is contained in:
Will Kennedy
2020-03-26 08:36:55 -04:00
committed by GitHub
parent 7bb8038ce9
commit 79e43c4144
10 changed files with 118 additions and 29 deletions

View File

@@ -21,13 +21,23 @@ namespace DiscordChatExporter.Core.Services
return new User(id, discriminator, name, avatarHash, isBot);
}
private Member ParseMember(JToken json)
{
var userId = ParseUser(json["user"]!).Id;
var nick = json["nick"]?.Value<string>();
var roles = json["roles"]!.Select(jt => jt.Value<string>()).ToArray();
return new Member(userId, nick, roles);
}
private Guild ParseGuild(JToken json)
{
var id = json["id"]!.Value<string>();
var name = json["name"]!.Value<string>();
var iconHash = json["icon"]!.Value<string>();
var roles = json["roles"]!.Select(ParseRole).ToList();
return new Guild(id, name, iconHash);
return new Guild(id, name, roles, iconHash);
}
private Channel ParseChannel(JToken json)
@@ -64,8 +74,10 @@ namespace DiscordChatExporter.Core.Services
{
var id = json["id"]!.Value<string>();
var name = json["name"]!.Value<string>();
var color = json["color"]!.Value<int>();
var position = json["position"]!.Value<int>();
return new Role(id, name);
return new Role(id, name, Color.FromArgb(color), position);
}
private Attachment ParseAttachment(JToken json)
@@ -193,7 +205,7 @@ namespace DiscordChatExporter.Core.Services
// Get author
var author = ParseUser(json["author"]!);
// Get attachments
var attachments = (json["attachments"] ?? Enumerable.Empty<JToken>()).Select(ParseAttachment).ToArray();

View File

@@ -40,8 +40,12 @@ namespace DiscordChatExporter.Core.Services
},
(response, timespan, retryCount, context) => Task.CompletedTask);
}
private async Task<JToken> GetApiResponseAsync(AuthToken token, string route)
{
return (await GetApiResponseAsync(token, route, true))!;
}
private async Task<JToken?> GetApiResponseAsync(AuthToken token, string route, bool errorOnFail)
{
using var response = await _httpPolicy.ExecuteAsync(async () =>
{
@@ -56,7 +60,10 @@ namespace DiscordChatExporter.Core.Services
// We throw our own exception here because default one doesn't have status code
if (!response.IsSuccessStatusCode)
throw new HttpErrorStatusCodeException(response.StatusCode, response.ReasonPhrase);
{
if(errorOnFail) throw new HttpErrorStatusCodeException(response.StatusCode, response.ReasonPhrase);
else return null;
}
var jsonRaw = await response.Content.ReadAsStringAsync();
return JToken.Parse(jsonRaw);
@@ -74,6 +81,15 @@ namespace DiscordChatExporter.Core.Services
return guild;
}
public async Task<Member?> GetGuildMemberAsync(AuthToken token, string guildId, string userId)
{
var response = await GetApiResponseAsync(token, $"guilds/{guildId}/members/{userId}", false);
if(response == null) return null;
var member = ParseMember(response);
return member;
}
public async Task<Channel> GetChannelAsync(AuthToken token, string channelId)
{
var response = await GetApiResponseAsync(token, $"channels/{channelId}");
@@ -125,18 +141,6 @@ namespace DiscordChatExporter.Core.Services
return channels;
}
public async Task<IReadOnlyList<Role>> GetGuildRolesAsync(AuthToken token, string guildId)
{
// Special case for direct messages pseudo-guild
if (guildId == Guild.DirectMessages.Id)
return Array.Empty<Role>();
var response = await GetApiResponseAsync(token, $"guilds/{guildId}/roles");
var roles = response.Select(ParseRole).ToArray();
return roles;
}
private async Task<Message> GetLastMessageAsync(AuthToken token, string channelId, DateTimeOffset? before = null)
{
var route = $"channels/{channelId}/messages?limit=1";

View File

@@ -34,7 +34,7 @@ namespace DiscordChatExporter.Core.Services
// Create context
var mentionableUsers = new HashSet<User>(IdBasedEqualityComparer.Instance);
var mentionableChannels = await _dataService.GetGuildChannelsAsync(token, guild.Id);
var mentionableRoles = await _dataService.GetGuildRolesAsync(token, guild.Id);
var mentionableRoles = guild.Roles;
var context = new RenderContext
(
@@ -50,8 +50,21 @@ namespace DiscordChatExporter.Core.Services
await foreach (var message in _dataService.GetMessagesAsync(token, channel.Id, after, before, progress))
{
// Add encountered users to the list of mentionable users
mentionableUsers.Add(message.Author);
mentionableUsers.AddRange(message.MentionedUsers);
var encounteredUsers = new List<User>();
encounteredUsers.Add(message.Author);
encounteredUsers.AddRange(message.MentionedUsers);
mentionableUsers.AddRange(encounteredUsers);
foreach (User u in encounteredUsers)
{
if(!guild.Members.ContainsKey(u.Id))
{
var member = await _dataService.GetGuildMemberAsync(token, guild.Id, u.Id);
guild.Members[u.Id] = member;
}
}
// Render message
await renderer.RenderMessageAsync(message);