mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-12 10:18:27 -04:00
Restructured the project structure back to the way it was, there's no reasonable way to split the modules
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
#nullable disable
|
||||
using System.Globalization;
|
||||
using CsvHelper;
|
||||
using CsvHelper.Configuration;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
|
||||
#if !GLOBAL_NADEKO
|
||||
namespace NadekoBot.Modules.Administration
|
||||
{
|
||||
public partial class Administration
|
||||
{
|
||||
[Group]
|
||||
[OwnerOnly]
|
||||
public partial class DangerousCommands : NadekoModule<DangerousCommandsService>
|
||||
{
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public Task SqlSelect([Leftover] string sql)
|
||||
{
|
||||
var result = _service.SelectSql(sql);
|
||||
|
||||
return ctx.SendPaginatedConfirmAsync(0,
|
||||
cur =>
|
||||
{
|
||||
var items = result.Results.Skip(cur * 20).Take(20).ToList();
|
||||
|
||||
if (!items.Any())
|
||||
return _eb.Create().WithErrorColor().WithFooter(sql).WithDescription("-");
|
||||
|
||||
return _eb.Create()
|
||||
.WithOkColor()
|
||||
.WithFooter(sql)
|
||||
.WithTitle(string.Join(" ║ ", result.ColumnNames))
|
||||
.WithDescription(string.Join('\n', items.Select(x => string.Join(" ║ ", x))));
|
||||
},
|
||||
result.Results.Count,
|
||||
20);
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task SqlSelectCsv([Leftover] string sql)
|
||||
{
|
||||
var result = _service.SelectSql(sql);
|
||||
|
||||
// create a file stream and write the data as csv
|
||||
using var ms = new MemoryStream();
|
||||
await using var sw = new StreamWriter(ms);
|
||||
await using var csv = new CsvWriter(sw,
|
||||
new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = "," });
|
||||
|
||||
foreach (var cn in result.ColumnNames)
|
||||
{
|
||||
csv.WriteField(cn);
|
||||
}
|
||||
|
||||
await csv.NextRecordAsync();
|
||||
|
||||
foreach (var row in result.Results)
|
||||
{
|
||||
foreach (var field in row)
|
||||
{
|
||||
csv.WriteField(field);
|
||||
}
|
||||
|
||||
await csv.NextRecordAsync();
|
||||
}
|
||||
|
||||
|
||||
await csv.FlushAsync();
|
||||
ms.Position = 0;
|
||||
|
||||
// send the file
|
||||
await ctx.Channel.SendFileAsync(ms, $"query_result_{DateTime.UtcNow.Ticks}.csv");
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task SqlExec([Leftover] string sql)
|
||||
{
|
||||
try
|
||||
{
|
||||
var embed = _eb.Create()
|
||||
.WithTitle(GetText(strs.sql_confirm_exec))
|
||||
.WithDescription(Format.Code(sql));
|
||||
|
||||
if (!await PromptUserConfirmAsync(embed))
|
||||
return;
|
||||
|
||||
var res = await _service.ExecuteSql(sql);
|
||||
await SendConfirmAsync(res.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await SendErrorAsync(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async Task PurgeUser(ulong userId)
|
||||
{
|
||||
var embed = _eb.Create()
|
||||
.WithDescription(GetText(strs.purge_user_confirm(Format.Bold(userId.ToString()))));
|
||||
|
||||
if (!await PromptUserConfirmAsync(embed))
|
||||
return;
|
||||
|
||||
await _service.PurgeUserAsync(userId);
|
||||
await ctx.OkAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public Task PurgeUser([Leftover] IUser user)
|
||||
=> PurgeUser(user.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,104 @@
|
||||
#nullable disable
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Db.Models;
|
||||
using Nadeko.Bot.Db.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
||||
public class DangerousCommandsService : INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
|
||||
public DangerousCommandsService(DbService db)
|
||||
=> _db = db;
|
||||
|
||||
public async Task<int> ExecuteSql(string sql)
|
||||
{
|
||||
int res;
|
||||
await using var uow = _db.GetDbContext();
|
||||
res = await uow.Database.ExecuteSqlRawAsync(sql);
|
||||
return res;
|
||||
}
|
||||
|
||||
public SelectResult SelectSql(string sql)
|
||||
{
|
||||
var result = new SelectResult
|
||||
{
|
||||
ColumnNames = new(),
|
||||
Results = new()
|
||||
};
|
||||
|
||||
using var uow = _db.GetDbContext();
|
||||
var conn = uow.Database.GetDbConnection();
|
||||
conn.Open();
|
||||
using var cmd = conn.CreateCommand();
|
||||
cmd.CommandText = sql;
|
||||
using var reader = cmd.ExecuteReader();
|
||||
if (reader.HasRows)
|
||||
{
|
||||
for (var i = 0; i < reader.FieldCount; i++)
|
||||
result.ColumnNames.Add(reader.GetName(i));
|
||||
while (reader.Read())
|
||||
{
|
||||
var obj = new object[reader.FieldCount];
|
||||
reader.GetValues(obj);
|
||||
result.Results.Add(obj.Select(x => x.ToString()).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task PurgeUserAsync(ulong userId)
|
||||
{
|
||||
await using var uow = _db.GetDbContext();
|
||||
|
||||
// get waifu info
|
||||
var wi = await uow.Set<WaifuInfo>().FirstOrDefaultAsyncEF(x => x.Waifu.UserId == userId);
|
||||
|
||||
// if it exists, delete waifu related things
|
||||
if (wi is not null)
|
||||
{
|
||||
// remove updates which have new or old as this waifu
|
||||
await uow.Set<WaifuUpdate>().DeleteAsync(wu => wu.New.UserId == userId || wu.Old.UserId == userId);
|
||||
|
||||
// delete all items this waifu owns
|
||||
await uow.Set<WaifuItem>().DeleteAsync(x => x.WaifuInfoId == wi.Id);
|
||||
|
||||
// all waifus this waifu claims are released
|
||||
await uow.Set<WaifuInfo>()
|
||||
.AsQueryable()
|
||||
.Where(x => x.Claimer.UserId == userId)
|
||||
.UpdateAsync(x => new()
|
||||
{
|
||||
ClaimerId = null
|
||||
});
|
||||
|
||||
// all affinities set to this waifu are reset
|
||||
await uow.Set<WaifuInfo>()
|
||||
.AsQueryable()
|
||||
.Where(x => x.Affinity.UserId == userId)
|
||||
.UpdateAsync(x => new()
|
||||
{
|
||||
AffinityId = null
|
||||
});
|
||||
}
|
||||
|
||||
// delete guild xp
|
||||
await uow.Set<UserXpStats>().DeleteAsync(x => x.UserId == userId);
|
||||
|
||||
// delete currency transactions
|
||||
await uow.Set<CurrencyTransaction>().DeleteAsync(x => x.UserId == userId);
|
||||
|
||||
// delete user, currency, and clubs go away with it
|
||||
await uow.Set<DiscordUser>().DeleteAsync(u => u.UserId == userId);
|
||||
}
|
||||
|
||||
public class SelectResult
|
||||
{
|
||||
public List<string> ColumnNames { get; set; }
|
||||
public List<string[]> Results { get; set; }
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user