Groudwork for multilanguage

This commit is contained in:
Runebaas 2017-11-15 01:08:20 +01:00
parent 6cef559601
commit 7584b09d35
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
4 changed files with 155 additions and 2 deletions

View file

@ -17,12 +17,14 @@ namespace Geekbot.net.Commands
private readonly IDatabase _redis; private readonly IDatabase _redis;
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly IErrorHandler _errorHandler; private readonly IErrorHandler _errorHandler;
private readonly ITranslationHandler _translation;
public Admin(IDatabase redis, DiscordSocketClient client, IErrorHandler errorHandler) public Admin(IDatabase redis, DiscordSocketClient client, IErrorHandler errorHandler, ITranslationHandler translationHandler)
{ {
_redis = redis; _redis = redis;
_client = client; _client = client;
_errorHandler = errorHandler; _errorHandler = errorHandler;
_translation = translationHandler;
} }
[Command("welcome", RunMode = RunMode.Async)] [Command("welcome", RunMode = RunMode.Async)]
@ -107,5 +109,28 @@ namespace Geekbot.net.Commands
_errorHandler.HandleCommandException(e, Context, "Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`"); _errorHandler.HandleCommandException(e, Context, "Modchannel doesn't seem to exist, please set one with `!admin modchannel [channelId]`");
} }
} }
[Command("setlang", RunMode = RunMode.Async)]
[Remarks(CommandCategories.Admin)]
[Summary("Change the bots language")]
public async Task setLanguage([Summary("language")] string languageRaw)
{
try
{
var language = languageRaw.ToUpper();
var success = _translation.SetLanguage(Context.Guild.Id, language);
if (success)
{
await ReplyAsync(_translation.GetString(Context.Guild.Id, "LanguageChanger", "Confirm"));
return;
}
await ReplyAsync(
$"That doesn't seem to be a supported language\r\nSupported Languages are {string.Join(", ", _translation.GetSupportedLanguages())}");
}
catch (Exception e)
{
_errorHandler.HandleCommandException(e, Context);
}
}
} }
} }

View file

@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Discord.WebSocket;
using Serilog;
using StackExchange.Redis;
namespace Geekbot.net.Lib
{
public class TranslationHandler : ITranslationHandler
{
private readonly ILogger _logger;
private readonly IDatabase _redis;
private Dictionary<string, Dictionary<string, Dictionary<string, string>>> _translations;
private Dictionary<ulong, string> _serverLanguages;
public List<string> _supportedLanguages;
public TranslationHandler(IReadOnlyCollection<SocketGuild> clientGuilds, IDatabase redis, ILogger logger)
{
_logger = logger;
_redis = redis;
_logger.Information("[Geekbot] Loading Translations");
LoadTranslations();
CheckSupportedLanguages();
LoadServerLanguages(clientGuilds);
}
private void LoadTranslations()
{
try
{
var translations = File.ReadAllText(Path.GetFullPath("./Storage/Translations.json"));
_translations =
Utf8Json.JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, Dictionary<string, string>>>>(
translations);
}
catch (Exception e)
{
_logger.Fatal(e, "Failed to load Translations");
Environment.Exit(110);
}
}
private void CheckSupportedLanguages()
{
try
{
_supportedLanguages = new List<string>();
foreach (var lang in _translations.First().Value.First().Value)
{
_supportedLanguages.Add(lang.Key);
}
}
catch (Exception e)
{
_logger.Fatal(e, "Failed to load Translations");
Environment.Exit(110);
}
}
private void LoadServerLanguages(IReadOnlyCollection<SocketGuild> clientGuilds)
{
_serverLanguages = new Dictionary<ulong, string>();
foreach (var guild in clientGuilds)
{
var language = _redis.HashGet($"{guild.Id}:Settings", "Language");
if (string.IsNullOrEmpty(language) || !_supportedLanguages.Contains(language))
{
_serverLanguages[guild.Id] = "EN";
}
else
{
_serverLanguages[guild.Id] = language.ToString();
}
}
}
public string GetString(ulong guildId, string command, string stringName)
{
var translation = _translations[command][stringName][_serverLanguages[guildId]];
if (!string.IsNullOrWhiteSpace(translation)) return translation;
translation = _translations[command][stringName]["EN"];
if (string.IsNullOrWhiteSpace(translation))
{
_logger.Warning($"No translation found for {command} - {stringName}");
}
return translation;
}
public bool SetLanguage(ulong guildId, string language)
{
try
{
if (!_supportedLanguages.Contains(language)) return false;
_redis.HashSet($"{guildId}:Settings", new HashEntry[]{ new HashEntry("Language", language), });
_serverLanguages[guildId] = language;
return true;
}
catch (Exception e)
{
_logger.Error(e, "[Geekbot] Error while changing language");
return false;
}
}
public List<string> GetSupportedLanguages()
{
return _supportedLanguages;
}
}
public interface ITranslationHandler
{
string GetString(ulong guildId, string command, string stringName);
bool SetLanguage(ulong guildId, string language);
List<string> GetSupportedLanguages();
}
}

View file

@ -153,9 +153,10 @@ namespace Geekbot.net
logger.Information($"[Geekbot] Now Connected as {client.CurrentUser.Username} to {client.Guilds.Count} Servers"); logger.Information($"[Geekbot] Now Connected as {client.CurrentUser.Username} to {client.Guilds.Count} Servers");
logger.Information("[Geekbot] Registering Stuff"); logger.Information("[Geekbot] Registering Stuff");
var translationHandler = new TranslationHandler(client.Guilds, redis, logger);
await commands.AddModulesAsync(Assembly.GetEntryAssembly()); await commands.AddModulesAsync(Assembly.GetEntryAssembly());
services.AddSingleton(commands); services.AddSingleton(commands);
services.AddSingleton<ITranslationHandler>(translationHandler);
services.AddSingleton<DiscordSocketClient>(client); services.AddSingleton<DiscordSocketClient>(client);
servicesProvider = services.BuildServiceProvider(); servicesProvider = services.BuildServiceProvider();

View file

@ -0,0 +1,8 @@
{
"LanguageChanger": {
"Confirm": {
"EN": "I will in english from now on",
"CHDE": "I werd ab jetzt in schwiizerdüütsch antworte, äuuä"
}
}
}