diff --git a/src/Bot/Commands/Admin/Admin.cs b/src/Bot/Commands/Admin/Admin.cs index 2627f86..60ba8ac 100644 --- a/src/Bot/Commands/Admin/Admin.cs +++ b/src/Bot/Commands/Admin/Admin.cs @@ -14,7 +14,6 @@ using Geekbot.Core.CommandPreconditions; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; using Geekbot.Core.GuildSettingsManager; -using Geekbot.Core.Localization; namespace Geekbot.Bot.Commands.Admin { @@ -24,21 +23,18 @@ namespace Geekbot.Bot.Commands.Admin public class Admin : GeekbotCommandBase { private readonly DiscordSocketClient _client; - private readonly IGuildSettingsManager _guildSettingsManager; - public Admin(DiscordSocketClient client, IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager, ITranslationHandler translationHandler) : base(errorHandler, translationHandler) + public Admin(DiscordSocketClient client, IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager) { _client = client; - _guildSettingsManager = guildSettingsManager; } [Command("welcome", RunMode = RunMode.Async)] [Summary("Set a Welcome Message (use '$user' to mention the new joined user).")] public async Task SetWelcomeMessage([Remainder, Summary("message")] string welcomeMessage) { - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.WelcomeMessage = welcomeMessage; - await _guildSettingsManager.UpdateSettings(guild); + GuildSettings.WelcomeMessage = welcomeMessage; + await GuildSettingsManager.UpdateSettings(GuildSettings); 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}"); @@ -52,9 +48,8 @@ namespace Geekbot.Bot.Commands.Admin { var m = await channel.SendMessageAsync("..."); - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.WelcomeChannel = channel.Id.AsLong(); - await _guildSettingsManager.UpdateSettings(guild); + GuildSettings.WelcomeChannel = channel.Id.AsLong(); + await GuildSettingsManager.UpdateSettings(GuildSettings); await m.DeleteAsync(); @@ -74,9 +69,8 @@ namespace Geekbot.Bot.Commands.Admin { var m = await channel.SendMessageAsync("verifying..."); - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.ModChannel = channel.Id.AsLong(); - await _guildSettingsManager.UpdateSettings(guild); + GuildSettings.ModChannel = channel.Id.AsLong(); + await GuildSettingsManager.UpdateSettings(GuildSettings); var sb = new StringBuilder(); sb.AppendLine("Successfully saved mod channel, you can now do the following"); @@ -96,13 +90,12 @@ namespace Geekbot.Bot.Commands.Admin { try { - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - var modChannel = await GetModChannel(guild.ModChannel.AsUlong()); + var modChannel = await GetModChannel(GuildSettings.ModChannel.AsUlong()); if (modChannel == null) return; - guild.ShowLeave = !guild.ShowLeave; - await _guildSettingsManager.UpdateSettings(guild); - await modChannel.SendMessageAsync(guild.ShowLeave + GuildSettings.ShowLeave = !GuildSettings.ShowLeave; + await GuildSettingsManager.UpdateSettings(GuildSettings); + await modChannel.SendMessageAsync(GuildSettings.ShowLeave ? "Saved - now sending messages here when someone leaves" : "Saved - stopping sending messages here when someone leaves" ); @@ -119,13 +112,12 @@ namespace Geekbot.Bot.Commands.Admin { try { - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - var modChannel = await GetModChannel(guild.ModChannel.AsUlong()); + var modChannel = await GetModChannel(GuildSettings.ModChannel.AsUlong()); if (modChannel == null) return; - guild.ShowDelete = !guild.ShowDelete; - await _guildSettingsManager.UpdateSettings(guild); - await modChannel.SendMessageAsync(guild.ShowDelete + GuildSettings.ShowDelete = !GuildSettings.ShowDelete; + await GuildSettingsManager.UpdateSettings(GuildSettings); + await modChannel.SendMessageAsync(GuildSettings.ShowDelete ? "Saved - now sending messages here when someone deletes a message" : "Saved - stopping sending messages here when someone deletes a message" ); @@ -138,31 +130,25 @@ namespace Geekbot.Bot.Commands.Admin [Command("setlang", RunMode = RunMode.Async)] [Summary("Change the bots language")] - public async Task SetLanguage([Summary("language")] string languageRaw) + public async Task SetLanguage([Summary("language")] string language) { try { - var language = languageRaw.ToUpper(); - var success = await Translations.SetLanguage(Context.Guild.Id, language); - if (success) + var availableLanguages = new List(); + availableLanguages.Add("en-GB"); // default + availableLanguages.AddRange(GetAvailableCultures().Select(culture => culture.Name)); + if (availableLanguages.Contains(language)) { - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.Language = language; - await _guildSettingsManager.UpdateSettings(guild); + GuildSettings.Language = language; + await GuildSettingsManager.UpdateSettings(GuildSettings); + + Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language.ToLower() == "chde" ? "de-CH" : language); - if (language.ToLower() == "chde") - { - Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-ch"); - } - await ReplyAsync(Localization.Admin.NewLanguageSet); return; } - - var available = new List(); - available.Add("en-GB"); // default - available.AddRange(GetAvailableCultures().Select(culture => culture.Name)); - await ReplyAsync($"That doesn't seem to be a supported language\nSupported Languages are {string.Join(", ", available)}"); + + await ReplyAsync($"That doesn't seem to be a supported language\nSupported Languages are {string.Join(", ", availableLanguages)}"); } catch (Exception e) { @@ -177,9 +163,8 @@ namespace Geekbot.Bot.Commands.Admin try { var language = languageRaw.ToLower(); - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.WikiLang = language; - await _guildSettingsManager.UpdateSettings(guild); + GuildSettings.WikiLang = language; + await GuildSettingsManager.UpdateSettings(GuildSettings); await ReplyAsync($"Now using the {language} wikipedia"); } @@ -195,10 +180,10 @@ namespace Geekbot.Bot.Commands.Admin { try { - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.Ping = !guild.Ping; - await _guildSettingsManager.UpdateSettings(guild); - await ReplyAsync(guild.Ping ? "i will reply to ping now" : "No more pongs..."); + // var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); + GuildSettings.Ping = !GuildSettings.Ping; + await GuildSettingsManager.UpdateSettings(GuildSettings); + await ReplyAsync(GuildSettings.Ping ? "i will reply to ping now" : "No more pongs..."); } catch (Exception e) { @@ -212,10 +197,10 @@ namespace Geekbot.Bot.Commands.Admin { try { - var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); - guild.Hui = !guild.Hui; - await _guildSettingsManager.UpdateSettings(guild); - await ReplyAsync(guild.Hui ? "i will reply to hui now" : "No more hui's..."); + // var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); + GuildSettings.Hui = !GuildSettings.Hui; + await GuildSettingsManager.UpdateSettings(GuildSettings); + await ReplyAsync(GuildSettings.Hui ? "i will reply to hui now" : "No more hui's..."); } catch (Exception e) { diff --git a/src/Bot/Commands/Admin/Owner/Owner.cs b/src/Bot/Commands/Admin/Owner/Owner.cs index 5fa3976..64292e9 100644 --- a/src/Bot/Commands/Admin/Owner/Owner.cs +++ b/src/Bot/Commands/Admin/Owner/Owner.cs @@ -3,8 +3,10 @@ using System.Threading.Tasks; using Discord; using Discord.Commands; using Discord.WebSocket; +using Geekbot.Core; using Geekbot.Core.ErrorHandling; using Geekbot.Core.GlobalSettings; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.Logger; using Geekbot.Core.UserRepository; @@ -12,20 +14,19 @@ namespace Geekbot.Bot.Commands.Admin.Owner { [Group("owner")] [RequireOwner] - public class Owner : ModuleBase + public class Owner : GeekbotCommandBase { private readonly DiscordSocketClient _client; - private readonly IErrorHandler _errorHandler; private readonly IGlobalSettings _globalSettings; private readonly IGeekbotLogger _logger; private readonly IUserRepository _userRepository; - public Owner(DiscordSocketClient client, IGeekbotLogger logger, IUserRepository userRepositry, IErrorHandler errorHandler, IGlobalSettings globalSettings) + public Owner(DiscordSocketClient client, IGeekbotLogger logger, IUserRepository userRepositry, IErrorHandler errorHandler, IGlobalSettings globalSettings, + IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager) { _client = client; _logger = logger; _userRepository = userRepositry; - _errorHandler = errorHandler; _globalSettings = globalSettings; } @@ -73,7 +74,7 @@ namespace Geekbot.Bot.Commands.Admin.Owner } catch (Exception e) { - await _errorHandler.HandleCommandException(e, Context, + await ErrorHandler.HandleCommandException(e, Context, "Couldn't complete User Repository, see console for more info"); } } @@ -89,10 +90,10 @@ namespace Geekbot.Bot.Commands.Admin.Owner } catch (Exception e) { - await _errorHandler.HandleCommandException(e, Context); + await ErrorHandler.HandleCommandException(e, Context); } } - + [Command("refreshuser", RunMode = RunMode.Async)] [Summary("Refresh a user in the user cache")] public async Task PopUserRepoCommand([Summary("user-id")] ulong userId) @@ -105,7 +106,7 @@ namespace Geekbot.Bot.Commands.Admin.Owner } catch (Exception e) { - await _errorHandler.HandleCommandException(e, Context); + await ErrorHandler.HandleCommandException(e, Context); } } @@ -119,7 +120,7 @@ namespace Geekbot.Bot.Commands.Admin.Owner } catch (Exception e) { - await _errorHandler.HandleCommandException(e, Context); + await ErrorHandler.HandleCommandException(e, Context); } } } diff --git a/src/Bot/Commands/Admin/Role.cs b/src/Bot/Commands/Admin/Role.cs index c8459dd..efec7bd 100644 --- a/src/Bot/Commands/Admin/Role.cs +++ b/src/Bot/Commands/Admin/Role.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Net; using System.Text; using System.Threading.Tasks; using Discord; @@ -11,7 +12,7 @@ using Geekbot.Core.Database; using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.ReactionListener; namespace Geekbot.Bot.Commands.Admin @@ -23,7 +24,7 @@ namespace Geekbot.Bot.Commands.Admin private readonly DatabaseContext _database; private readonly IReactionListener _reactionListener; - public Role(DatabaseContext database, IErrorHandler errorHandler, IReactionListener reactionListener, ITranslationHandler translationHandler) : base(errorHandler, translationHandler) + public Role(DatabaseContext database, IErrorHandler errorHandler, IReactionListener reactionListener, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager) { _database = database; _reactionListener = reactionListener; @@ -89,7 +90,14 @@ namespace Geekbot.Bot.Commands.Admin } catch (HttpException e) { - await ErrorHandler.HandleHttpException(e, Context); + if (e.HttpCode == HttpStatusCode.Forbidden) + { + await ReplyAsync(Localization.Internal.Http403); + } + else + { + await ErrorHandler.HandleCommandException(e, Context); + } } catch (Exception e) { diff --git a/src/Bot/Commands/Games/Roll/Roll.cs b/src/Bot/Commands/Games/Roll/Roll.cs index 244edbe..6ef9322 100644 --- a/src/Bot/Commands/Games/Roll/Roll.cs +++ b/src/Bot/Commands/Games/Roll/Roll.cs @@ -2,13 +2,14 @@ using System.Linq; using System.Threading.Tasks; using Discord.Commands; +using Geekbot.Bot.Utils; using Geekbot.Core; using Geekbot.Core.Database; using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.KvInMemoryStore; -using Geekbot.Core.Localization; using Geekbot.Core.RandomNumberGenerator; namespace Geekbot.Bot.Commands.Games.Roll @@ -19,7 +20,8 @@ namespace Geekbot.Bot.Commands.Games.Roll private readonly DatabaseContext _database; private readonly IRandomNumberGenerator _randomNumberGenerator; - public Roll(IKvInMemoryStore kvInMemoryStore,IErrorHandler errorHandler, ITranslationHandler translation, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator) : base(errorHandler, translation) + public Roll(IKvInMemoryStore kvInMemoryStore, IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator, IGuildSettingsManager guildSettingsManager) + : base(errorHandler, guildSettingsManager) { _kvInMemoryStore = kvInMemoryStore; _database = database; @@ -34,10 +36,9 @@ namespace Geekbot.Bot.Commands.Games.Roll { var number = _randomNumberGenerator.Next(1, 100); int.TryParse(stuff, out var guess); - var transContext = await Translations.GetGuildContext(Context); if (guess <= 100 && guess > 0) { - var kvKey = $"{Context.Guild.Id}:{Context.User.Id}:RollsPrevious"; + var kvKey = $"{Context?.Guild?.Id ?? 0}:{Context.User.Id}:RollsPrevious"; var prevRoll = _kvInMemoryStore.Get(kvKey); @@ -46,11 +47,11 @@ namespace Geekbot.Bot.Commands.Games.Roll await ReplyAsync(string.Format( Localization.Roll.NoPrevGuess, Context.Message.Author.Mention, - transContext.FormatDateTimeAsRemaining(prevRoll.GuessedOn.AddDays(1)))); + DateLocalization.FormatDateTimeAsRemaining(prevRoll.GuessedOn.AddDays(1)))); return; } - _kvInMemoryStore.Set(kvKey, new RollTimeout { LastGuess = guess, GuessedOn = DateTime.Now }); + _kvInMemoryStore.Set(kvKey, new RollTimeout {LastGuess = guess, GuessedOn = DateTime.Now}); await ReplyAsync(string.Format(Localization.Roll.Rolled, Context.Message.Author.Mention, number, guess)); if (guess == number) @@ -72,13 +73,13 @@ namespace Geekbot.Bot.Commands.Games.Roll await ErrorHandler.HandleCommandException(e, Context); } } - + private async Task GetUser(ulong userId) { - var user = _database.Rolls.FirstOrDefault(u =>u.GuildId.Equals(Context.Guild.Id.AsLong()) && u.UserId.Equals(userId.AsLong())) ?? await CreateNewRow(userId); + var user = _database.Rolls.FirstOrDefault(u => u.GuildId.Equals(Context.Guild.Id.AsLong()) && u.UserId.Equals(userId.AsLong())) ?? await CreateNewRow(userId); return user; } - + private async Task CreateNewRow(ulong userId) { var user = new RollsModel() diff --git a/src/Bot/Commands/Randomness/Ship.cs b/src/Bot/Commands/Randomness/Ship.cs index 78f3c99..f48713e 100644 --- a/src/Bot/Commands/Randomness/Ship.cs +++ b/src/Bot/Commands/Randomness/Ship.cs @@ -8,7 +8,7 @@ using Geekbot.Core.Database; using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.RandomNumberGenerator; namespace Geekbot.Bot.Commands.Randomness @@ -18,7 +18,7 @@ namespace Geekbot.Bot.Commands.Randomness private readonly IRandomNumberGenerator _randomNumberGenerator; private readonly DatabaseContext _database; - public Ship(DatabaseContext database, IErrorHandler errorHandler, IRandomNumberGenerator randomNumberGenerator, ITranslationHandler translations) : base(errorHandler, translations) + public Ship(DatabaseContext database, IErrorHandler errorHandler, IRandomNumberGenerator randomNumberGenerator, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager) { _database = database; _randomNumberGenerator = randomNumberGenerator; diff --git a/src/Bot/Commands/Rpg/Cookies.cs b/src/Bot/Commands/Rpg/Cookies.cs index 570f08a..a51d652 100644 --- a/src/Bot/Commands/Rpg/Cookies.cs +++ b/src/Bot/Commands/Rpg/Cookies.cs @@ -3,13 +3,14 @@ using System.Linq; using System.Threading.Tasks; using Discord; using Discord.Commands; +using Geekbot.Bot.Utils; using Geekbot.Core; using Geekbot.Core.CommandPreconditions; using Geekbot.Core.Database; using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.RandomNumberGenerator; namespace Geekbot.Bot.Commands.Rpg @@ -22,7 +23,8 @@ namespace Geekbot.Bot.Commands.Rpg private readonly DatabaseContext _database; private readonly IRandomNumberGenerator _randomNumberGenerator; - public Cookies(DatabaseContext database, IErrorHandler errorHandler, ITranslationHandler translations , IRandomNumberGenerator randomNumberGenerator) : base(errorHandler, translations) + public Cookies(DatabaseContext database, IErrorHandler errorHandler, IRandomNumberGenerator randomNumberGenerator, IGuildSettingsManager guildSettingsManager) + : base(errorHandler, guildSettingsManager) { _database = database; _randomNumberGenerator = randomNumberGenerator; @@ -34,12 +36,11 @@ namespace Geekbot.Bot.Commands.Rpg { try { - var transContext = await Translations.GetGuildContext(Context); var actor = await GetUser(Context.User.Id); if (actor.LastPayout.Value.AddDays(1).Date > DateTime.Now.Date) { - var formatedWaitTime = transContext.FormatDateTimeAsRemaining(DateTimeOffset.Now.AddDays(1).Date); - await ReplyAsync(string.Format(Localization.Cookies.WaitForMoreCookies, formatedWaitTime)); + var formattedWaitTime = DateLocalization.FormatDateTimeAsRemaining(DateTimeOffset.Now.AddDays(1).Date); + await ReplyAsync(string.Format(Localization.Cookies.WaitForMoreCookies, formattedWaitTime)); return; } actor.Cookies += 10; diff --git a/src/Bot/Commands/User/Karma.cs b/src/Bot/Commands/User/Karma.cs index 41a401c..4778bce 100644 --- a/src/Bot/Commands/User/Karma.cs +++ b/src/Bot/Commands/User/Karma.cs @@ -1,17 +1,16 @@ using System; -using System.Globalization; using System.Linq; -using System.Threading; using System.Threading.Tasks; using Discord; using Discord.Commands; +using Geekbot.Bot.Utils; using Geekbot.Core; using Geekbot.Core.CommandPreconditions; using Geekbot.Core.Database; using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; namespace Geekbot.Bot.Commands.User { @@ -19,12 +18,10 @@ namespace Geekbot.Bot.Commands.User public class Karma : GeekbotCommandBase { private readonly DatabaseContext _database; - private readonly ITranslationHandler _translations; - public Karma(DatabaseContext database, IErrorHandler errorHandler, ITranslationHandler translations) : base(errorHandler, translations) + public Karma(DatabaseContext database, IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager) { _database = database; - _translations = translations; } [Command("good", RunMode = RunMode.Async)] @@ -33,8 +30,6 @@ namespace Geekbot.Bot.Commands.User { try { - var transContext = await _translations.GetGuildContext(Context); - var actor = await GetUser(Context.User.Id); if (user.Id == Context.User.Id) { @@ -42,7 +37,7 @@ namespace Geekbot.Bot.Commands.User } else if (TimeoutFinished(actor.TimeOut)) { - var formatedWaitTime = transContext.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3)); + var formatedWaitTime = DateLocalization.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3)); await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime)); } else @@ -81,8 +76,6 @@ namespace Geekbot.Bot.Commands.User { try { - var transContext = await _translations.GetGuildContext(Context); - var actor = await GetUser(Context.User.Id); if (user.Id == Context.User.Id) { @@ -90,7 +83,7 @@ namespace Geekbot.Bot.Commands.User } else if (TimeoutFinished(actor.TimeOut)) { - var formatedWaitTime = transContext.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3)); + var formatedWaitTime = DateLocalization.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3)); await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime)); } else diff --git a/src/Bot/Commands/User/Ranking/Rank.cs b/src/Bot/Commands/User/Ranking/Rank.cs index d73aacc..20749a8 100644 --- a/src/Bot/Commands/User/Ranking/Rank.cs +++ b/src/Bot/Commands/User/Ranking/Rank.cs @@ -10,8 +10,8 @@ using Geekbot.Core.Converters; using Geekbot.Core.Database; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.Highscores; -using Geekbot.Core.Localization; namespace Geekbot.Bot.Commands.User.Ranking { @@ -21,7 +21,8 @@ namespace Geekbot.Bot.Commands.User.Ranking private readonly IHighscoreManager _highscoreManager; private readonly DatabaseContext _database; - public Rank(DatabaseContext database, IErrorHandler errorHandler, IEmojiConverter emojiConverter, IHighscoreManager highscoreManager, ITranslationHandler translations): base(errorHandler, translations) + public Rank(DatabaseContext database, IErrorHandler errorHandler, IEmojiConverter emojiConverter, IHighscoreManager highscoreManager, IGuildSettingsManager guildSettingsManager) + : base(errorHandler, guildSettingsManager) { _database = database; _emojiConverter = emojiConverter; @@ -53,7 +54,7 @@ namespace Geekbot.Bot.Commands.User.Ranking await ReplyAsync(Localization.Rank.LimitingTo20Warning); amount = 20; } - + var guildId = Context.Guild.Id; Dictionary highscoreUsers; try @@ -78,9 +79,9 @@ namespace Geekbot.Bot.Commands.User.Ranking var failedToRetrieveUser = highscoreUsers.Any(e => string.IsNullOrEmpty(e.Key.Username)); if (failedToRetrieveUser) replyBuilder.AppendLine(Localization.Rank.FailedToResolveAllUsernames).AppendLine(); - + replyBuilder.AppendLine(string.Format(Localization.Rank.HighscoresFor, type.ToString().CapitalizeFirst(), Context.Guild.Name)); - + var highscorePlace = 1; foreach (var (user, value) in highscoreUsers) { @@ -91,7 +92,7 @@ namespace Geekbot.Bot.Commands.User.Ranking replyBuilder.Append(user.Username != null ? $"**{user.Username}#{user.Discriminator}**" : $"**{user.Id}**"); - + replyBuilder.Append(type == HighscoreTypes.messages ? $" - {value} {type} - {Math.Round((double) (100 * value) / guildMessages, 2)}%\n" : $" - {value} {type}\n"); diff --git a/src/Bot/Commands/Utils/Choose.cs b/src/Bot/Commands/Utils/Choose.cs index ea239d7..731bee6 100644 --- a/src/Bot/Commands/Utils/Choose.cs +++ b/src/Bot/Commands/Utils/Choose.cs @@ -3,13 +3,13 @@ using System.Threading.Tasks; using Discord.Commands; using Geekbot.Core; using Geekbot.Core.ErrorHandling; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; namespace Geekbot.Bot.Commands.Utils { public class Choose : GeekbotCommandBase { - public Choose(IErrorHandler errorHandler, ITranslationHandler translation) : base(errorHandler, translation) + public Choose(IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager) { } diff --git a/src/Bot/Commands/Utils/Quote/Quote.cs b/src/Bot/Commands/Utils/Quote/Quote.cs index 5bb23a9..a7d3ff1 100644 --- a/src/Bot/Commands/Utils/Quote/Quote.cs +++ b/src/Bot/Commands/Utils/Quote/Quote.cs @@ -9,7 +9,7 @@ using Geekbot.Core.Database; using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; using Geekbot.Core.Extensions; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.Polyfills; using Geekbot.Core.RandomNumberGenerator; @@ -23,7 +23,8 @@ namespace Geekbot.Bot.Commands.Utils.Quote private readonly IRandomNumberGenerator _randomNumberGenerator; private readonly bool _isDev; - public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator, ITranslationHandler translationHandler) : base(errorHandler, translationHandler) + public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator, IGuildSettingsManager guildSettingsManager) + : base(errorHandler, guildSettingsManager) { _database = database; _randomNumberGenerator = randomNumberGenerator; diff --git a/src/Bot/Program.cs b/src/Bot/Program.cs index 04b1450..5a4b456 100644 --- a/src/Bot/Program.cs +++ b/src/Bot/Program.cs @@ -17,7 +17,6 @@ using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.Highscores; using Geekbot.Core.KvInMemoryStore; using Geekbot.Core.Levels; -using Geekbot.Core.Localization; using Geekbot.Core.Logger; using Geekbot.Core.MalClient; using Geekbot.Core.Media; @@ -168,8 +167,7 @@ namespace Geekbot.Bot var randomNumberGenerator = new RandomNumberGenerator(); var mediaProvider = new MediaProvider(_logger, randomNumberGenerator); var kvMemoryStore = new KvInInMemoryStore(); - var translationHandler = new TranslationHandler(_logger, _guildSettingsManager); - var errorHandler = new ErrorHandler(_logger, translationHandler, _runParameters); + var errorHandler = new ErrorHandler(_logger, _runParameters, () => Localization.Internal.SomethingWentWrong); var diceParser = new DiceParser(randomNumberGenerator); services.AddSingleton(_userRepository); @@ -186,7 +184,6 @@ namespace Geekbot.Bot services.AddSingleton(_globalSettings); services.AddSingleton(errorHandler); services.AddSingleton(diceParser); - services.AddSingleton(translationHandler); services.AddSingleton(_reactionListener); services.AddSingleton(_guildSettingsManager); services.AddSingleton(_client); diff --git a/src/Bot/Utils/DateLocalization.cs b/src/Bot/Utils/DateLocalization.cs new file mode 100644 index 0000000..eea40fb --- /dev/null +++ b/src/Bot/Utils/DateLocalization.cs @@ -0,0 +1,49 @@ +using System; +using System.Text; + +namespace Geekbot.Bot.Utils +{ + public class DateLocalization + { + public static string FormatDateTimeAsRemaining(DateTimeOffset dateTime) + { + var remaining = dateTime - DateTimeOffset.Now; + const string formattable = "{0} {1}"; + var sb = new StringBuilder(); + + if (remaining.Days > 0) + { + sb.AppendFormat(formattable, remaining.Days, GetSingularOrPlural(remaining.Days, Localization.Internal.Days)); + } + + if (remaining.Hours > 0) + { + if (sb.Length > 0) sb.Append(", "); + sb.AppendFormat(formattable, remaining.Hours, GetSingularOrPlural(remaining.Hours, Localization.Internal.Hours)); + } + + if (remaining.Minutes > 0) + { + if (sb.Length > 0) sb.Append(", "); + sb.AppendFormat(formattable, remaining.Minutes, GetSingularOrPlural(remaining.Minutes, Localization.Internal.Minutes)); + } + + if (remaining.Seconds > 0) + { + if (sb.Length > 0) + { + sb.AppendFormat(" {0} ", Localization.Internal.And); + } + sb.AppendFormat(formattable, remaining.Seconds, GetSingularOrPlural(remaining.Seconds, Localization.Internal.Seconds)); + } + + return sb.ToString().Trim(); + } + + private static string GetSingularOrPlural(int number, string rawString) + { + var versions = rawString.Split('|'); + return number == 1 ? versions[0] : versions[1]; + } + } +} \ No newline at end of file diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index fcbce09..fd44a95 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -31,10 +31,4 @@ - - - PreserveNewest - - - diff --git a/src/Core/ErrorHandling/ErrorHandler.cs b/src/Core/ErrorHandling/ErrorHandler.cs index 02402f2..47ed22d 100644 --- a/src/Core/ErrorHandling/ErrorHandler.cs +++ b/src/Core/ErrorHandling/ErrorHandler.cs @@ -1,9 +1,6 @@ using System; -using System.Net; using System.Threading.Tasks; using Discord.Commands; -using Discord.Net; -using Geekbot.Core.Localization; using Geekbot.Core.Logger; using SharpRaven; using SharpRaven.Data; @@ -14,14 +11,14 @@ namespace Geekbot.Core.ErrorHandling public class ErrorHandler : IErrorHandler { private readonly IGeekbotLogger _logger; - private readonly ITranslationHandler _translation; + private readonly Func _getDefaultErrorText; private readonly IRavenClient _raven; private readonly bool _errorsInChat; - public ErrorHandler(IGeekbotLogger logger, ITranslationHandler translation, RunParameters runParameters) + public ErrorHandler(IGeekbotLogger logger, RunParameters runParameters, Func getDefaultErrorText) { _logger = logger; - _translation = translation; + _getDefaultErrorText = getDefaultErrorText; _errorsInChat = runParameters.ExposeErrors; var sentryDsn = runParameters.SentryEndpoint; @@ -40,7 +37,9 @@ namespace Geekbot.Core.ErrorHandling { try { - var errorString = errorMessage == "def" ? await _translation.GetString(context.Guild?.Id ?? 0, "errorHandler", "SomethingWentWrong") : errorMessage; + var errorString = errorMessage == "def" + ? _getDefaultErrorText() + : errorMessage; var errorObj = SimpleConextConverter.ConvertContext(context); if (e.Message.Contains("50007")) return; if (e.Message.Contains("50013")) return; @@ -76,17 +75,6 @@ namespace Geekbot.Core.ErrorHandling } } - public async Task HandleHttpException(HttpException e, ICommandContext context) - { - var errorStrings = await _translation.GetDict(context, "httpErrors"); - switch(e.HttpCode) - { - case HttpStatusCode.Forbidden: - await context.Channel.SendMessageAsync(errorStrings["403"]); - break; - } - } - private void ReportExternal(Exception e, MessageDto errorObj) { if (_raven == null) return; diff --git a/src/Core/ErrorHandling/IErrorHandler.cs b/src/Core/ErrorHandling/IErrorHandler.cs index c012b82..d0e1d20 100644 --- a/src/Core/ErrorHandling/IErrorHandler.cs +++ b/src/Core/ErrorHandling/IErrorHandler.cs @@ -1,13 +1,11 @@ using System; using System.Threading.Tasks; using Discord.Commands; -using Discord.Net; namespace Geekbot.Core.ErrorHandling { public interface IErrorHandler { Task HandleCommandException(Exception e, ICommandContext context, string errorMessage = "def"); - Task HandleHttpException(HttpException e, ICommandContext context); } } \ No newline at end of file diff --git a/src/Core/GeekbotCommandBase.cs b/src/Core/GeekbotCommandBase.cs index 8df5265..43ced95 100644 --- a/src/Core/GeekbotCommandBase.cs +++ b/src/Core/GeekbotCommandBase.cs @@ -1,26 +1,29 @@ using System.Globalization; using System.Threading; using Discord.Commands; +using Geekbot.Core.Database.Models; using Geekbot.Core.ErrorHandling; -using Geekbot.Core.Localization; +using Geekbot.Core.GuildSettingsManager; namespace Geekbot.Core { public class GeekbotCommandBase : ModuleBase { + protected readonly IGuildSettingsManager GuildSettingsManager; + protected GuildSettingsModel GuildSettings; protected readonly IErrorHandler ErrorHandler; - protected readonly ITranslationHandler Translations; - protected GeekbotCommandBase(IErrorHandler errorHandler, ITranslationHandler translations) + protected GeekbotCommandBase(IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) { + GuildSettingsManager = guildSettingsManager; ErrorHandler = errorHandler; - Translations = translations; } protected override void BeforeExecute(CommandInfo command) { base.BeforeExecute(command); - var language = Translations.GetServerLanguage(Context.Guild.Id); + GuildSettings = GuildSettingsManager.GetSettings(Context?.Guild?.Id ?? 0); + var language = GuildSettings.Language; Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language == "CHDE" ? "de-ch" : language); } } diff --git a/src/Core/Localization/ITranslationHandler.cs b/src/Core/Localization/ITranslationHandler.cs deleted file mode 100644 index 1cc06fa..0000000 --- a/src/Core/Localization/ITranslationHandler.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Discord.Commands; - -namespace Geekbot.Core.Localization -{ - public interface ITranslationHandler - { - Task GetString(ulong guildId, string command, string stringName); - string GetString(string language, string command, string stringName); - Task> GetDict(ICommandContext context, string command); - Task GetGuildContext(ICommandContext context); - Task SetLanguage(ulong guildId, string language); - List SupportedLanguages { get; } - string GetServerLanguage(ulong guildId); - } -} \ No newline at end of file diff --git a/src/Core/Localization/TranslationGuildContext.cs b/src/Core/Localization/TranslationGuildContext.cs deleted file mode 100644 index 25685da..0000000 --- a/src/Core/Localization/TranslationGuildContext.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; - -namespace Geekbot.Core.Localization -{ - public class TranslationGuildContext - { - public ITranslationHandler TranslationHandler { get; } - public string Language { get; } - public Dictionary Dict { get; } - - public TranslationGuildContext(ITranslationHandler translationHandler, string language, Dictionary dict) - { - TranslationHandler = translationHandler; - Language = language; - Dict = dict; - } - - public string GetString(string stringToFormat, params object[] args) - { - return string.Format(Dict[stringToFormat] ?? "", args); - } - - public string FormatDateTimeAsRemaining(DateTimeOffset dateTime) - { - var remaining = dateTime - DateTimeOffset.Now; - const string formattable = "{0} {1}"; - var sb = new StringBuilder(); - - if (remaining.Days > 0) - { - var s = GetTimeString(TimeTypes.Days); - sb.AppendFormat(formattable, remaining.Days, GetSingOrPlur(remaining.Days, s)); - } - - if (remaining.Hours > 0) - { - if (sb.Length > 0) sb.Append(", "); - var s = GetTimeString(TimeTypes.Hours); - sb.AppendFormat(formattable, remaining.Hours, GetSingOrPlur(remaining.Hours, s)); - } - - if (remaining.Minutes > 0) - { - if (sb.Length > 0) sb.Append(", "); - var s = GetTimeString(TimeTypes.Minutes); - sb.AppendFormat(formattable, remaining.Minutes, GetSingOrPlur(remaining.Minutes, s)); - } - - if (remaining.Seconds > 0) - { - if (sb.Length > 0) - { - var and = TranslationHandler.GetString(Language, "dateTime", "And"); - sb.AppendFormat(" {0} ", and); - } - var s = GetTimeString(TimeTypes.Seconds); - sb.AppendFormat(formattable, remaining.Seconds, GetSingOrPlur(remaining.Seconds, s)); - } - - return sb.ToString().Trim(); - } - - public Task SetLanguage(ulong guildId, string language) - { - return TranslationHandler.SetLanguage(guildId, language); - } - - private string GetTimeString(TimeTypes type) - { - return TranslationHandler.GetString(Language, "dateTime", type.ToString()); - } - - private string GetSingOrPlur(int number, string rawString) - { - var versions = rawString.Split('|'); - return number == 1 ? versions[0] : versions[1]; - } - - private enum TimeTypes - { - Days, - Hours, - Minutes, - Seconds - } - } -} \ No newline at end of file diff --git a/src/Core/Localization/TranslationHandler.cs b/src/Core/Localization/TranslationHandler.cs deleted file mode 100644 index 1a46ada..0000000 --- a/src/Core/Localization/TranslationHandler.cs +++ /dev/null @@ -1,194 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Discord.Commands; -using Geekbot.Core.GuildSettingsManager; -using Geekbot.Core.Logger; -using YamlDotNet.Core; -using YamlDotNet.Serialization; - -namespace Geekbot.Core.Localization -{ - public class TranslationHandler : ITranslationHandler - { - private readonly IGeekbotLogger _logger; - private readonly IGuildSettingsManager _guildSettingsManager; - private readonly Dictionary _serverLanguages; - private Dictionary>> _translations; - - public TranslationHandler(IGeekbotLogger logger, IGuildSettingsManager guildSettingsManager) - { - _logger = logger; - _guildSettingsManager = guildSettingsManager; - _logger.Information(LogSource.Geekbot, "Loading Translations"); - LoadTranslations(); - _serverLanguages = new Dictionary(); - } - - private void LoadTranslations() - { - try - { - // Read the file - var translationFile = File.ReadAllText(Path.GetFullPath("./Localization/Translations.yml")); - - // Deserialize - var input = new StringReader(translationFile); - var mergingParser = new MergingParser(new Parser(input)); - var deserializer = new DeserializerBuilder().Build(); - var rawTranslations = deserializer.Deserialize>>>(mergingParser); - - // Sort - var sortedPerLanguage = new Dictionary>>(); - foreach (var command in rawTranslations) - { - foreach (var str in command.Value) - { - foreach (var lang in str.Value) - { - if (!sortedPerLanguage.ContainsKey(lang.Key)) - { - var commandDict = new Dictionary>(); - var strDict = new Dictionary - { - {str.Key, lang.Value} - }; - commandDict.Add(command.Key, strDict); - sortedPerLanguage.Add(lang.Key, commandDict); - } - if (!sortedPerLanguage[lang.Key].ContainsKey(command.Key)) - { - var strDict = new Dictionary - { - {str.Key, lang.Value} - }; - sortedPerLanguage[lang.Key].Add(command.Key, strDict); - } - if (!sortedPerLanguage[lang.Key][command.Key].ContainsKey(str.Key)) - { - sortedPerLanguage[lang.Key][command.Key].Add(str.Key, lang.Value); - } - } - } - } - _translations = sortedPerLanguage; - - // Find Languages - SupportedLanguages = new List(); - foreach (var lang in sortedPerLanguage) - { - SupportedLanguages.Add(lang.Key); - } - } - catch (Exception e) - { - _logger.Error(LogSource.Geekbot, "Failed to load Translations", e); - Environment.Exit(GeekbotExitCode.TranslationsFailed.GetHashCode()); - } - } - - public string GetServerLanguage(ulong guildId) - { - try - { - string lang; - try - { - lang = _serverLanguages[guildId]; - if (!string.IsNullOrEmpty(lang)) - { - return lang; - } - throw new Exception(); - } - catch - { - lang = _guildSettingsManager.GetSettings(guildId, false)?.Language ?? "EN"; - _serverLanguages[guildId] = lang; - return lang; - } - } - catch (Exception e) - { - _logger.Error(LogSource.Geekbot, "Could not get guild language", e); - return "EN"; - } - } - - public async Task GetString(ulong guildId, string command, string stringName) - { - var serverLang = GetServerLanguage(guildId); - return GetString(serverLang, command, stringName); - } - - public string GetString(string language, string command, string stringName) - { - var translation = _translations[language][command][stringName]; - if (!string.IsNullOrWhiteSpace(translation)) return translation; - translation = _translations[command][stringName]["EN"]; - if (string.IsNullOrWhiteSpace(translation)) - { - _logger.Warning(LogSource.Geekbot, $"No translation found for {command} - {stringName}"); - } - return translation; - } - - private async Task> GetDict(ICommandContext context) - { - try - { - var command = context.Message.Content.Split(' ').First().TrimStart('!').ToLower(); - var serverLanguage = GetServerLanguage(context.Guild?.Id ?? 0); - return _translations[serverLanguage][command]; - } - catch (Exception e) - { - _logger.Error(LogSource.Geekbot, "No translations for command found", e); - return new Dictionary(); - } - } - - public async Task GetGuildContext(ICommandContext context) - { - var dict = await GetDict(context); - var language = GetServerLanguage(context.Guild?.Id ?? 0); - return new TranslationGuildContext(this, language, dict); - } - - public async Task> GetDict(ICommandContext context, string command) - { - try - { - var serverLanguage = GetServerLanguage(context.Guild?.Id ?? 0); - return _translations[serverLanguage][command]; - } - catch (Exception e) - { - _logger.Error(LogSource.Geekbot, "No translations for command found", e); - return new Dictionary(); - } - } - - public async Task SetLanguage(ulong guildId, string language) - { - try - { - if (!SupportedLanguages.Contains(language)) return false; - var guild = _guildSettingsManager.GetSettings(guildId); - guild.Language = language; - await _guildSettingsManager.UpdateSettings(guild); - _serverLanguages[guildId] = language; - return true; - } - catch (Exception e) - { - _logger.Error(LogSource.Geekbot, "Error while changing language", e); - return false; - } - } - - public List SupportedLanguages { get; private set; } - } -} \ No newline at end of file diff --git a/src/Core/Localization/Translations.yml b/src/Core/Localization/Translations.yml deleted file mode 100644 index dc18c2b..0000000 --- a/src/Core/Localization/Translations.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -dateTime: - Days: - EN: "day|days" - CHDE: "tag|täg" - Hours: - EN: "hour|hours" - CHDE: "stund|stunde" - Minutes: - EN: "minute|minutes" - CHDE: "minute|minute" - Seconds: - EN: "second|seconds" - CHDE: "sekunde|sekunde" - And: - EN: "and" - CHDE: "und" -errorHandler: - SomethingWentWrong: - EN: "Something went wrong :confused:" - CHDE: "Öppis isch schief gange :confused:" -httpErrors: - 403: - EN: "Seems like i don't have enough permission to that :confused:" - CHDE: "Gseht danach us das ich nid gnueg recht han zum das mache :confused:" \ No newline at end of file diff --git a/tests/Core/Localization/TranslationGuildContext.test.cs b/tests/Core/Localization/TranslationGuildContext.test.cs deleted file mode 100644 index 4aaca16..0000000 --- a/tests/Core/Localization/TranslationGuildContext.test.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using Geekbot.Core.Localization; -using Moq; -using Xunit; - -namespace Tests.Core.Localization -{ - public class TranslationGuildContext_test - { - public class FormatDateTimeAsRemainingTestDto - { - public DateTimeOffset DateTime { get; set; } - public string Expected { get; set; } - } - - public static TestData FormatDateTimeAsRemainingData => - new TestData - { - { - "Wait for days", - new FormatDateTimeAsRemainingTestDto - { - DateTime = DateTimeOffset.Now.AddDays(5), - Expected = "4 days, 23 hours, 59 minutes and 59 seconds" - } - }, - { - "Wait for minutes", - new FormatDateTimeAsRemainingTestDto - { - DateTime = DateTimeOffset.Now.AddMinutes(5), - Expected = "4 minutes and 59 seconds" - } - }, - { - "Wait for seconds", - new FormatDateTimeAsRemainingTestDto - { - DateTime = DateTimeOffset.Now.AddSeconds(5), - Expected = "4 seconds" - } - } - }; - - [Theory, MemberData(nameof(FormatDateTimeAsRemainingData))] - public void FormatDateTimeAsRemaining(string testName, FormatDateTimeAsRemainingTestDto testData) - { - var translationHandlerMock = new Mock(MockBehavior.Loose); - translationHandlerMock - .Setup(thm => thm.GetString("EN", "dateTime", "Days")) - .Returns("day|days"); - translationHandlerMock - .Setup(thm => thm.GetString("EN", "dateTime", "Hours")) - .Returns("hour|hours"); - translationHandlerMock - .Setup(thm => thm.GetString("EN", "dateTime", "Minutes")) - .Returns("minute|minutes"); - translationHandlerMock - .Setup(thm => thm.GetString("EN", "dateTime", "Seconds")) - .Returns("second|seconds"); - translationHandlerMock - .Setup(thm => thm.GetString("EN", "dateTime", "And")) - .Returns("and"); - - var context = new TranslationGuildContext(translationHandlerMock.Object, "EN", new Dictionary()); - var result = context.FormatDateTimeAsRemaining(testData.DateTime); - Assert.Equal(result, testData.Expected); - } - } -} \ No newline at end of file diff --git a/tests/Core/Localization/Translations.test.cs b/tests/Core/Localization/Translations.test.cs deleted file mode 100644 index d8a0879..0000000 --- a/tests/Core/Localization/Translations.test.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using FluentAssertions; -using Xunit; -using YamlDotNet.Core; -using YamlDotNet.Serialization; - -namespace Tests.Core.Localization -{ - public class Translations_test - { - [Fact] - public void TranslationsYamlIsValid() - { - // Read the file - var translationFile = File.ReadAllText(Path.GetFullPath("./../../../../src/Core/Localization/Translations.yml")); - - // Deserialize - var input = new StringReader(translationFile); - var mergingParser = new MergingParser(new Parser(input)); - var deserializer = new DeserializerBuilder().Build(); - var rawTranslations = deserializer.Deserialize>>>(mergingParser); - - // These languages must be supported - var supportedLanguages = new List - { - "EN", - "CHDE" - }; - - // Iterate every single key to make sure it's populated - foreach (var command in rawTranslations) - { - foreach (var str in command.Value) - { - str.Value.Select(e => e.Key).ToList().Should().BeEquivalentTo(supportedLanguages, str.Key); - foreach (var lang in str.Value) - { - lang.Value.Should().NotBeNullOrEmpty($"{command.Key} / {str.Key} / {lang.Key}"); - } - } - } - } - } -} \ No newline at end of file