Add ShowModLogs command

This commit is contained in:
Noi 2022-10-05 12:40:53 -07:00
parent c25808716b
commit 8cbeb09017
3 changed files with 102 additions and 9 deletions

View file

@ -70,14 +70,7 @@ public static class Utilities {
/// Builds and returns an embed which displays this log entry. /// Builds and returns an embed which displays this log entry.
/// </summary> /// </summary>
public static Embed BuildEmbed(this Data.ModLogEntry entry, RegexbotClient bot) { public static Embed BuildEmbed(this Data.ModLogEntry entry, RegexbotClient bot) {
string? issuedDisplay = null; var issuedDisplay = TryFromEntityNameString(entry.IssuedBy, bot);
try {
var entityTry = new EntityName(entry.IssuedBy, EntityType.User);
var issueq = bot.EcQueryUser(entityTry.Id!.Value.ToString());
if (issueq != null) issuedDisplay = $"<@{issueq.UserId}> - {issueq.Username}#{issueq.Discriminator} `{issueq.UserId}`";
else issuedDisplay = $"Unknown user with ID `{entityTry.Id!.Value}`";
} catch (Exception) { }
issuedDisplay ??= entry.IssuedBy;
string targetDisplay; string targetDisplay;
var targetq = bot.EcQueryUser(entry.UserId.ToString()); var targetq = bot.EcQueryUser(entry.UserId.ToString());
if (targetq != null) targetDisplay = $"<@{targetq.UserId}> - {targetq.Username}#{targetq.Discriminator} `{targetq.UserId}`"; if (targetq != null) targetDisplay = $"<@{targetq.UserId}> - {targetq.Username}#{targetq.Discriminator} `{targetq.UserId}`";
@ -107,4 +100,20 @@ public static class Utilities {
/// Returns a representation of this entity that can be parsed by the <seealso cref="EntityName"/> constructor. /// Returns a representation of this entity that can be parsed by the <seealso cref="EntityName"/> constructor.
/// </summary> /// </summary>
public static string AsEntityNameString(this IUser entity) => $"@{entity.Id}::{entity.Username}"; public static string AsEntityNameString(this IUser entity) => $"@{entity.Id}::{entity.Username}";
/// <summary>
/// If given string is in an EntityName format, returns a displayable representation of it based on
/// a cache query. Otherwise, returns the input string as-is.
/// </summary>
[return: NotNullIfNotNull("input")]
public static string? TryFromEntityNameString(string? input, RegexbotClient bot) {
string? result = null;
try {
var entityTry = new EntityName(input!, EntityType.User);
var issueq = bot.EcQueryUser(entityTry.Id!.Value.ToString());
if (issueq != null) result = $"<@{issueq.UserId}> - {issueq.Username}#{issueq.Discriminator} `{issueq.UserId}`";
else result = $"Unknown user with ID `{entityTry.Id!.Value}`";
} catch (Exception) { }
return result ?? input;
}
} }

View file

@ -0,0 +1,82 @@
using Discord;
using Microsoft.EntityFrameworkCore;
using RegexBot.Common;
using RegexBot.Data;
namespace RegexBot.Modules.ModCommands.Commands;
class ShowModLogs : CommandConfig {
const int LogEntriesPerMessage = 10;
private readonly string _usage;
protected override string DefaultUsageMsg => _usage;
// No configuration.
// TODO bring in some options from BanKick. Particularly custom success msg.
// TODO when ModLogs fully implemented, add a reason?
public ShowModLogs(ModCommands module, JObject config) : base(module, config) {
_usage = $"{Command} `user or user ID` [page]\n"
+ "Retrieves moderation log entries regarding the specified user.";
}
// Usage: (command) (query) [page]
public override async Task Invoke(SocketGuild g, SocketMessage msg) {
var line = msg.Content.Split(new char[] { ' ' }, 3, StringSplitOptions.RemoveEmptyEntries);
if (line.Length < 2) {
await SendUsageMessageAsync(msg.Channel, null);
return;
}
int pagenum;
if (line.Length == 3) {
const string PageNumError = ":x: Requested page must be a non-negative number.";
if (!int.TryParse(line[2], out pagenum)) {
await SendUsageMessageAsync(msg.Channel, PageNumError);
}
if (pagenum <= 0) await SendUsageMessageAsync(msg.Channel, PageNumError);
} else pagenum = 1;
var query = Module.Bot.EcQueryGuildUser(g.Id, line[1]);
if (query == null) {
await msg.Channel.SendMessageAsync(":x: Unable to find the given user.");
return;
}
int totalPages;
List<ModLogEntry> results;
using (var db = new BotDatabaseContext()) {
var totalEntries = db.ModLogs
.Where(l => l.GuildId == query.GuildId && l.UserId == query.UserId)
.Count();
totalPages = (int)Math.Ceiling((double)totalEntries / LogEntriesPerMessage);
results = db.ModLogs
.Where(l => l.GuildId == query.GuildId && l.UserId == query.UserId)
.OrderByDescending(l => l.LogId)
.Skip((pagenum - 1) * LogEntriesPerMessage)
.Take(LogEntriesPerMessage)
.AsNoTracking()
.ToList();
}
var resultList = new EmbedBuilder() {
Author = new EmbedAuthorBuilder() {
Name = $"{query.User.Username}#{query.User.Discriminator}",
IconUrl = query.User.AvatarUrl
},
Footer = new EmbedFooterBuilder() {
Text = $"Page {pagenum} of {totalPages}",
IconUrl = Module.Bot.DiscordClient.CurrentUser.GetAvatarUrl()
},
Title = "Moderation logs"
};
foreach (var item in results) {
var f = new EmbedFieldBuilder() {
Name = $"{Enum.GetName(item.LogType)} \\#{item.LogId}",
Value = $"**Timestamp**: <t:{item.Timestamp.ToUnixTimeSeconds()}:f>\n"
+ $"**Issued by**: {Utilities.TryFromEntityNameString(item.IssuedBy, Module.Bot)}\n"
+ $"**Message**: {item.Message ?? "*none specified*"}"
};
resultList.AddField(f);
}
await msg.Channel.SendMessageAsync(embed: resultList.Build());
}
}

View file

@ -41,7 +41,9 @@ class ModuleConfig {
{ "addrole", typeof(RoleAdd) }, { "addrole", typeof(RoleAdd) },
{ "roleadd", typeof(RoleAdd) }, { "roleadd", typeof(RoleAdd) },
{ "delrole", typeof(RoleDel) }, { "delrole", typeof(RoleDel) },
{ "roledel", typeof(RoleDel) } { "roledel", typeof(RoleDel) },
{ "modlogs", typeof(ShowModLogs) },
{ "showmodlogs", typeof(ShowModLogs) }
} }
); );