Optimize viewer export in the app

This commit is contained in:
chylex 2022-03-05 21:35:56 +01:00
parent 6a2933ea0a
commit b9899922e0
No known key found for this signature in database
GPG Key ID: 4DE42C8F19A80548

View File

@ -1,13 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Dynamic;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
using DHT.Server.Data; using DHT.Server.Data;
using DHT.Server.Data.Filters; using DHT.Server.Data.Filters;
using DHT.Utils.Logging;
namespace DHT.Server.Database.Export { namespace DHT.Server.Database.Export {
public static class ViewerJsonExport { public static class ViewerJsonExport {
private static readonly Log Log = Log.ForType(typeof(ViewerJsonExport));
public static string Generate(IDatabaseFile db, MessageFilter? filter = null) { public static string Generate(IDatabaseFile db, MessageFilter? filter = null) {
var perf = Log.Start();
var includedUserIds = new HashSet<ulong>(); var includedUserIds = new HashSet<ulong>();
var includedChannelIds = new HashSet<ulong>(); var includedChannelIds = new HashSet<ulong>();
var includedServerIds = new HashSet<ulong>(); var includedServerIds = new HashSet<ulong>();
@ -34,16 +38,19 @@ namespace DHT.Server.Database.Export {
var servers = GenerateServerList(db, includedServerIds, out var serverindex); var servers = GenerateServerList(db, includedServerIds, out var serverindex);
var channels = GenerateChannelList(includedChannels, serverindex); var channels = GenerateChannelList(includedChannels, serverindex);
return JsonSerializer.Serialize(new { var json = JsonSerializer.Serialize(new {
meta = new { users, userindex, servers, channels }, meta = new { users, userindex, servers, channels },
data = GenerateMessageList(includedMessages, userIndices) data = GenerateMessageList(includedMessages, userIndices)
}, opts); }, opts);
perf.End();
return json;
} }
private static dynamic GenerateUserList(IDatabaseFile db, HashSet<ulong> userIds, out List<string> userindex, out Dictionary<ulong, int> userIndices) { private static object GenerateUserList(IDatabaseFile db, HashSet<ulong> userIds, out List<string> userindex, out Dictionary<ulong, object> userIndices) {
var users = new Dictionary<string, dynamic>(); var users = new Dictionary<string, object>();
userindex = new List<string>(); userindex = new List<string>();
userIndices = new Dictionary<ulong, int>(); userIndices = new Dictionary<ulong, object>();
foreach (var user in db.GetAllUsers()) { foreach (var user in db.GetAllUsers()) {
var id = user.Id; var id = user.Id;
@ -51,15 +58,16 @@ namespace DHT.Server.Database.Export {
continue; continue;
} }
dynamic obj = new ExpandoObject(); var obj = new Dictionary<string, object> {
obj.name = user.Name; ["name"] = user.Name
};
if (user.AvatarUrl != null) { if (user.AvatarUrl != null) {
obj.avatar = user.AvatarUrl; obj["avatar"] = user.AvatarUrl;
} }
if (user.Discriminator != null) { if (user.Discriminator != null) {
obj.tag = user.Discriminator; obj["tag"] = user.Discriminator;
} }
var idStr = id.ToString(); var idStr = id.ToString();
@ -71,9 +79,9 @@ namespace DHT.Server.Database.Export {
return users; return users;
} }
private static dynamic GenerateServerList(IDatabaseFile db, HashSet<ulong> serverIds, out Dictionary<ulong, int> serverIndices) { private static object GenerateServerList(IDatabaseFile db, HashSet<ulong> serverIds, out Dictionary<ulong, object> serverIndices) {
var servers = new List<dynamic>(); var servers = new List<object>();
serverIndices = new Dictionary<ulong, int>(); serverIndices = new Dictionary<ulong, object>();
foreach (var server in db.GetAllServers()) { foreach (var server in db.GetAllServers()) {
var id = server.Id; var id = server.Id;
@ -82,37 +90,38 @@ namespace DHT.Server.Database.Export {
} }
serverIndices[id] = servers.Count; serverIndices[id] = servers.Count;
servers.Add(new { servers.Add(new Dictionary<string, object> {
name = server.Name, ["name"] = server.Name,
type = ServerTypes.ToJsonViewerString(server.Type) ["type"] = ServerTypes.ToJsonViewerString(server.Type)
}); });
} }
return servers; return servers;
} }
private static dynamic GenerateChannelList(List<Channel> includedChannels, Dictionary<ulong, int> serverIndices) { private static object GenerateChannelList(List<Channel> includedChannels, Dictionary<ulong, object> serverIndices) {
var channels = new Dictionary<string, dynamic>(); var channels = new Dictionary<string, object>();
foreach (var channel in includedChannels) { foreach (var channel in includedChannels) {
dynamic obj = new ExpandoObject(); var obj = new Dictionary<string, object> {
obj.server = serverIndices[channel.Server]; ["server"] = serverIndices[channel.Server],
obj.name = channel.Name; ["name"] = channel.Name
};
if (channel.ParentId != null) { if (channel.ParentId != null) {
obj.parent = channel.ParentId; obj["parent"] = channel.ParentId;
} }
if (channel.Position != null) { if (channel.Position != null) {
obj.position = channel.Position; obj["position"] = channel.Position;
} }
if (channel.Topic != null) { if (channel.Topic != null) {
obj.topic = channel.Topic; obj["topic"] = channel.Topic;
} }
if (channel.Nsfw != null) { if (channel.Nsfw != null) {
obj.nsfw = channel.Nsfw; obj["nsfw"] = channel.Nsfw;
} }
channels[channel.Id.ToString()] = obj; channels[channel.Id.ToString()] = obj;
@ -121,54 +130,55 @@ namespace DHT.Server.Database.Export {
return channels; return channels;
} }
private static dynamic GenerateMessageList(List<Message> includedMessages, Dictionary<ulong, int> userIndices) { private static object GenerateMessageList(List<Message> includedMessages, Dictionary<ulong, object> userIndices) {
var data = new Dictionary<string, Dictionary<string, dynamic>>(); var data = new Dictionary<string, Dictionary<string, object>>();
foreach (var grouping in includedMessages.GroupBy(static message => message.Channel)) { foreach (var grouping in includedMessages.GroupBy(static message => message.Channel)) {
var channel = grouping.Key.ToString(); var channel = grouping.Key.ToString();
var channelData = new Dictionary<string, dynamic>(); var channelData = new Dictionary<string, object>();
foreach (var message in grouping) { foreach (var message in grouping) {
dynamic obj = new ExpandoObject(); var obj = new Dictionary<string, object> {
obj.u = userIndices[message.Sender]; ["u"] = userIndices[message.Sender],
obj.t = message.Timestamp; ["t"] = message.Timestamp
};
if (!string.IsNullOrEmpty(message.Text)) { if (!string.IsNullOrEmpty(message.Text)) {
obj.m = message.Text; obj["m"] = message.Text;
} }
if (message.EditTimestamp != null) { if (message.EditTimestamp != null) {
obj.te = message.EditTimestamp; obj["te"] = message.EditTimestamp;
} }
if (message.RepliedToId != null) { if (message.RepliedToId != null) {
obj.r = message.RepliedToId.Value; obj["r"] = message.RepliedToId.Value;
} }
if (!message.Attachments.IsEmpty) { if (!message.Attachments.IsEmpty) {
obj.a = message.Attachments.Select(static attachment => new { obj["a"] = message.Attachments.Select(static attachment => new {
url = attachment.Url url = attachment.Url
}).ToArray(); }).ToArray();
} }
if (!message.Embeds.IsEmpty) { if (!message.Embeds.IsEmpty) {
obj.e = message.Embeds.Select(static embed => embed.Json).ToArray(); obj["e"] = message.Embeds.Select(static embed => embed.Json).ToArray();
} }
if (!message.Reactions.IsEmpty) { if (!message.Reactions.IsEmpty) {
obj.re = message.Reactions.Select(static reaction => { obj["re"] = message.Reactions.Select(static reaction => {
dynamic r = new ExpandoObject(); var r = new Dictionary<string, object>();
if (reaction.EmojiId != null) { if (reaction.EmojiId != null) {
r.id = reaction.EmojiId.Value; r["id"] = reaction.EmojiId.Value;
} }
if (reaction.EmojiName != null) { if (reaction.EmojiName != null) {
r.n = reaction.EmojiName; r["n"] = reaction.EmojiName;
} }
r.a = reaction.EmojiFlags.HasFlag(EmojiFlags.Animated); r["a"] = reaction.EmojiFlags.HasFlag(EmojiFlags.Animated);
r.c = reaction.Count; r["c"] = reaction.Count;
return r; return r;
}); });
} }