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