diff --git a/Geekbot.net/Commands/Admin/Admin.cs b/Geekbot.net/Commands/Admin/Admin.cs index 15b4df1..9120971 100644 --- a/Geekbot.net/Commands/Admin/Admin.cs +++ b/Geekbot.net/Commands/Admin/Admin.cs @@ -1,15 +1,13 @@ using System; -using System.Linq; using System.Text; using System.Threading.Tasks; using Discord; using Discord.Commands; using Discord.WebSocket; -using Geekbot.net.Database; -using Geekbot.net.Database.Models; using Geekbot.net.Lib.CommandPreconditions; using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.Extensions; +using Geekbot.net.Lib.GuildSettingsManager; using Geekbot.net.Lib.Localization; namespace Geekbot.net.Commands.Admin @@ -21,15 +19,14 @@ namespace Geekbot.net.Commands.Admin { private readonly DiscordSocketClient _client; private readonly IErrorHandler _errorHandler; - private readonly DatabaseContext _database; + private readonly IGuildSettingsManager _guildSettingsManager; private readonly ITranslationHandler _translation; - public Admin(DatabaseContext database, DiscordSocketClient client, IErrorHandler errorHandler, - ITranslationHandler translationHandler) + public Admin(DiscordSocketClient client, IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager, ITranslationHandler translationHandler) { - _database = database; _client = client; _errorHandler = errorHandler; + _guildSettingsManager = guildSettingsManager; _translation = translationHandler; } @@ -37,11 +34,10 @@ namespace Geekbot.net.Commands.Admin [Summary("Set a Welcome Message (use '$user' to mention the new joined user).")] public async Task SetWelcomeMessage([Remainder, Summary("message")] string welcomeMessage) { - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.WelcomeMessage = welcomeMessage; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); - + await _guildSettingsManager.UpdateSettings(guild); + var formatedMessage = welcomeMessage.Replace("$user", Context.User.Mention); await ReplyAsync($"Welcome message has been changed\r\nHere is an example of how it would look:\r\n{formatedMessage}"); } @@ -54,13 +50,12 @@ namespace Geekbot.net.Commands.Admin { var m = await channel.SendMessageAsync("..."); - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.WelcomeChannel = channel.Id.AsLong(); - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); - + await _guildSettingsManager.UpdateSettings(guild); + await m.DeleteAsync(); - + await ReplyAsync("Successfully saved the welcome channel"); } catch (Exception e) @@ -68,7 +63,7 @@ namespace Geekbot.net.Commands.Admin await _errorHandler.HandleCommandException(e, Context, "That channel doesn't seem to exist or i don't have write permissions"); } } - + [Command("modchannel", RunMode = RunMode.Async)] [Summary("Set a channel for moderation purposes")] public async Task SelectModChannel([Summary("#Channel")] ISocketMessageChannel channel) @@ -77,11 +72,10 @@ namespace Geekbot.net.Commands.Admin { var m = await channel.SendMessageAsync("verifying..."); - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.ModChannel = channel.Id.AsLong(); - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); - + await _guildSettingsManager.UpdateSettings(guild); + var sb = new StringBuilder(); sb.AppendLine("Successfully saved mod channel, you can now do the following"); sb.AppendLine("- `!admin showleave` - send message to mod channel when someone leaves"); @@ -100,13 +94,12 @@ namespace Geekbot.net.Commands.Admin { try { - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); var modChannel = await GetModChannel(guild.ModChannel.AsUlong()); if (modChannel == null) return; - + guild.ShowLeave = !guild.ShowLeave; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); + await _guildSettingsManager.UpdateSettings(guild); await modChannel.SendMessageAsync(guild.ShowLeave ? "Saved - now sending messages here when someone leaves" : "Saved - stopping sending messages here when someone leaves" @@ -124,13 +117,12 @@ namespace Geekbot.net.Commands.Admin { try { - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); var modChannel = await GetModChannel(guild.ModChannel.AsUlong()); if (modChannel == null) return; - + guild.ShowDelete = !guild.ShowDelete; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); + await _guildSettingsManager.UpdateSettings(guild); await modChannel.SendMessageAsync(guild.ShowDelete ? "Saved - now sending messages here when someone deletes a message" : "Saved - stopping sending messages here when someone deletes a message" @@ -152,11 +144,10 @@ namespace Geekbot.net.Commands.Admin var success = await _translation.SetLanguage(Context.Guild.Id, language); if (success) { - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.Language = language; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); - + await _guildSettingsManager.UpdateSettings(guild); + var transContext = await _translation.GetGuildContext(Context); await ReplyAsync(transContext.GetString("NewLanguageSet")); return; @@ -170,7 +161,7 @@ namespace Geekbot.net.Commands.Admin await _errorHandler.HandleCommandException(e, Context); } } - + [Command("wiki", RunMode = RunMode.Async)] [Summary("Change the wikipedia instance (use lang code in xx.wikipedia.org)")] public async Task SetWikiLanguage([Summary("language")] string languageRaw) @@ -178,11 +169,10 @@ namespace Geekbot.net.Commands.Admin try { var language = languageRaw.ToLower(); - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.WikiLang = language; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); - + await _guildSettingsManager.UpdateSettings(guild); + await ReplyAsync($"Now using the {language} wikipedia"); } catch (Exception e) @@ -190,17 +180,16 @@ namespace Geekbot.net.Commands.Admin await _errorHandler.HandleCommandException(e, Context); } } - + [Command("ping", RunMode = RunMode.Async)] [Summary("Enable the ping reply.")] public async Task TogglePing() { try { - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.Ping = !guild.Ping; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); + await _guildSettingsManager.UpdateSettings(guild); await ReplyAsync(guild.Ping ? "i will reply to ping now" : "No more pongs..."); } catch (Exception e) @@ -208,17 +197,16 @@ namespace Geekbot.net.Commands.Admin await _errorHandler.HandleCommandException(e, Context); } } - + [Command("hui", RunMode = RunMode.Async)] [Summary("Enable the ping reply.")] public async Task ToggleHui() { try { - var guild = await GetGuildSettings(Context.Guild.Id); + var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); guild.Hui = !guild.Hui; - _database.GuildSettings.Update(guild); - await _database.SaveChangesAsync(); + await _guildSettingsManager.UpdateSettings(guild); await ReplyAsync(guild.Hui ? "i will reply to hui now" : "No more hui's..."); } catch (Exception e) @@ -227,41 +215,20 @@ namespace Geekbot.net.Commands.Admin } } - private async Task GetGuildSettings(ulong guildId) - { - var guild = _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong())); - if (guild != null) return guild; - Console.WriteLine("Adding non-exist Guild Settings to database"); - _database.GuildSettings.Add(new GuildSettingsModel() - { - GuildId = guildId.AsLong(), - Hui = false, - Ping = false, - Language = "EN", - ShowDelete = false, - ShowLeave = false, - WikiLang = "en" - }); - await _database.SaveChangesAsync(); - return _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong())); - } - private async Task GetModChannel(ulong channelId) { try { - if(channelId == ulong.MinValue) throw new Exception(); + if (channelId == ulong.MinValue) throw new Exception(); var modChannel = (ISocketMessageChannel) _client.GetChannel(channelId); - if(modChannel == null) throw new Exception(); + if (modChannel == null) throw new Exception(); return modChannel; } catch { - await ReplyAsync( - "Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`"); + await ReplyAsync("Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`"); return null; } } - } } \ No newline at end of file diff --git a/Geekbot.net/Handlers/CommandHandler.cs b/Geekbot.net/Handlers/CommandHandler.cs index 5074ff2..b811a8e 100644 --- a/Geekbot.net/Handlers/CommandHandler.cs +++ b/Geekbot.net/Handlers/CommandHandler.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Discord; using Discord.Commands; @@ -8,7 +7,7 @@ using Discord.Rest; using Discord.WebSocket; using Geekbot.net.Database; using Geekbot.net.Database.Models; -using Geekbot.net.Lib.Extensions; +using Geekbot.net.Lib.GuildSettingsManager; using Geekbot.net.Lib.Logger; namespace Geekbot.net.Handlers @@ -20,10 +19,12 @@ namespace Geekbot.net.Handlers private readonly IServiceProvider _servicesProvider; private readonly CommandService _commands; private readonly RestApplication _applicationInfo; + private readonly IGuildSettingsManager _guildSettingsManager; private readonly List _ignoredServers; private readonly DatabaseContext _database; - public CommandHandler(DatabaseContext database, IDiscordClient client, IGeekbotLogger logger, IServiceProvider servicesProvider, CommandService commands, RestApplication applicationInfo) + public CommandHandler(DatabaseContext database, IDiscordClient client, IGeekbotLogger logger, IServiceProvider servicesProvider, CommandService commands, RestApplication applicationInfo, + IGuildSettingsManager guildSettingsManager) { _database = database; _client = client; @@ -31,6 +32,7 @@ namespace Geekbot.net.Handlers _servicesProvider = servicesProvider; _commands = commands; _applicationInfo = applicationInfo; + _guildSettingsManager = guildSettingsManager; // Some guilds only want very specific functionally without any of the commands, a quick hack that solves that "short term" // ToDo: create a clean solution for this... @@ -68,14 +70,14 @@ namespace Geekbot.net.Handlers var argPos = 0; if (!IsCommand(message, ref argPos)) return Task.CompletedTask; - + ExecuteCommand(message, argPos); } catch (Exception e) { _logger.Error(LogSource.Geekbot, "Failed to Process Message", e); } - + return Task.CompletedTask; } @@ -102,7 +104,7 @@ namespace Geekbot.net.Handlers if (!lowerCaseMessage.StartsWith("ping ") && !lowerCaseMessage.Equals("ping")) return false; return GetGuildSettings(guildId)?.Ping ?? false; } - + private bool ShouldHui(string lowerCaseMessage, ulong guildId) { if (!lowerCaseMessage.StartsWith("hui")) return false; @@ -111,7 +113,7 @@ namespace Geekbot.net.Handlers private GuildSettingsModel GetGuildSettings(ulong guildId) { - return _database.GuildSettings.FirstOrDefault(guild => guild.GuildId.Equals(guildId.AsLong())); + return _guildSettingsManager.GetSettings(guildId, false); } } } \ No newline at end of file diff --git a/Geekbot.net/Lib/GuildSettingsManager/GuildSettingsManager.cs b/Geekbot.net/Lib/GuildSettingsManager/GuildSettingsManager.cs new file mode 100644 index 0000000..bfa7556 --- /dev/null +++ b/Geekbot.net/Lib/GuildSettingsManager/GuildSettingsManager.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Geekbot.net.Database; +using Geekbot.net.Database.Models; +using Geekbot.net.Lib.Extensions; + +namespace Geekbot.net.Lib.GuildSettingsManager +{ + public class GuildSettingsManager : IGuildSettingsManager + { + private readonly DatabaseContext _database; + private readonly Dictionary _settings; + + public GuildSettingsManager(DatabaseContext database) + { + _database = database; + _settings = new Dictionary(); + } + + public GuildSettingsModel GetSettings(ulong guildId, bool createIfNonExist = true) + { + return _settings.ContainsKey(guildId) ? _settings[guildId] : GetFromDatabase(guildId, createIfNonExist); + } + + public async Task UpdateSettings(GuildSettingsModel settings) + { + _database.GuildSettings.Update(settings); + if (_settings.ContainsKey(settings.GuildId.AsUlong())) + { + _settings[settings.GuildId.AsUlong()] = settings; + } + else + { + _settings.Add(settings.GuildId.AsUlong(), settings); + } + await _database.SaveChangesAsync(); + } + + private GuildSettingsModel GetFromDatabase(ulong guildId, bool createIfNonExist) + { + var settings = _database.GuildSettings.FirstOrDefault(guild => guild.GuildId.Equals(guildId.AsLong())); + if (createIfNonExist && settings == null) + { + settings = CreateSettings(guildId); + } + + _settings.Add(guildId, settings); + return settings; + } + + private GuildSettingsModel CreateSettings(ulong guildId) + { + _database.GuildSettings.Add(new GuildSettingsModel + { + GuildId = guildId.AsLong(), + Hui = false, + Ping = false, + Language = "EN", + ShowDelete = false, + ShowLeave = false, + WikiLang = "en" + }); + _database.SaveChanges(); + return _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong())); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/Lib/GuildSettingsManager/IGuildSettingsManager.cs b/Geekbot.net/Lib/GuildSettingsManager/IGuildSettingsManager.cs new file mode 100644 index 0000000..a45b263 --- /dev/null +++ b/Geekbot.net/Lib/GuildSettingsManager/IGuildSettingsManager.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using Geekbot.net.Database.Models; + +namespace Geekbot.net.Lib.GuildSettingsManager +{ + public interface IGuildSettingsManager + { + GuildSettingsModel GetSettings(ulong guildId, bool createIfNonExist = true); + Task UpdateSettings(GuildSettingsModel settings); + } +} \ No newline at end of file diff --git a/Geekbot.net/Lib/Localization/TranslationHandler.cs b/Geekbot.net/Lib/Localization/TranslationHandler.cs index a7a1a12..89ba632 100644 --- a/Geekbot.net/Lib/Localization/TranslationHandler.cs +++ b/Geekbot.net/Lib/Localization/TranslationHandler.cs @@ -4,9 +4,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using Discord.Commands; -using Geekbot.net.Database; -using Geekbot.net.Database.Models; -using Geekbot.net.Lib.Extensions; +using Geekbot.net.Lib.GuildSettingsManager; using Geekbot.net.Lib.Logger; using YamlDotNet.Core; using YamlDotNet.Serialization; @@ -15,15 +13,15 @@ namespace Geekbot.net.Lib.Localization { public class TranslationHandler : ITranslationHandler { - private readonly DatabaseContext _database; private readonly IGeekbotLogger _logger; + private readonly IGuildSettingsManager _guildSettingsManager; private readonly Dictionary _serverLanguages; private Dictionary>> _translations; - public TranslationHandler(DatabaseContext database, IGeekbotLogger logger) + public TranslationHandler(IGeekbotLogger logger, IGuildSettingsManager guildSettingsManager) { - _database = database; _logger = logger; + _guildSettingsManager = guildSettingsManager; _logger.Information(LogSource.Geekbot, "Loading Translations"); LoadTranslations(); _serverLanguages = new Dictionary(); @@ -107,7 +105,7 @@ namespace Geekbot.net.Lib.Localization } catch { - lang = (await GetGuild(guildId)).Language ?? "EN"; + lang = _guildSettingsManager.GetSettings(guildId, false)?.Language ?? "EN"; _serverLanguages[guildId] = lang; return lang; } @@ -178,9 +176,9 @@ namespace Geekbot.net.Lib.Localization try { if (!SupportedLanguages.Contains(language)) return false; - var guild = await GetGuild(guildId); + var guild = _guildSettingsManager.GetSettings(guildId); guild.Language = language; - _database.GuildSettings.Update(guild); + await _guildSettingsManager.UpdateSettings(guild); _serverLanguages[guildId] = language; return true; } @@ -192,17 +190,5 @@ namespace Geekbot.net.Lib.Localization } public List SupportedLanguages { get; private set; } - - private async Task GetGuild(ulong guildId) - { - var guild = _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong())); - if (guild != null) return guild; - _database.GuildSettings.Add(new GuildSettingsModel - { - GuildId = guildId.AsLong() - }); - await _database.SaveChangesAsync(); - return _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong())); - } } } \ No newline at end of file diff --git a/Geekbot.net/Program.cs b/Geekbot.net/Program.cs index 262d830..1299583 100755 --- a/Geekbot.net/Program.cs +++ b/Geekbot.net/Program.cs @@ -13,6 +13,7 @@ using Geekbot.net.Lib.Clients; using Geekbot.net.Lib.Converters; using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.GlobalSettings; +using Geekbot.net.Lib.GuildSettingsManager; using Geekbot.net.Lib.Highscores; using Geekbot.net.Lib.KvInMemoryStore; using Geekbot.net.Lib.Levels; @@ -40,6 +41,7 @@ namespace Geekbot.net private IUserRepository _userRepository; private RunParameters _runParameters; private IReactionListener _reactionListener; + private IGuildSettingsManager _guildSettingsManager; private static void Main(string[] args) { @@ -156,6 +158,7 @@ namespace Geekbot.net _userRepository = new UserRepository(_databaseInitializer.Initialize(), _logger); _reactionListener = new ReactionListener(_databaseInitializer.Initialize()); + _guildSettingsManager = new GuildSettingsManager(_databaseInitializer.Initialize()); var fortunes = new FortunesProvider(_logger); var mediaProvider = new MediaProvider(_logger); var malClient = new MalClient(_globalSettings, _logger); @@ -165,7 +168,7 @@ namespace Geekbot.net var wikipediaClient = new WikipediaClient(); var randomNumberGenerator = new RandomNumberGenerator(); var kvMemoryStore = new KvInInMemoryStore(); - var translationHandler = new TranslationHandler(_databaseInitializer.Initialize(), _logger); + var translationHandler = new TranslationHandler(_logger, _guildSettingsManager); var errorHandler = new ErrorHandler(_logger, translationHandler, _runParameters.ExposeErrors); services.AddSingleton(_userRepository); @@ -183,6 +186,7 @@ namespace Geekbot.net services.AddSingleton(errorHandler); services.AddSingleton(translationHandler); services.AddSingleton(_reactionListener); + services.AddSingleton(_guildSettingsManager); services.AddSingleton(_client); services.AddTransient(e => new HighscoreManager(_databaseInitializer.Initialize(), _userRepository)); services.AddTransient(e => _databaseInitializer.Initialize()); @@ -197,7 +201,7 @@ namespace Geekbot.net _commands = new CommandService(); await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _servicesProvider); - var commandHandler = new CommandHandler(_databaseInitializer.Initialize(), _client, _logger, _servicesProvider, _commands, applicationInfo); + var commandHandler = new CommandHandler(_databaseInitializer.Initialize(), _client, _logger, _servicesProvider, _commands, applicationInfo, _guildSettingsManager); var userHandler = new UserHandler(_userRepository, _logger, _databaseInitializer.Initialize(), _client); var reactionHandler = new ReactionHandler(_reactionListener); var statsHandler = new StatsHandler(_logger, _databaseInitializer.Initialize());