feat: export guilds from old bot and import into new one
This commit is contained in:
parent
301744dd4e
commit
9302ba200f
10 changed files with 1326 additions and 0 deletions
14
Catalogger.GoImporter/Catalogger.GoImporter.csproj
Normal file
14
Catalogger.GoImporter/Catalogger.GoImporter.csproj
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Catalogger.Backend\Catalogger.Backend.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
129
Catalogger.GoImporter/GuildImport.cs
Normal file
129
Catalogger.GoImporter/GuildImport.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// 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/>.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using Catalogger.Backend.Database;
|
||||
using Catalogger.Backend.Database.Models;
|
||||
using NodaTime.Extensions;
|
||||
using Serilog;
|
||||
|
||||
namespace Catalogger.GoImporter;
|
||||
|
||||
public static class GuildImport
|
||||
{
|
||||
public static async Task DoImportAsync(DatabaseContext db, string filename)
|
||||
{
|
||||
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();
|
||||
|
||||
await using var tx = await db.Database.BeginTransactionAsync();
|
||||
|
||||
foreach (var g in data.Guilds)
|
||||
ImportGuild(db, g);
|
||||
foreach (var i in data.Invites)
|
||||
ImportInvite(db, i);
|
||||
foreach (var w in data.Watchlist)
|
||||
ImportWatchlistEntry(db, w);
|
||||
|
||||
await db.SaveChangesAsync();
|
||||
await tx.CommitAsync();
|
||||
|
||||
Log.Information(
|
||||
"Imported guilds, invites, and watchlist entries in {Duration}",
|
||||
watch.Elapsed.ToDuration()
|
||||
);
|
||||
}
|
||||
|
||||
private static void ImportGuild(DatabaseContext db, GoGuild guild)
|
||||
{
|
||||
var channels = new Guild.ChannelConfig
|
||||
{
|
||||
IgnoredChannels = guild.IgnoredChannels.ToList(),
|
||||
IgnoredUsers = guild.IgnoredUsers.ToList(),
|
||||
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;
|
||||
|
||||
var dbGuild = new Guild
|
||||
{
|
||||
Id = guild.Id,
|
||||
BannedSystems = guild.BannedSystems.ToList(),
|
||||
KeyRoles = guild.KeyRoles.ToList(),
|
||||
Channels = channels,
|
||||
};
|
||||
|
||||
db.Guilds.Add(dbGuild);
|
||||
}
|
||||
|
||||
private static void ImportInvite(DatabaseContext db, GoInvite invite)
|
||||
{
|
||||
var dbInvite = new Invite
|
||||
{
|
||||
GuildId = invite.GuildId,
|
||||
Code = invite.Code,
|
||||
Name = invite.Name,
|
||||
};
|
||||
db.Invites.Add(dbInvite);
|
||||
}
|
||||
|
||||
private static void ImportWatchlistEntry(DatabaseContext db, GoWatchlistEntry watchlistEntry)
|
||||
{
|
||||
var dbWatchlist = new Watchlist
|
||||
{
|
||||
GuildId = watchlistEntry.GuildId,
|
||||
UserId = watchlistEntry.UserId,
|
||||
ModeratorId = watchlistEntry.ModeratorId,
|
||||
AddedAt = watchlistEntry.AddedAt,
|
||||
Reason = watchlistEntry.Reason,
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
47
Catalogger.GoImporter/Models.cs
Normal file
47
Catalogger.GoImporter/Models.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// 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/>.
|
||||
|
||||
using NodaTime;
|
||||
using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
|
||||
|
||||
// ReSharper disable NotAccessedPositionalProperty.Global
|
||||
|
||||
namespace Catalogger.GoImporter;
|
||||
|
||||
public record GoGuild(
|
||||
[property: J("ID")] ulong Id,
|
||||
Dictionary<string, string> Channels,
|
||||
Dictionary<string, string> Redirects,
|
||||
ulong[] IgnoredChannels,
|
||||
string[] BannedSystems,
|
||||
ulong[] KeyRoles,
|
||||
ulong[] IgnoredUsers
|
||||
);
|
||||
|
||||
public record GoInvite([property: J("GuildID")] ulong GuildId, string Code, string Name);
|
||||
|
||||
public record GoWatchlistEntry(
|
||||
[property: J("GuildID")] ulong GuildId,
|
||||
[property: J("UserID")] ulong UserId,
|
||||
[property: J("Moderator")] ulong ModeratorId,
|
||||
[property: J("Added")] Instant AddedAt,
|
||||
string Reason
|
||||
);
|
||||
|
||||
public record GuildsExport(
|
||||
List<GoGuild> Guilds,
|
||||
List<GoInvite> Invites,
|
||||
List<GoWatchlistEntry> Watchlist
|
||||
);
|
||||
56
Catalogger.GoImporter/Program.cs
Normal file
56
Catalogger.GoImporter/Program.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// See https://aka.ms/new-console-template for more information
|
||||
|
||||
using System.Text.Json;
|
||||
using Catalogger.Backend;
|
||||
using Catalogger.Backend.Database;
|
||||
using Catalogger.Backend.Extensions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NodaTime;
|
||||
using NodaTime.Serialization.SystemTextJson;
|
||||
using NodaTime.Text;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
|
||||
namespace Catalogger.GoImporter;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
public static JsonSerializerOptions JsonOptions =
|
||||
new JsonSerializerOptions().ConfigureForNodaTime(
|
||||
new NodaJsonSettings
|
||||
{
|
||||
InstantConverter = new NodaPatternConverter<Instant>(InstantPattern.ExtendedIso),
|
||||
}
|
||||
);
|
||||
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.Enrich.FromLogContext()
|
||||
.MinimumLevel.Debug()
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
.WriteTo.Console(theme: AnsiConsoleTheme.Sixteen)
|
||||
.CreateLogger();
|
||||
|
||||
var config = new ConfigurationBuilder().AddConfiguration().Build().Get<Config>();
|
||||
if (config == null)
|
||||
{
|
||||
Log.Fatal("No configuration object was created");
|
||||
return;
|
||||
}
|
||||
|
||||
var db = new DatabaseContext(config, null);
|
||||
await db.Database.MigrateAsync();
|
||||
|
||||
var type = args[0].ToLowerInvariant();
|
||||
var file = args[1];
|
||||
|
||||
if (type == "guilds")
|
||||
{
|
||||
Log.Information("Importing guilds from {File}", file);
|
||||
await GuildImport.DoImportAsync(db, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue