Delete the TranslationHandler and the old translations file. Refactor GeekbotCommandBase to get the server language from guild settings. Create DateLocalization to create a localized relative time remaining string.

This commit is contained in:
runebaas 2020-08-14 23:15:11 +02:00
parent 078c884df7
commit 33829e91bc
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
22 changed files with 156 additions and 579 deletions

View file

@ -14,7 +14,6 @@ using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Admin namespace Geekbot.Bot.Commands.Admin
{ {
@ -24,21 +23,18 @@ namespace Geekbot.Bot.Commands.Admin
public class Admin : GeekbotCommandBase public class Admin : GeekbotCommandBase
{ {
private readonly DiscordSocketClient _client; 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; _client = client;
_guildSettingsManager = guildSettingsManager;
} }
[Command("welcome", RunMode = RunMode.Async)] [Command("welcome", RunMode = RunMode.Async)]
[Summary("Set a Welcome Message (use '$user' to mention the new joined user).")] [Summary("Set a Welcome Message (use '$user' to mention the new joined user).")]
public async Task SetWelcomeMessage([Remainder, Summary("message")] string welcomeMessage) public async Task SetWelcomeMessage([Remainder, Summary("message")] string welcomeMessage)
{ {
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); GuildSettings.WelcomeMessage = welcomeMessage;
guild.WelcomeMessage = welcomeMessage; await GuildSettingsManager.UpdateSettings(GuildSettings);
await _guildSettingsManager.UpdateSettings(guild);
var formatedMessage = welcomeMessage.Replace("$user", Context.User.Mention); 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}"); 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 m = await channel.SendMessageAsync("...");
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); GuildSettings.WelcomeChannel = channel.Id.AsLong();
guild.WelcomeChannel = channel.Id.AsLong(); await GuildSettingsManager.UpdateSettings(GuildSettings);
await _guildSettingsManager.UpdateSettings(guild);
await m.DeleteAsync(); await m.DeleteAsync();
@ -74,9 +69,8 @@ namespace Geekbot.Bot.Commands.Admin
{ {
var m = await channel.SendMessageAsync("verifying..."); var m = await channel.SendMessageAsync("verifying...");
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); GuildSettings.ModChannel = channel.Id.AsLong();
guild.ModChannel = channel.Id.AsLong(); await GuildSettingsManager.UpdateSettings(GuildSettings);
await _guildSettingsManager.UpdateSettings(guild);
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("Successfully saved mod channel, you can now do the following"); sb.AppendLine("Successfully saved mod channel, you can now do the following");
@ -96,13 +90,12 @@ namespace Geekbot.Bot.Commands.Admin
{ {
try try
{ {
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); var modChannel = await GetModChannel(GuildSettings.ModChannel.AsUlong());
var modChannel = await GetModChannel(guild.ModChannel.AsUlong());
if (modChannel == null) return; if (modChannel == null) return;
guild.ShowLeave = !guild.ShowLeave; GuildSettings.ShowLeave = !GuildSettings.ShowLeave;
await _guildSettingsManager.UpdateSettings(guild); await GuildSettingsManager.UpdateSettings(GuildSettings);
await modChannel.SendMessageAsync(guild.ShowLeave await modChannel.SendMessageAsync(GuildSettings.ShowLeave
? "Saved - now sending messages here when someone leaves" ? "Saved - now sending messages here when someone leaves"
: "Saved - stopping sending messages here when someone leaves" : "Saved - stopping sending messages here when someone leaves"
); );
@ -119,13 +112,12 @@ namespace Geekbot.Bot.Commands.Admin
{ {
try try
{ {
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); var modChannel = await GetModChannel(GuildSettings.ModChannel.AsUlong());
var modChannel = await GetModChannel(guild.ModChannel.AsUlong());
if (modChannel == null) return; if (modChannel == null) return;
guild.ShowDelete = !guild.ShowDelete; GuildSettings.ShowDelete = !GuildSettings.ShowDelete;
await _guildSettingsManager.UpdateSettings(guild); await GuildSettingsManager.UpdateSettings(GuildSettings);
await modChannel.SendMessageAsync(guild.ShowDelete await modChannel.SendMessageAsync(GuildSettings.ShowDelete
? "Saved - now sending messages here when someone deletes a message" ? "Saved - now sending messages here when someone deletes a message"
: "Saved - stopping 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)] [Command("setlang", RunMode = RunMode.Async)]
[Summary("Change the bots language")] [Summary("Change the bots language")]
public async Task SetLanguage([Summary("language")] string languageRaw) public async Task SetLanguage([Summary("language")] string language)
{ {
try try
{ {
var language = languageRaw.ToUpper(); var availableLanguages = new List<string>();
var success = await Translations.SetLanguage(Context.Guild.Id, language); availableLanguages.Add("en-GB"); // default
if (success) availableLanguages.AddRange(GetAvailableCultures().Select(culture => culture.Name));
if (availableLanguages.Contains(language))
{ {
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); GuildSettings.Language = language;
guild.Language = language; await GuildSettingsManager.UpdateSettings(GuildSettings);
await _guildSettingsManager.UpdateSettings(guild);
if (language.ToLower() == "chde") Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language.ToLower() == "chde" ? "de-CH" : language);
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("de-ch");
}
await ReplyAsync(Localization.Admin.NewLanguageSet); await ReplyAsync(Localization.Admin.NewLanguageSet);
return; return;
} }
var available = new List<string>(); await ReplyAsync($"That doesn't seem to be a supported language\nSupported Languages are {string.Join(", ", availableLanguages)}");
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)}");
} }
catch (Exception e) catch (Exception e)
{ {
@ -177,9 +163,8 @@ namespace Geekbot.Bot.Commands.Admin
try try
{ {
var language = languageRaw.ToLower(); var language = languageRaw.ToLower();
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); GuildSettings.WikiLang = language;
guild.WikiLang = language; await GuildSettingsManager.UpdateSettings(GuildSettings);
await _guildSettingsManager.UpdateSettings(guild);
await ReplyAsync($"Now using the {language} wikipedia"); await ReplyAsync($"Now using the {language} wikipedia");
} }
@ -195,10 +180,10 @@ namespace Geekbot.Bot.Commands.Admin
{ {
try try
{ {
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); // var guild = _guildSettingsManager.GetSettings(Context.Guild.Id);
guild.Ping = !guild.Ping; GuildSettings.Ping = !GuildSettings.Ping;
await _guildSettingsManager.UpdateSettings(guild); await GuildSettingsManager.UpdateSettings(GuildSettings);
await ReplyAsync(guild.Ping ? "i will reply to ping now" : "No more pongs..."); await ReplyAsync(GuildSettings.Ping ? "i will reply to ping now" : "No more pongs...");
} }
catch (Exception e) catch (Exception e)
{ {
@ -212,10 +197,10 @@ namespace Geekbot.Bot.Commands.Admin
{ {
try try
{ {
var guild = _guildSettingsManager.GetSettings(Context.Guild.Id); // var guild = _guildSettingsManager.GetSettings(Context.Guild.Id);
guild.Hui = !guild.Hui; GuildSettings.Hui = !GuildSettings.Hui;
await _guildSettingsManager.UpdateSettings(guild); await GuildSettingsManager.UpdateSettings(GuildSettings);
await ReplyAsync(guild.Hui ? "i will reply to hui now" : "No more hui's..."); await ReplyAsync(GuildSettings.Hui ? "i will reply to hui now" : "No more hui's...");
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -3,8 +3,10 @@ using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using Geekbot.Core;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.GlobalSettings; using Geekbot.Core.GlobalSettings;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Logger; using Geekbot.Core.Logger;
using Geekbot.Core.UserRepository; using Geekbot.Core.UserRepository;
@ -12,20 +14,19 @@ namespace Geekbot.Bot.Commands.Admin.Owner
{ {
[Group("owner")] [Group("owner")]
[RequireOwner] [RequireOwner]
public class Owner : ModuleBase public class Owner : GeekbotCommandBase
{ {
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IErrorHandler _errorHandler;
private readonly IGlobalSettings _globalSettings; private readonly IGlobalSettings _globalSettings;
private readonly IGeekbotLogger _logger; private readonly IGeekbotLogger _logger;
private readonly IUserRepository _userRepository; 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; _client = client;
_logger = logger; _logger = logger;
_userRepository = userRepositry; _userRepository = userRepositry;
_errorHandler = errorHandler;
_globalSettings = globalSettings; _globalSettings = globalSettings;
} }
@ -73,7 +74,7 @@ namespace Geekbot.Bot.Commands.Admin.Owner
} }
catch (Exception e) catch (Exception e)
{ {
await _errorHandler.HandleCommandException(e, Context, await ErrorHandler.HandleCommandException(e, Context,
"Couldn't complete User Repository, see console for more info"); "Couldn't complete User Repository, see console for more info");
} }
} }
@ -89,7 +90,7 @@ namespace Geekbot.Bot.Commands.Admin.Owner
} }
catch (Exception e) catch (Exception e)
{ {
await _errorHandler.HandleCommandException(e, Context); await ErrorHandler.HandleCommandException(e, Context);
} }
} }
@ -105,7 +106,7 @@ namespace Geekbot.Bot.Commands.Admin.Owner
} }
catch (Exception e) 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) catch (Exception e)
{ {
await _errorHandler.HandleCommandException(e, Context); await ErrorHandler.HandleCommandException(e, Context);
} }
} }
} }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Net;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord; using Discord;
@ -11,7 +12,7 @@ using Geekbot.Core.Database;
using Geekbot.Core.Database.Models; using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.ReactionListener; using Geekbot.Core.ReactionListener;
namespace Geekbot.Bot.Commands.Admin namespace Geekbot.Bot.Commands.Admin
@ -23,7 +24,7 @@ namespace Geekbot.Bot.Commands.Admin
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
private readonly IReactionListener _reactionListener; 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; _database = database;
_reactionListener = reactionListener; _reactionListener = reactionListener;
@ -89,7 +90,14 @@ namespace Geekbot.Bot.Commands.Admin
} }
catch (HttpException e) 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) catch (Exception e)
{ {

View file

@ -2,13 +2,14 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands; using Discord.Commands;
using Geekbot.Bot.Utils;
using Geekbot.Core; using Geekbot.Core;
using Geekbot.Core.Database; using Geekbot.Core.Database;
using Geekbot.Core.Database.Models; using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.KvInMemoryStore; using Geekbot.Core.KvInMemoryStore;
using Geekbot.Core.Localization;
using Geekbot.Core.RandomNumberGenerator; using Geekbot.Core.RandomNumberGenerator;
namespace Geekbot.Bot.Commands.Games.Roll namespace Geekbot.Bot.Commands.Games.Roll
@ -19,7 +20,8 @@ namespace Geekbot.Bot.Commands.Games.Roll
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
private readonly IRandomNumberGenerator _randomNumberGenerator; 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; _kvInMemoryStore = kvInMemoryStore;
_database = database; _database = database;
@ -34,10 +36,9 @@ namespace Geekbot.Bot.Commands.Games.Roll
{ {
var number = _randomNumberGenerator.Next(1, 100); var number = _randomNumberGenerator.Next(1, 100);
int.TryParse(stuff, out var guess); int.TryParse(stuff, out var guess);
var transContext = await Translations.GetGuildContext(Context);
if (guess <= 100 && guess > 0) 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<RollTimeout>(kvKey); var prevRoll = _kvInMemoryStore.Get<RollTimeout>(kvKey);
@ -46,11 +47,11 @@ namespace Geekbot.Bot.Commands.Games.Roll
await ReplyAsync(string.Format( await ReplyAsync(string.Format(
Localization.Roll.NoPrevGuess, Localization.Roll.NoPrevGuess,
Context.Message.Author.Mention, Context.Message.Author.Mention,
transContext.FormatDateTimeAsRemaining(prevRoll.GuessedOn.AddDays(1)))); DateLocalization.FormatDateTimeAsRemaining(prevRoll.GuessedOn.AddDays(1))));
return; 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)); await ReplyAsync(string.Format(Localization.Roll.Rolled, Context.Message.Author.Mention, number, guess));
if (guess == number) if (guess == number)
@ -75,7 +76,7 @@ namespace Geekbot.Bot.Commands.Games.Roll
private async Task<RollsModel> GetUser(ulong userId) private async Task<RollsModel> 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; return user;
} }

