2024-10-24 23:35:44 +02:00
|
|
|
// Copyright (C) 2021-present sam (starshines.gay)
|
|
|
|
|
//
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
|
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
2024-10-28 23:42:57 +01:00
|
|
|
using System.Data.Common;
|
2024-10-24 23:35:44 +02:00
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Text.Json;
|
|
|
|
|
using Catalogger.Backend.Database;
|
|
|
|
|
using Catalogger.Backend.Database.Models;
|
2024-10-28 23:42:57 +01:00
|
|
|
using Dapper;
|
2024-10-24 23:35:44 +02:00
|
|
|
using NodaTime.Extensions;
|
|
|
|
|
using Serilog;
|
|
|
|
|
|
|
|
|
|
namespace Catalogger.GoImporter;
|
|
|
|
|
|
|
|
|
|
public static class GuildImport
|
|
|
|
|
{
|
2024-10-28 23:42:57 +01:00
|
|
|
public static async Task DoImportAsync(DatabaseConnection conn, string filename)
|
2024-10-24 23:35:44 +02:00
|
|
|
{
|
|
|
|
|
var rawData = await File.OpenText(filename).ReadToEndAsync();
|
|
|
|
|
var data = JsonSerializer.Deserialize<GuildsExport>(rawData, Program.JsonOptions);
|
|
|
|
|
if (data == null)
|
|
|
|
|
{
|
|
|
|
|
Log.Error("Guilds JSON dump was deserialized as null, aborting");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var watch = new Stopwatch();
|
|
|
|
|
watch.Start();
|
|
|
|
|
|
2024-10-28 23:42:57 +01:00
|
|
|
await using var tx = await conn.BeginTransactionAsync();
|
2024-10-24 23:35:44 +02:00
|
|
|
|
|
|
|
|
foreach (var g in data.Guilds)
|
2024-10-28 23:42:57 +01:00
|
|
|
await ImportGuildAsync(conn, tx, g);
|
2024-10-24 23:35:44 +02:00
|
|
|
foreach (var i in data.Invites)
|
2024-10-28 23:42:57 +01:00
|
|
|
await ImportInviteAsync(conn, tx, i);
|
2024-10-24 23:35:44 +02:00
|
|
|
foreach (var w in data.Watchlist)
|
2024-10-28 23:42:57 +01:00
|
|
|
await ImportWatchlistEntryAsync(conn, tx, w);
|
2024-10-24 23:35:44 +02:00
|
|
|
|
|
|
|
|
await tx.CommitAsync();
|
|
|
|
|
|
|
|
|
|
Log.Information(
|
|
|
|
|
"Imported guilds, invites, and watchlist entries in {Duration}",
|
|
|
|
|
watch.Elapsed.ToDuration()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-28 23:42:57 +01:00
|
|
|
private static async Task ImportGuildAsync(
|
|
|
|
|
DatabaseConnection conn,
|
|
|
|
|
DbTransaction tx,
|
|
|
|
|
GoGuild guild
|
|
|
|
|
)
|
2024-10-24 23:35:44 +02:00
|
|
|
{
|
2024-11-18 00:47:27 +01:00
|
|
|
var messages = new Guild.MessageConfig
|
2024-10-24 23:35:44 +02:00
|
|
|
{
|
|
|
|
|
IgnoredChannels = guild.IgnoredChannels.ToList(),
|
|
|
|
|
IgnoredUsers = guild.IgnoredUsers.ToList(),
|
2024-11-18 00:47:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var channels = new Guild.ChannelConfig
|
|
|
|
|
{
|
2024-10-24 23:35:44 +02:00
|
|
|
GuildUpdate = guild.Channels.TryParse("GUILD_UPDATE"),
|
|
|
|
|
GuildEmojisUpdate = guild.Channels.TryParse("GUILD_EMOJIS_UPDATE"),
|
|
|
|
|
GuildRoleCreate = guild.Channels.TryParse("GUILD_ROLE_CREATE"),
|
|
|
|
|
GuildRoleUpdate = guild.Channels.TryParse("GUILD_ROLE_UPDATE"),
|
|
|
|
|
GuildRoleDelete = guild.Channels.TryParse("GUILD_ROLE_DELETE"),
|
|
|
|
|
ChannelCreate = guild.Channels.TryParse("CHANNEL_CREATE"),
|
|
|
|
|
ChannelUpdate = guild.Channels.TryParse("CHANNEL_UPDATE"),
|
|
|
|
|
ChannelDelete = guild.Channels.TryParse("CHANNEL_DELETE"),
|
|
|
|
|
GuildMemberAdd = guild.Channels.TryParse("GUILD_MEMBER_ADD"),
|
|
|
|
|
GuildMemberUpdate = guild.Channels.TryParse("GUILD_MEMBER_UPDATE"),
|
|
|
|
|
GuildKeyRoleUpdate = guild.Channels.TryParse("GUILD_KEY_ROLE_UPDATE"),
|
|
|
|
|
GuildMemberNickUpdate = guild.Channels.TryParse("GUILD_MEMBER_NICK_UPDATE"),
|
|
|
|
|
GuildMemberAvatarUpdate = guild.Channels.TryParse("GUILD_MEMBER_NICK_UPDATE"),
|
|
|
|
|
GuildMemberTimeout = guild.Channels.TryParse("GUILD_MEMBER_KICK"),
|
|
|
|
|
GuildMemberRemove = guild.Channels.TryParse("GUILD_MEMBER_REMOVE"),
|
|
|
|
|
GuildMemberKick = guild.Channels.TryParse("GUILD_MEMBER_KICK"),
|
|
|
|
|
GuildBanAdd = guild.Channels.TryParse("GUILD_BAN_ADD"),
|
|
|
|
|
GuildBanRemove = guild.Channels.TryParse("GUILD_BAN_REMOVE"),
|
|
|
|
|
InviteCreate = guild.Channels.TryParse("INVITE_CREATE"),
|
|
|
|
|
InviteDelete = guild.Channels.TryParse("INVITE_DELETE"),
|
|
|
|
|
MessageUpdate = guild.Channels.TryParse("MESSAGE_UPDATE"),
|
|
|
|
|
MessageDelete = guild.Channels.TryParse("MESSAGE_DELETE"),
|
|
|
|
|
MessageDeleteBulk = guild.Channels.TryParse("MESSAGE_DELETE_BULK"),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach (var (key, value) in guild.Redirects)
|
|
|
|
|
if (ulong.TryParse(key, out var fromId) && ulong.TryParse(value, out var toId))
|
|
|
|
|
channels.Redirects[fromId] = toId;
|
|
|
|
|
|
2024-10-28 23:42:57 +01:00
|
|
|
await conn.ExecuteAsync(
|
|
|
|
|
"""
|
2024-11-18 00:47:27 +01:00
|
|
|
insert into guilds (id, channels, messages, banned_systems, key_roles)
|
|
|
|
|
values (@Id, @channels::jsonb, @messages::jsonb, @BannedSystems, @KeyRoles)
|
2024-10-28 23:42:57 +01:00
|
|
|
""",
|
|
|
|
|
new
|
|
|
|
|
{
|
|
|
|
|
guild.Id,
|
2024-11-18 00:47:27 +01:00
|
|
|
messages,
|
|
|
|
|
channels,
|
2024-10-28 23:42:57 +01:00
|
|
|
guild.BannedSystems,
|
|
|
|
|
guild.KeyRoles,
|
|
|
|
|
},
|
|
|
|
|
tx
|
|
|
|
|
);
|
2024-10-24 23:35:44 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-28 23:42:57 +01:00
|
|
|
private static async Task ImportInviteAsync(
|
|
|
|
|
DatabaseConnection conn,
|
|
|
|
|
DbTransaction tx,
|
|
|
|
|
GoInvite invite
|
|
|
|
|
)
|
2024-10-24 23:35:44 +02:00
|
|
|
{
|
2024-10-28 23:42:57 +01:00
|
|
|
await conn.ExecuteAsync(
|
|
|
|
|
"insert into invites (code, guild_id, name) values (@Code, @GuildId, @Name)",
|
|
|
|
|
new
|
|
|
|
|
{
|
|
|
|
|
invite.GuildId,
|
|
|
|
|
invite.Code,
|
|
|
|
|
invite.Name,
|
|
|
|
|
},
|
|
|
|
|
tx
|
|
|
|
|
);
|
2024-10-24 23:35:44 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-28 23:42:57 +01:00
|
|
|
private static async Task ImportWatchlistEntryAsync(
|
|
|
|
|
DatabaseConnection conn,
|
|
|
|
|
DbTransaction tx,
|
|
|
|
|
GoWatchlistEntry watchlistEntry
|
|
|
|
|
)
|
2024-10-24 23:35:44 +02:00
|
|
|
{
|
2024-10-28 23:42:57 +01:00
|
|
|
await conn.ExecuteAsync(
|
|
|
|
|
"""
|
|
|
|
|
insert into watchlists (guild_id, user_id, added_at, moderator_id, reason)
|
|
|
|
|
values (@GuildId, @UserId, @AddedAt, @ModeratorId, @Reason)
|
|
|
|
|
""",
|
|
|
|
|
new
|
|
|
|
|
{
|
|
|
|
|
watchlistEntry.GuildId,
|
|
|
|
|
watchlistEntry.UserId,
|
|
|
|
|
watchlistEntry.AddedAt,
|
|
|
|
|
watchlistEntry.ModeratorId,
|
|
|
|
|
watchlistEntry.Reason,
|
|
|
|
|
},
|
|
|
|
|
tx
|
|
|
|
|
);
|
2024-10-24 23:35:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static ulong TryParse(this Dictionary<string, string> dict, string key) =>
|
|
|
|
|
dict.TryGetValue(key, out var raw) && ulong.TryParse(raw, out var id) ? id : 0;
|
|
|
|
|
}
|