From cc565598d327fb8cd7aa5f61bb95cf4b8b767fe7 Mon Sep 17 00:00:00 2001 From: Alexey Golub Date: Fri, 27 Oct 2017 22:08:53 +0300 Subject: [PATCH] Add support for channel mentions formatting Closes #19 --- DiscordChatExporter/Models/Message.cs | 6 +++- DiscordChatExporter/Services/DataService.cs | 29 +++++++++++++++---- DiscordChatExporter/Services/ExportService.cs | 13 +++++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/DiscordChatExporter/Models/Message.cs b/DiscordChatExporter/Models/Message.cs index c54d195..2ce20f6 100644 --- a/DiscordChatExporter/Models/Message.cs +++ b/DiscordChatExporter/Models/Message.cs @@ -21,10 +21,13 @@ namespace DiscordChatExporter.Models public IReadOnlyList MentionedRoles { get; } + public IReadOnlyList MentionedChannels { get; } + public Message(string id, User author, DateTime timeStamp, DateTime? editedTimeStamp, string content, IReadOnlyList attachments, - IReadOnlyList mentionedUsers, IReadOnlyList mentionedRoles) + IReadOnlyList mentionedUsers, IReadOnlyList mentionedRoles, + IReadOnlyList mentionedChannels) { Id = id; Author = author; @@ -34,6 +37,7 @@ namespace DiscordChatExporter.Models Attachments = attachments; MentionedUsers = mentionedUsers; MentionedRoles = mentionedRoles; + MentionedChannels = mentionedChannels; } public override string ToString() diff --git a/DiscordChatExporter/Services/DataService.cs b/DiscordChatExporter/Services/DataService.cs index b639630..53c1b55 100644 --- a/DiscordChatExporter/Services/DataService.cs +++ b/DiscordChatExporter/Services/DataService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Text.RegularExpressions; using System.Threading.Tasks; using DiscordChatExporter.Exceptions; using DiscordChatExporter.Models; @@ -15,7 +16,8 @@ namespace DiscordChatExporter.Services private const string ApiRoot = "https://discordapp.com/api/v6"; private readonly HttpClient _httpClient = new HttpClient(); - private readonly Dictionary _rolesCache = new Dictionary(); + private readonly Dictionary _roleCache = new Dictionary(); + private readonly Dictionary _channelCache = new Dictionary(); private async Task GetStringAsync(string url) { @@ -61,7 +63,7 @@ namespace DiscordChatExporter.Services { var roles = await GetGuildRolesAsync(token, guild.Id); foreach (var role in roles) - _rolesCache[role.Id] = role; + _roleCache[role.Id] = role; } return guilds; @@ -92,6 +94,10 @@ namespace DiscordChatExporter.Services // Parse var channels = JArray.Parse(content).Select(ParseChannel).ToArray(); + // Cache + foreach (var channel in channels) + _channelCache[channel.Id] = channel; + return channels; } @@ -114,7 +120,7 @@ namespace DiscordChatExporter.Services var content = await GetStringAsync(url); // Parse - var messages = JArray.Parse(content).Select(j => ParseMessage(j, _rolesCache)); + var messages = JArray.Parse(content).Select(j => ParseMessage(j, _roleCache, _channelCache)); // Add messages to list string currentMessageId = null; @@ -213,7 +219,8 @@ namespace DiscordChatExporter.Services return new Channel(id, name, type); } - private static Message ParseMessage(JToken token, IDictionary roles) + private static Message ParseMessage(JToken token, + IDictionary roles, IDictionary channels) { // Get basic data var id = token.Value("id"); @@ -259,15 +266,25 @@ namespace DiscordChatExporter.Services attachments.Add(attachment); } - // Get mentions + // Get user mentions var mentionedUsers = token["mentions"].Select(ParseUser).ToArray(); + + // Get role mentions var mentionedRoles = token["mention_roles"] .Values() .Select(i => roles.GetOrDefault(i) ?? new Role(i, "deleted-role")) .ToArray(); + // Get channel mentions + var mentionedChanenls = Regex.Matches(content, "<#(\\d+)>") + .Cast() + .Select(m => m.Groups[1].Value) + .ExceptBlank() + .Select(i => channels.GetOrDefault(i) ?? new Channel(i, "deleted-channel", ChannelType.GuildTextChat)) + .ToArray(); + return new Message(id, author, timeStamp, editedTimeStamp, content, attachments, - mentionedUsers, mentionedRoles); + mentionedUsers, mentionedRoles, mentionedChanenls); } } } \ No newline at end of file diff --git a/DiscordChatExporter/Services/ExportService.cs b/DiscordChatExporter/Services/ExportService.cs index a39134b..31492aa 100644 --- a/DiscordChatExporter/Services/ExportService.cs +++ b/DiscordChatExporter/Services/ExportService.cs @@ -230,6 +230,10 @@ namespace DiscordChatExporter.Services foreach (var mentionedRole in message.MentionedRoles) content = content.Replace($"<@&{mentionedRole.Id}>", $"@{mentionedRole.Name}"); + // Channel mentions (<#id>) + foreach (var mentionedChannel in message.MentionedChannels) + content = content.Replace($"<#{mentionedChannel.Id}>", $"#{mentionedChannel.Name}"); + // Custom emojis (<:name:id>) content = Regex.Replace(content, "<(:.*?:)\\d*>", "$1"); @@ -294,6 +298,15 @@ namespace DiscordChatExporter.Services ""); } + // Channel mentions (<#id>) + foreach (var mentionedChannel in message.MentionedChannels) + { + content = content.Replace($"<#{mentionedChannel.Id}>", + "" + + $"#{HtmlEncode(mentionedChannel.Name)}" + + ""); + } + // Custom emojis (<:name:id>) content = Regex.Replace(content, "<(:.*?:)(\\d*)>", "");