Reorganized code and files
This commit is contained in:
parent
666e5406ca
commit
5339701bef
6 changed files with 149 additions and 134 deletions
|
@ -1,22 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Noikoio.RegexBot.Module.ModLogs
|
|
||||||
{
|
|
||||||
// Types of non-custom events that can be referenced by ModLogs in configuration.
|
|
||||||
// Enum value names will show themselves to the user in the form of strings valid in configuration,
|
|
||||||
// so try not to change those without good reason.
|
|
||||||
[Flags]
|
|
||||||
enum EventType
|
|
||||||
{
|
|
||||||
None = 0x0,
|
|
||||||
Note = 0x1,
|
|
||||||
Warn = 0x2,
|
|
||||||
Kick = 0x4,
|
|
||||||
Ban = 0x8,
|
|
||||||
JoinGuild = 0x10,
|
|
||||||
LeaveGuild = 0x20,
|
|
||||||
NameChange = 0x40,
|
|
||||||
MsgEdit = 0x80,
|
|
||||||
MsgDelete = 0x100
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,13 +5,13 @@ using System;
|
||||||
namespace Noikoio.RegexBot.Module.ModLogs
|
namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ModLogs guild-specific configuration values.
|
/// ModLogs guild-specific values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class GuildConfig
|
class GuildState
|
||||||
{
|
{
|
||||||
// Event reporting
|
// Event reporting
|
||||||
private readonly EntityName _rptTarget;
|
private readonly EntityName _rptTarget;
|
||||||
private EventType _rptTypes;
|
private LogEntry.LogType _rptTypes;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Target reporting channel.
|
/// Target reporting channel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -19,12 +19,12 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event types to send to the reporting channel.
|
/// Event types to send to the reporting channel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EventType RptTypes => _rptTypes;
|
public LogEntry.LogType RptTypes => _rptTypes;
|
||||||
|
|
||||||
// Query command
|
// Query command
|
||||||
private readonly string _qCmd; // command name
|
private readonly string _qCmd; // command name
|
||||||
private readonly EntityList _qAccess; // list of those able to issue the command
|
private readonly EntityList _qAccess; // list of those able to issue the command
|
||||||
private readonly EventType _qDefaultAnswer; // default entry types to display
|
private readonly LogEntry.LogType _qDefaultAnswer; // default entry types to display
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Query command. The first word in an incoming message, including prefix, that triggers a query.
|
/// Query command. The first word in an incoming message, including prefix, that triggers a query.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -37,16 +37,16 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event types to display in a query.
|
/// Event types to display in a query.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EventType QrTypes => _qDefaultAnswer;
|
public LogEntry.LogType QrTypes => _qDefaultAnswer;
|
||||||
|
|
||||||
public GuildConfig(JObject cfgRoot)
|
public GuildState(JObject cfgRoot)
|
||||||
{
|
{
|
||||||
// AutoReporting settings
|
// AutoReporting settings
|
||||||
var arcfg = cfgRoot["AutoReporting"];
|
var arcfg = cfgRoot["AutoReporting"];
|
||||||
if (arcfg == null)
|
if (arcfg == null)
|
||||||
{
|
{
|
||||||
_rptTarget = default(EntityName); // NOTE: Change this if EntityName becomes a class later
|
_rptTarget = default(EntityName); // NOTE: Change this if EntityName becomes a class later
|
||||||
_rptTypes = EventType.None;
|
_rptTypes = LogEntry.LogType.None;
|
||||||
}
|
}
|
||||||
else if (arcfg.Type == JTokenType.Object)
|
else if (arcfg.Type == JTokenType.Object)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,14 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
|
|
||||||
// TODO make optional
|
// TODO make optional
|
||||||
string rpval = arcfg["Events"]?.Value<string>();
|
string rpval = arcfg["Events"]?.Value<string>();
|
||||||
_rptTypes = GetTypesFromString(rpval);
|
try
|
||||||
|
{
|
||||||
|
_rptTypes = LogEntry.GetLogTypeFromString(rpval);
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
throw new RuleImportException(ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -74,7 +81,7 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
{
|
{
|
||||||
_qCmd = null;
|
_qCmd = null;
|
||||||
_qAccess = null;
|
_qAccess = null;
|
||||||
_qDefaultAnswer = EventType.None;
|
_qDefaultAnswer = LogEntry.LogType.None;
|
||||||
}
|
}
|
||||||
else if (arcfg.Type == JTokenType.Object)
|
else if (arcfg.Type == JTokenType.Object)
|
||||||
{
|
{
|
||||||
|
@ -90,38 +97,20 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
|
|
||||||
// TODO make optional
|
// TODO make optional
|
||||||
string ansval = arcfg["DefaultEvents"]?.Value<string>();
|
string ansval = arcfg["DefaultEvents"]?.Value<string>();
|
||||||
_qDefaultAnswer = GetTypesFromString(ansval);
|
try
|
||||||
|
{
|
||||||
|
_qDefaultAnswer = LogEntry.GetLogTypeFromString(ansval);
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
throw new RuleImportException(ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new RuleImportException("Section for QueryCommand is not correctly defined.");
|
throw new RuleImportException("Section for QueryCommand is not correctly defined.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EventType GetTypesFromString(string input)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(input))
|
|
||||||
throw new RuleImportException("Types are not properly defined.");
|
|
||||||
|
|
||||||
var strTypes = input.Split(
|
|
||||||
new char[] { ' ', ',', '/', '+' }, // and more?
|
|
||||||
StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
EventType endResult = EventType.None;
|
|
||||||
foreach (var item in strTypes)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var result = Enum.Parse<EventType>(item, true);
|
|
||||||
endResult |= result;
|
|
||||||
}
|
|
||||||
catch (ArgumentException)
|
|
||||||
{
|
|
||||||
throw new RuleImportException($"Unable to determine the given event type \"{item}\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return endResult;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
using Npgsql;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Noikoio.RegexBot.Module.ModLogs
|
namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
|
@ -10,7 +8,7 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a log entry in the database.
|
/// Represents a log entry in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Entry
|
class LogEntry
|
||||||
{
|
{
|
||||||
readonly int _logId;
|
readonly int _logId;
|
||||||
readonly DateTime _ts;
|
readonly DateTime _ts;
|
||||||
|
@ -18,7 +16,7 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
readonly ulong? _invokeId;
|
readonly ulong? _invokeId;
|
||||||
readonly ulong _targetId;
|
readonly ulong _targetId;
|
||||||
readonly ulong? _channelId;
|
readonly ulong? _channelId;
|
||||||
readonly string _type;
|
readonly LogType _type;
|
||||||
readonly string _message;
|
readonly string _message;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -47,15 +45,15 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong? TargetChannel => _channelId;
|
public ulong? TargetChannel => _channelId;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets this log entry's category.
|
/// Gets this log entry's type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Category => _type;
|
public LogType Type => _type;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content of this log entry.
|
/// Gets the content of this log entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Message => _message;
|
public string Message => _message;
|
||||||
|
|
||||||
public Entry(DbDataReader r)
|
public LogEntry(DbDataReader r)
|
||||||
{
|
{
|
||||||
// Double-check ordinals if making changes to QueryColumns
|
// Double-check ordinals if making changes to QueryColumns
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
if (r.IsDBNull(5)) _channelId = null;
|
if (r.IsDBNull(5)) _channelId = null;
|
||||||
else _channelId = (ulong)r.GetInt64(5);
|
else _channelId = (ulong)r.GetInt64(5);
|
||||||
}
|
}
|
||||||
_type = r.GetString(6);
|
_type = (LogType)r.GetInt32(6);
|
||||||
_message = r.GetString(7);
|
_message = r.GetString(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,40 +77,128 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
|
|
||||||
// TODO figure out some helper methods to retrieve data of other entities by ID, if it becomes necessary
|
// TODO figure out some helper methods to retrieve data of other entities by ID, if it becomes necessary
|
||||||
|
|
||||||
#region Queries
|
#region Log entry types
|
||||||
|
/// <summary>
|
||||||
|
/// Enumeration of all possible event flags. Names will show themselves to users
|
||||||
|
/// and associated values will be saved to the databaase.
|
||||||
|
/// Once they're included in a release build, they should never be changed again.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum LogType
|
||||||
|
{
|
||||||
|
/// <summary>Should only be useful in GuildState and ignored elsewhere.</summary>
|
||||||
|
None = 0x0,
|
||||||
|
Note = 0x1,
|
||||||
|
Warn = 0x2,
|
||||||
|
Kick = 0x4,
|
||||||
|
Ban = 0x8,
|
||||||
|
/// <summary>Record of a user joining a guild.</summary>
|
||||||
|
JoinGuild = 0x10,
|
||||||
|
/// <summary>Record of a user leaving a guild, voluntarily or by force (kick, ban).</summary>
|
||||||
|
LeaveGuild = 0x20,
|
||||||
|
NameChange = 0x40,
|
||||||
|
/// <summary>Not a database entry, but exists for MessageCache configuration.</summary>
|
||||||
|
MsgEdit = 0x80,
|
||||||
|
/// <summary>Not a database entry, but exists for MessageCache configuration.</summary>
|
||||||
|
MsgDelete = 0x100
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LogType GetLogTypeFromString(string input)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(input))
|
||||||
|
throw new ArgumentException("Types are not properly defined.");
|
||||||
|
|
||||||
|
var strTypes = input.Split(
|
||||||
|
new char[] { ' ', ',', '/', '+' }, // and more?
|
||||||
|
StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
LogType endResult = LogType.None;
|
||||||
|
foreach (var item in strTypes)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var result = Enum.Parse<LogType>(item, true);
|
||||||
|
endResult |= result;
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Unable to determine the given event type \"{item}\".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return endResult;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region SQL setup and querying
|
||||||
|
public const string TblEntry = "modlogs_entries";
|
||||||
|
public const string TblEntryIncr = TblEntry + "_id";
|
||||||
|
|
||||||
|
internal static void CreateTables()
|
||||||
|
{
|
||||||
|
using (var db = RegexBot.Config.GetOpenDatabaseConnectionAsync().GetAwaiter().GetResult())
|
||||||
|
{
|
||||||
|
using (var c = db.CreateCommand())
|
||||||
|
{
|
||||||
|
c.CommandText = "CREATE TABLE IF NOT EXISTS " + TblEntry + " ("
|
||||||
|
+ "id int primary key, "
|
||||||
|
+ "entry_ts timestamptz not null, "
|
||||||
|
+ "guild_id bigint not null, "
|
||||||
|
+ "target_id bigint not null, "
|
||||||
|
+ $"invoke_id bigint null references {EntityCache.SqlHelper.TableUser}.user_id, "
|
||||||
|
+ "target_channel_id bigint null, " // TODO channel cache reference?
|
||||||
|
+ "entry_type integer not null, "
|
||||||
|
+ "message text not null, "
|
||||||
|
+ $"FOREIGN KEY (target_id, guild_id) REFERENCES {EntityCache.SqlHelper.TableUser} (user_id, guild_id)";
|
||||||
|
c.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
using (var c = db.CreateCommand())
|
||||||
|
{
|
||||||
|
c.CommandText = $"CREATE SEQUENCE IF NOT EXISTS {TblEntryIncr} "
|
||||||
|
+ $"START 1000 MAXVALUE {int.MaxValue}";
|
||||||
|
c.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Double-check constructor if making changes to this constant
|
// Double-check constructor if making changes to this constant
|
||||||
const string QueryColumns = "id, entry_ts, guild_id, target_id, invoke_id, target_channel_id, category, message";
|
const string QueryColumns = "id, entry_ts, guild_id, target_id, invoke_id, target_channel_id, entry_type, message";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to look up a log entry with the given ID.
|
/// Attempts to look up a log entry by its ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Null if no result.</returns>
|
/// <returns>Null if no result.</returns>
|
||||||
public static async Task<Entry> QueryIdAsync(ulong guild, int id)
|
public static async Task<LogEntry> QueryIdAsync(ulong guild, int id)
|
||||||
{
|
{
|
||||||
using (var db = await RegexBot.Config.GetOpenDatabaseConnectionAsync())
|
using (var db = await RegexBot.Config.GetOpenDatabaseConnectionAsync())
|
||||||
{
|
{
|
||||||
using (var c = db.CreateCommand())
|
using (var c = db.CreateCommand())
|
||||||
{
|
{
|
||||||
c.CommandText = $"SELECT {QueryColumns} FROM {Sql.TableLog} "
|
c.CommandText = $"SELECT {QueryColumns} FROM {TblEntry} "
|
||||||
+ "WHERE guild_id = @Guild and id = @Id";
|
+ "WHERE guild_id = @Guild and id = @Id";
|
||||||
c.Parameters.Add("@Guild", NpgsqlTypes.NpgsqlDbType.Bigint).Value = guild;
|
c.Parameters.Add("@Guild", NpgsqlTypes.NpgsqlDbType.Bigint).Value = guild;
|
||||||
c.Parameters.Add("@Id", NpgsqlTypes.NpgsqlDbType.Numeric).Value = id;
|
c.Parameters.Add("@Id", NpgsqlTypes.NpgsqlDbType.Numeric).Value = id;
|
||||||
c.Prepare();
|
c.Prepare();
|
||||||
using (var r = await c.ExecuteReaderAsync())
|
using (var r = await c.ExecuteReaderAsync())
|
||||||
{
|
{
|
||||||
if (r.Read()) return new Entry(r);
|
if (r.Read()) return new LogEntry(r);
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IEnumerable<Entry>> QueryLogAsync
|
/// <summary>
|
||||||
|
/// Attempts to look up a log entry by a number of parameters.
|
||||||
|
/// At least "target" or "invoker" are required when calling this method.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<IEnumerable<LogEntry>> QueryLogAsync
|
||||||
(ulong guild,
|
(ulong guild,
|
||||||
ulong? target = null,
|
ulong? target = null,
|
||||||
ulong? invoker = null,
|
ulong? invoker = null,
|
||||||
ulong? channel = null,
|
ulong? channel = null,
|
||||||
IEnumerable<string> category = null)
|
LogType? category = null)
|
||||||
{
|
{
|
||||||
// Enforce some limits - can't search too broadly here. Requires this at a minimum:
|
// Enforce some limits - can't search too broadly here. Requires this at a minimum:
|
||||||
if (target.HasValue == false && invoker.HasValue == false)
|
if (target.HasValue == false && invoker.HasValue == false)
|
||||||
|
@ -120,12 +206,12 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
throw new ArgumentNullException("Query requires at minimum searching of a target or invoker.");
|
throw new ArgumentNullException("Query requires at minimum searching of a target or invoker.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = new List<Entry>();
|
var result = new List<LogEntry>();
|
||||||
using (var db = await RegexBot.Config.GetOpenDatabaseConnectionAsync())
|
using (var db = await RegexBot.Config.GetOpenDatabaseConnectionAsync())
|
||||||
{
|
{
|
||||||
using (var c = db.CreateCommand())
|
using (var c = db.CreateCommand())
|
||||||
{
|
{
|
||||||
c.CommandText = $"SELECT {QueryColumns} FROM {Sql.TableLog} WHERE";
|
c.CommandText = $"SELECT {QueryColumns} FROM {TblEntry} WHERE";
|
||||||
|
|
||||||
bool and = false;
|
bool and = false;
|
||||||
if (target.HasValue)
|
if (target.HasValue)
|
||||||
|
@ -149,13 +235,20 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
c.CommandText += " target_channel_id = @ChannelId";
|
c.CommandText += " target_channel_id = @ChannelId";
|
||||||
c.Parameters.Add("@ChannelId", NpgsqlTypes.NpgsqlDbType.Bigint).Value = channel.Value;
|
c.Parameters.Add("@ChannelId", NpgsqlTypes.NpgsqlDbType.Bigint).Value = channel.Value;
|
||||||
}
|
}
|
||||||
|
if (category.HasValue)
|
||||||
|
{
|
||||||
|
if (and) c.CommandText += " AND";
|
||||||
|
else and = true;
|
||||||
|
c.CommandText += " entry_type = @Category";
|
||||||
|
c.Parameters.Add("@Category", NpgsqlTypes.NpgsqlDbType.Integer).Value = (int)category;
|
||||||
|
}
|
||||||
c.Prepare();
|
c.Prepare();
|
||||||
|
|
||||||
using (var r = await c.ExecuteReaderAsync())
|
using (var r = await c.ExecuteReaderAsync())
|
||||||
{
|
{
|
||||||
while (r.Read())
|
while (r.Read())
|
||||||
{
|
{
|
||||||
result.Add(new Entry(r));
|
result.Add(new LogEntry(r));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,11 +17,11 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _dClient;
|
private readonly DiscordSocketClient _dClient;
|
||||||
private readonly AsyncLogger _outLog;
|
private readonly AsyncLogger _outLog;
|
||||||
private readonly Func<ulong, GuildConfig> _outGetConfig;
|
private readonly Func<ulong, GuildState> _outGetConfig;
|
||||||
|
|
||||||
// TODO: How to clear the cache after a time? Can't hold on to this forever.
|
// TODO: How to clear the cache after a time? Can't hold on to this forever.
|
||||||
|
|
||||||
public MessageCache(DiscordSocketClient client, AsyncLogger logger, Func<ulong, GuildConfig> getConfFunc)
|
public MessageCache(DiscordSocketClient client, AsyncLogger logger, Func<ulong, GuildState> getConfFunc)
|
||||||
{
|
{
|
||||||
_dClient = client;
|
_dClient = client;
|
||||||
_outLog = logger;
|
_outLog = logger;
|
||||||
|
@ -87,8 +87,8 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
// Check if this feature is enabled before doing anything else.
|
// Check if this feature is enabled before doing anything else.
|
||||||
var cfg = _outGetConfig(guildId);
|
var cfg = _outGetConfig(guildId);
|
||||||
if (cfg == null) return;
|
if (cfg == null) return;
|
||||||
if (isDelete && (cfg.RptTypes & EventType.MsgDelete) == 0) return;
|
if (isDelete && (cfg.RptTypes & LogEntry.LogType.MsgDelete) == 0) return;
|
||||||
if (!isDelete && (cfg.RptTypes & EventType.MsgEdit) == 0) return;
|
if (!isDelete && (cfg.RptTypes & LogEntry.LogType.MsgEdit) == 0) return;
|
||||||
|
|
||||||
// Ignore if it's a message being deleted withing the reporting channel.
|
// Ignore if it's a message being deleted withing the reporting channel.
|
||||||
if (isDelete && cfg.RptTarget.Value.Id.Value == ch.Id) return;
|
if (isDelete && cfg.RptTarget.Value.Id.Value == ch.Id) return;
|
||||||
|
@ -122,7 +122,7 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userId != 0) ucd = await EntityCache.EntityCache.QueryAsync(guildId, userId);
|
if (userId != 0) ucd = await EntityCache.EntityCache.QueryUserAsync(guildId, userId);
|
||||||
}
|
}
|
||||||
catch (NpgsqlException ex)
|
catch (NpgsqlException ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,9 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
if (!RegexBot.Config.DatabaseAvailable) return;
|
if (!RegexBot.Config.DatabaseAvailable) return;
|
||||||
|
|
||||||
// MessageCache (reporting of MessageEdit, MessageDelete) handled by helper class
|
// MessageCache (reporting of MessageEdit, MessageDelete) handled by helper class
|
||||||
_msgCacheInstance = new MessageCache(client, Log, delegate (ulong id) { return GetState<GuildConfig>(id); });
|
_msgCacheInstance = new MessageCache(client, Log, delegate (ulong id) { return GetState<GuildState>(id); });
|
||||||
|
|
||||||
|
LogEntry.CreateTables();
|
||||||
|
|
||||||
// TODO add handlers for detecting joins, leaves, bans, kicks, user edits (nick/username/discr)
|
// TODO add handlers for detecting joins, leaves, bans, kicks, user edits (nick/username/discr)
|
||||||
// TODO add handler for processing the log query command
|
// TODO add handler for processing the log query command
|
||||||
|
@ -37,8 +39,8 @@ namespace Noikoio.RegexBot.Module.ModLogs
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var conf = new GuildConfig((JObject)configSection);
|
var conf = new GuildState((JObject)configSection);
|
||||||
if (conf.RptTypes != EventType.None)
|
if (conf.RptTypes != LogEntry.LogType.None)
|
||||||
await Log("Enabled event autoreporting to " + conf.RptTarget);
|
await Log("Enabled event autoreporting to " + conf.RptTarget);
|
||||||
|
|
||||||
return conf;
|
return conf;
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Noikoio.RegexBot.Module.ModLogs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Contains common constants and static methods used for accessing the log database.
|
|
||||||
/// </summary>
|
|
||||||
class Sql
|
|
||||||
{
|
|
||||||
public const string TableLog = "modlogs_entries";
|
|
||||||
public const string TableLogIncr = TableLog + "_id";
|
|
||||||
public const string TableMsgCache = "modlogs_msgcache";
|
|
||||||
|
|
||||||
static void CreateTables()
|
|
||||||
{
|
|
||||||
using (var db = RegexBot.Config.GetOpenDatabaseConnectionAsync().GetAwaiter().GetResult())
|
|
||||||
{
|
|
||||||
using (var c = db.CreateCommand())
|
|
||||||
{
|
|
||||||
c.CommandText = "CREATE TABLE IF NOT EXISTS " + TableLog + " ("
|
|
||||||
+ "id int primary key, "
|
|
||||||
+ "entry_ts timestamptz not null, "
|
|
||||||
+ "guild_id bigint not null, "
|
|
||||||
+ "target_id bigint not null, "
|
|
||||||
+ $"invoke_id bigint null references {EntityCache.SqlHelper.TableUser}.user_id, "
|
|
||||||
+ "target_channel_id bigint null, " // TODO channel cache reference?
|
|
||||||
+ "category text not null, "
|
|
||||||
+ "message text not null, "
|
|
||||||
+ $"FOREIGN KEY (target_id, guild_id) REFERENCES {EntityCache.SqlHelper.TableUser} (user_id, guild_id)";
|
|
||||||
c.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
using (var c = db.CreateCommand())
|
|
||||||
{
|
|
||||||
c.CommandText = $"CREATE SEQUENCE IF NOT EXISTS {TableLogIncr} "
|
|
||||||
+ $"START 100 MAXVALUE {int.MaxValue}";
|
|
||||||
c.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Log entry manipulation
|
|
||||||
// what was I doing again
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue