DeukBot4/DeukBot4/MessageHandlers/CommandHandler/TagStorage.cs

259 lines
9.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DeukBot4.Database;
using DeukBot4.MessageHandlers.CommandHandler.RequestStructure;
using DeukBot4.MessageHandlers.Permissions;
using DeukBot4.Utilities;
using Discord;
using Npgsql;
namespace DeukBot4.MessageHandlers.CommandHandler
{
public static class TagStorage
{
public class ServerTags
{
private readonly Dictionary<string, string> Tags = new Dictionary<string, string>();
private ulong ServerId { get; set; }
public ServerTags(ulong serverId)
{
ServerId = serverId;
}
public ServerTags(ulong serverId, Dictionary<string, string> tags)
{
Tags = tags;
}
private static string CleanKey(string key)
{
return key.ToLowerInvariant();
}
public static readonly string[] ReservedTags = new[] {"create", "delete", "remove"};
public (bool success, string result) AddTag(string key, string value)
{
var parsedTag = CleanKey(key);
if (ReservedTags.Contains(parsedTag))
{
return (false, $"You can't use keyword {parsedTag}, that's a reserved tag");
}
if (Tags.ContainsKey(parsedTag))
{
return (false, "A tag with that name already exists");
}
Tags.Add(parsedTag, value);
using (var db = new DatabaseConnection())
{
using (var command = new NpgsqlCommand())
{
command.Connection = db;
command.CommandText = "INSERT INTO tags (server_id, key, value) VALUES (@id, @key, @value)";
command.Parameters.AddWithValue("@id", ServerId.ToLong());
command.Parameters.AddWithValue("@key", parsedTag);
command.Parameters.AddWithValue("@value", value);
command.ExecuteNonQuery();
}
}
return (true, "");
}
public (bool success, string result) RemoveTag(string key)
{
var parsedTag = CleanKey(key);
if (!Tags.ContainsKey(parsedTag))
{
return (false, "No tag with that name exists");
}
Tags.Remove(parsedTag);
using (var db = new DatabaseConnection())
{
using (var command = new NpgsqlCommand())
{
command.Connection = db;
command.CommandText = "DELETE FROM tags WHERE server_id = @id AND key = @key";
command.Parameters.AddWithValue("@id", ServerId.ToLong());
command.Parameters.AddWithValue("@key", parsedTag);
var res = command.ExecuteNonQuery();
}
}
return (true, "");
}
public string GetTag(string key)
{
var parsedTag = CleanKey(key);
if (!Tags.TryGetValue(parsedTag, out var value))
{
return "No tag by that name exists";
}
return value;
}
public List<string> TagList()
{
return Tags.Keys.OrderBy(x => x).ToList();
}
}
private static readonly Dictionary<ulong, ServerTags> ServerCache = new Dictionary<ulong, ServerTags>();
public static void BuildTags()
{
using (var conn = new DatabaseConnection())
{
using (var command = new NpgsqlCommand())
{
command.Connection = conn;
command.CommandText = "SELECT server_id, key, value FROM tags";
var reader = command.ExecuteReader();
var res = new Dictionary<ulong, Dictionary<string, string>>();
while (reader.Read())
{
var id = reader.GetInt64(0).ToUlong();
var key = reader.GetString(1);
var value = reader.GetString(2);
if (!res.TryGetValue(id, out var dic))
{
dic = new Dictionary<string, string>();
res.Add(id, dic);
}
dic.Add(key, value);
}
foreach (var dic in res)
{
ServerCache.Add(dic.Key, new ServerTags(dic.Key, dic.Value));
}
}
}
}
public static async Task AddTag(CommandRequest cmd)
{
var channel = cmd.OriginalMessage.Channel as IGuildChannel;
if (channel == null)
return;
var serverId = channel.GuildId;
if (!ServerCache.TryGetValue(serverId, out var serverTags))
{
serverTags = new ServerTags(serverId);
ServerCache.Add(serverId, serverTags);
}
var key = cmd.Parameters[0].AsString();
var value = cmd.Parameters[1].AsString();
var result = serverTags.AddTag(key, value);
if (!result.success)
{
cmd.SendSimpleEmbed("Tag Creation", "Something went wrong: " + result.result);
}
else
{
cmd.SendSimpleEmbed("Tag Creation","Success! Added tag with key: " + key);
}
}
public static async Task RemoveTag(CommandRequest cmd)
{
var channel = cmd.OriginalMessage.Channel as IGuildChannel;
if (channel == null)
return;
var serverId = channel.GuildId;
if (!ServerCache.TryGetValue(serverId, out var serverTags))
{
serverTags = new ServerTags(serverId);
ServerCache.Add(serverId, serverTags);
}
var key = cmd.Parameters[0].AsString();
var result = serverTags.RemoveTag(key);
if (!result.success)
{
cmd.SendSimpleEmbed("Tag Deletion","Something went wrong: " + result.result);
}
else
{
cmd.SendSimpleEmbed("Tag Deletion","Success! Removed tag with key: " + key);
}
}
public static async Task GetTag(CommandRequest cmd)
{
var channel = cmd.OriginalMessage.Channel as IGuildChannel;
if (channel == null)
return;
var serverId = channel.GuildId;
if (!ServerCache.TryGetValue(serverId, out var serverTags))
{
serverTags = new ServerTags(serverId);
ServerCache.Add(serverId, serverTags);
}
var split = cmd.Parameters[0].AsString().Split(" ");
var first = split[0].ToLowerInvariant();
if (first == "create")
{
var perms = await PermissionValidator.GetUserPermissionLevel(cmd.OriginalMessage);
if (perms < PermissionLevel.Helper)
return;
var keyword = split[1];
var rest = split.Skip(2).ToArray().Join(" ");
var result = serverTags.AddTag(keyword, rest);
if (!result.success)
{
cmd.SendSimpleEmbed("Tag Creation", "Something went wrong: " + result.result);
}
else
{
cmd.SendSimpleEmbed("Tag Creation","Success! Added tag with key: " + keyword);
}
return;
}
if (first == "remove" || first == "delete")
{
var perms = await PermissionValidator.GetUserPermissionLevel(cmd.OriginalMessage);
if (perms < PermissionLevel.Helper)
return;
var keyword = split[1];
var result = serverTags.RemoveTag(keyword);
if (!result.success)
{
cmd.SendSimpleEmbed("Tag Deletion","Something went wrong: " + result.result);
}
else
{
cmd.SendSimpleEmbed("Tag Deletion","Success! Removed tag with key: " + keyword);
}
return;
}
cmd.SendMessageAsync(serverTags.GetTag(first));
}
public static async Task GetTags(CommandRequest cmd)
{
var channel = cmd.OriginalMessage.Channel as IGuildChannel;
if (channel == null)
return;
var serverId = channel.GuildId;
if (!ServerCache.TryGetValue(serverId, out var serverTags))
{
return;
}
var tags = serverTags.TagList();
var eb = EmbedFactory.GetStandardEmbedBuilder();
eb.Title = "This Server Has The Following Tags";
eb.Description = tags.Join("\n");
cmd.OriginalMessage.Channel.SendMessageAsync("", embed: eb.Build());
}
}
}