View file

@ -8,7 +8,7 @@ using Geekbot.Core.Database;
using Geekbot.Core.Database.Models; using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.RandomNumberGenerator; using Geekbot.Core.RandomNumberGenerator;
namespace Geekbot.Bot.Commands.Randomness namespace Geekbot.Bot.Commands.Randomness
@ -18,7 +18,7 @@ namespace Geekbot.Bot.Commands.Randomness
private readonly IRandomNumberGenerator _randomNumberGenerator; private readonly IRandomNumberGenerator _randomNumberGenerator;
private readonly DatabaseContext _database; 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; _database = database;
_randomNumberGenerator = randomNumberGenerator; _randomNumberGenerator = randomNumberGenerator;

View file

@ -3,13 +3,14 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Geekbot.Bot.Utils;
using Geekbot.Core; using Geekbot.Core;
using Geekbot.Core.CommandPreconditions; using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database; using Geekbot.Core.Database;
using Geekbot.Core.Database.Models; using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.RandomNumberGenerator; using Geekbot.Core.RandomNumberGenerator;
namespace Geekbot.Bot.Commands.Rpg namespace Geekbot.Bot.Commands.Rpg
@ -22,7 +23,8 @@ namespace Geekbot.Bot.Commands.Rpg
private readonly DatabaseContext _database; private readonly DatabaseContext _database;
private readonly IRandomNumberGenerator _randomNumberGenerator; 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; _database = database;
_randomNumberGenerator = randomNumberGenerator; _randomNumberGenerator = randomNumberGenerator;
@ -34,12 +36,11 @@ namespace Geekbot.Bot.Commands.Rpg
{ {
try try
{ {
var transContext = await Translations.GetGuildContext(Context);
var actor = await GetUser(Context.User.Id); var actor = await GetUser(Context.User.Id);
if (actor.LastPayout.Value.AddDays(1).Date > DateTime.Now.Date) if (actor.LastPayout.Value.AddDays(1).Date > DateTime.Now.Date)
{ {
var formatedWaitTime = transContext.FormatDateTimeAsRemaining(DateTimeOffset.Now.AddDays(1).Date); var formattedWaitTime = DateLocalization.FormatDateTimeAsRemaining(DateTimeOffset.Now.AddDays(1).Date);
await ReplyAsync(string.Format(Localization.Cookies.WaitForMoreCookies, formatedWaitTime)); await ReplyAsync(string.Format(Localization.Cookies.WaitForMoreCookies, formattedWaitTime));
return; return;
} }
actor.Cookies += 10; actor.Cookies += 10;

View file

@ -1,17 +1,16 @@
using System; using System;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Geekbot.Bot.Utils;
using Geekbot.Core; using Geekbot.Core;
using Geekbot.Core.CommandPreconditions; using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database; using Geekbot.Core.Database;
using Geekbot.Core.Database.Models; using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
namespace Geekbot.Bot.Commands.User namespace Geekbot.Bot.Commands.User
{ {
@ -19,12 +18,10 @@ namespace Geekbot.Bot.Commands.User
public class Karma : GeekbotCommandBase public class Karma : GeekbotCommandBase
{ {
private readonly DatabaseContext _database; 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; _database = database;
_translations = translations;
} }
[Command("good", RunMode = RunMode.Async)] [Command("good", RunMode = RunMode.Async)]
@ -33,8 +30,6 @@ namespace Geekbot.Bot.Commands.User
{ {
try try
{ {
var transContext = await _translations.GetGuildContext(Context);
var actor = await GetUser(Context.User.Id); var actor = await GetUser(Context.User.Id);
if (user.Id == Context.User.Id) if (user.Id == Context.User.Id)
{ {
@ -42,7 +37,7 @@ namespace Geekbot.Bot.Commands.User
} }
else if (TimeoutFinished(actor.TimeOut)) 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)); await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime));
} }
else else
@ -81,8 +76,6 @@ namespace Geekbot.Bot.Commands.User
{ {
try try
{ {
var transContext = await _translations.GetGuildContext(Context);
var actor = await GetUser(Context.User.Id); var actor = await GetUser(Context.User.Id);
if (user.Id == Context.User.Id) if (user.Id == Context.User.Id)
{ {
@ -90,7 +83,7 @@ namespace Geekbot.Bot.Commands.User
} }
else if (TimeoutFinished(actor.TimeOut)) 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)); await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime));
} }
else else

View file

@ -10,8 +10,8 @@ using Geekbot.Core.Converters;
using Geekbot.Core.Database; using Geekbot.Core.Database;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Highscores; using Geekbot.Core.Highscores;
using Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.User.Ranking namespace Geekbot.Bot.Commands.User.Ranking
{ {
@ -21,7 +21,8 @@ namespace Geekbot.Bot.Commands.User.Ranking
private readonly IHighscoreManager _highscoreManager; private readonly IHighscoreManager _highscoreManager;
private readonly DatabaseContext _database; 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; _database = database;
_emojiConverter = emojiConverter; _emojiConverter = emojiConverter;

View file

@ -3,13 +3,13 @@ using System.Threading.Tasks;
using Discord.Commands; using Discord.Commands;
using Geekbot.Core; using Geekbot.Core;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
namespace Geekbot.Bot.Commands.Utils namespace Geekbot.Bot.Commands.Utils
{ {
public class Choose : GeekbotCommandBase public class Choose : GeekbotCommandBase
{ {
public Choose(IErrorHandler errorHandler, ITranslationHandler translation) : base(errorHandler, translation) public Choose(IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager)
{ {
} }

View file

@ -9,7 +9,7 @@ using Geekbot.Core.Database;
using Geekbot.Core.Database.Models; using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions; using Geekbot.Core.Extensions;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Polyfills; using Geekbot.Core.Polyfills;
using Geekbot.Core.RandomNumberGenerator; using Geekbot.Core.RandomNumberGenerator;
@ -23,7 +23,8 @@ namespace Geekbot.Bot.Commands.Utils.Quote
private readonly IRandomNumberGenerator _randomNumberGenerator; private readonly IRandomNumberGenerator _randomNumberGenerator;
private readonly bool _isDev; 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; _database = database;
_randomNumberGenerator = randomNumberGenerator; _randomNumberGenerator = randomNumberGenerator;

View file

@ -17,7 +17,6 @@ using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Highscores; using Geekbot.Core.Highscores;
using Geekbot.Core.KvInMemoryStore; using Geekbot.Core.KvInMemoryStore;
using Geekbot.Core.Levels; using Geekbot.Core.Levels;
using Geekbot.Core.Localization;
using Geekbot.Core.Logger; using Geekbot.Core.Logger;
using Geekbot.Core.MalClient; using Geekbot.Core.MalClient;
using Geekbot.Core.Media; using Geekbot.Core.Media;
@ -168,8 +167,7 @@ namespace Geekbot.Bot
var randomNumberGenerator = new RandomNumberGenerator(); var randomNumberGenerator = new RandomNumberGenerator();
var mediaProvider = new MediaProvider(_logger, randomNumberGenerator); var mediaProvider = new MediaProvider(_logger, randomNumberGenerator);
var kvMemoryStore = new KvInInMemoryStore(); var kvMemoryStore = new KvInInMemoryStore();
var translationHandler = new TranslationHandler(_logger, _guildSettingsManager); var errorHandler = new ErrorHandler(_logger, _runParameters, () => Localization.Internal.SomethingWentWrong);
var errorHandler = new ErrorHandler(_logger, translationHandler, _runParameters);
var diceParser = new DiceParser(randomNumberGenerator); var diceParser = new DiceParser(randomNumberGenerator);
services.AddSingleton(_userRepository); services.AddSingleton(_userRepository);
@ -186,7 +184,6 @@ namespace Geekbot.Bot
services.AddSingleton<IGlobalSettings>(_globalSettings); services.AddSingleton<IGlobalSettings>(_globalSettings);
services.AddSingleton<IErrorHandler>(errorHandler); services.AddSingleton<IErrorHandler>(errorHandler);
services.AddSingleton<IDiceParser>(diceParser); services.AddSingleton<IDiceParser>(diceParser);
services.AddSingleton<ITranslationHandler>(translationHandler);
services.AddSingleton<IReactionListener>(_reactionListener); services.AddSingleton<IReactionListener>(_reactionListener);
services.AddSingleton<IGuildSettingsManager>(_guildSettingsManager); services.AddSingleton<IGuildSettingsManager>(_guildSettingsManager);
services.AddSingleton(_client); services.AddSingleton(_client);

View file

@ -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];
}
}
}

View file

@ -31,10 +31,4 @@
<PackageReference Include="YamlDotNet" Version="6.0.0" /> <PackageReference Include="YamlDotNet" Version="6.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Localization\Translations.yml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project> </Project>

View file

@ -1,9 +1,6 @@
using System; using System;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands; using Discord.Commands;
using Discord.Net;
using Geekbot.Core.Localization;
using Geekbot.Core.Logger; using Geekbot.Core.Logger;
using SharpRaven; using SharpRaven;
using SharpRaven.Data; using SharpRaven.Data;
@ -14,14 +11,14 @@ namespace Geekbot.Core.ErrorHandling
public class ErrorHandler : IErrorHandler public class ErrorHandler : IErrorHandler
{ {
private readonly IGeekbotLogger _logger; private readonly IGeekbotLogger _logger;
private readonly ITranslationHandler _translation; private readonly Func<string> _getDefaultErrorText;
private readonly IRavenClient _raven; private readonly IRavenClient _raven;
private readonly bool _errorsInChat; private readonly bool _errorsInChat;
public ErrorHandler(IGeekbotLogger logger, ITranslationHandler translation, RunParameters runParameters) public ErrorHandler(IGeekbotLogger logger, RunParameters runParameters, Func<string> getDefaultErrorText)
{ {
_logger = logger; _logger = logger;
_translation = translation; _getDefaultErrorText = getDefaultErrorText;
_errorsInChat = runParameters.ExposeErrors; _errorsInChat = runParameters.ExposeErrors;
var sentryDsn = runParameters.SentryEndpoint; var sentryDsn = runParameters.SentryEndpoint;
@ -40,7 +37,9 @@ namespace Geekbot.Core.ErrorHandling
{ {
try 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); var errorObj = SimpleConextConverter.ConvertContext(context);
if (e.Message.Contains("50007")) return; if (e.Message.Contains("50007")) return;
if (e.Message.Contains("50013")) 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) private void ReportExternal(Exception e, MessageDto errorObj)
{ {
if (_raven == null) return; if (_raven == null) return;

View file

@ -1,13 +1,11 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord.Commands; using Discord.Commands;
using Discord.Net;
namespace Geekbot.Core.ErrorHandling namespace Geekbot.Core.ErrorHandling
{ {
public interface IErrorHandler public interface IErrorHandler
{ {
Task HandleCommandException(Exception e, ICommandContext context, string errorMessage = "def"); Task HandleCommandException(Exception e, ICommandContext context, string errorMessage = "def");
Task HandleHttpException(HttpException e, ICommandContext context);
} }
} }

View file

@ -1,26 +1,29 @@
using System.Globalization; using System.Globalization;
using System.Threading; using System.Threading;
using Discord.Commands; using Discord.Commands;
using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling; using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Localization; using Geekbot.Core.GuildSettingsManager;
namespace Geekbot.Core namespace Geekbot.Core
{ {
public class GeekbotCommandBase : ModuleBase<ICommandContext> public class GeekbotCommandBase : ModuleBase<ICommandContext>
{ {
protected readonly IGuildSettingsManager GuildSettingsManager;
protected GuildSettingsModel GuildSettings;
protected readonly IErrorHandler ErrorHandler; protected readonly IErrorHandler ErrorHandler;
protected readonly ITranslationHandler Translations;
protected GeekbotCommandBase(IErrorHandler errorHandler, ITranslationHandler translations) protected GeekbotCommandBase(IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager)
{ {
GuildSettingsManager = guildSettingsManager;
ErrorHandler = errorHandler; ErrorHandler = errorHandler;
Translations = translations;
} }
protected override void BeforeExecute(CommandInfo command) protected override void BeforeExecute(CommandInfo command)
{ {
base.BeforeExecute(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); Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language == "CHDE" ? "de-ch" : language);
} }
} }

View file

@ -1,17 +0,0 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Discord.Commands;
namespace Geekbot.Core.Localization
{
public interface ITranslationHandler
{
Task<string> GetString(ulong guildId, string command, string stringName);
string GetString(string language, string command, string stringName);
Task<Dictionary<string, string>> GetDict(ICommandContext context, string command);
Task<TranslationGuildContext> GetGuildContext(ICommandContext context);
Task<bool> SetLanguage(ulong guildId, string language);
List<string> SupportedLanguages { get; }
string GetServerLanguage(ulong guildId);
}
}

View file

@ -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<string, string> Dict { get; }
public TranslationGuildContext(ITranslationHandler translationHandler, string language, Dictionary<string, string> 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<bool> 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
}
}
}

View file

@ -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<ulong, string> _serverLanguages;
private Dictionary<string, Dictionary<string, Dictionary<string, string>>> _translations;
public TranslationHandler(IGeekbotLogger logger, IGuildSettingsManager guildSettingsManager)
{
_logger = logger;
_guildSettingsManager = guildSettingsManager;
_logger.Information(LogSource.Geekbot, "Loading Translations");
LoadTranslations();
_serverLanguages = new Dictionary<ulong, string>();
}
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<Dictionary<string, Dictionary<string, Dictionary<string, string>>>>(mergingParser);
// Sort
var sortedPerLanguage = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
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<string, Dictionary<string, string>>();
var strDict = new Dictionary<string, string>
{
{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<string, string>
{
{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<string>();
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<string> 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<Dictionary<string, string>> 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<string, string>();
}
}
public async Task<TranslationGuildContext> GetGuildContext(ICommandContext context)
{
var dict = await GetDict(context);
var language = GetServerLanguage(context.Guild?.Id ?? 0);
return new TranslationGuildContext(this, language, dict);
}
public async Task<Dictionary<string, string>> 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<string, string>();
}
}
public async Task<bool> 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<string> SupportedLanguages { get; private set; }
}
}

View file

@ -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:"

View file

@ -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<FormatDateTimeAsRemainingTestDto> FormatDateTimeAsRemainingData =>
new TestData<FormatDateTimeAsRemainingTestDto>
{
{
"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<ITranslationHandler>(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<string, string>());
var result = context.FormatDateTimeAsRemaining(testData.DateTime);
Assert.Equal(result, testData.Expected);
}
}
}

View file

@ -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<Dictionary<string, Dictionary<string, Dictionary<string, string>>>>(mergingParser);
// These languages must be supported
var supportedLanguages = new List<string>
{
"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}");
}
}
}
}
}
}