2017-11-15 01:08:20 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
2018-06-13 22:18:57 +02:00
|
|
|
|
using System.Threading.Tasks;
|
2017-11-16 00:51:36 +01:00
|
|
|
|
using Discord.Commands;
|
2018-05-26 02:33:45 +02:00
|
|
|
|
using Geekbot.net.Database;
|
|
|
|
|
using Geekbot.net.Database.Models;
|
|
|
|
|
using Geekbot.net.Lib.Extensions;
|
2018-05-03 00:56:06 +02:00
|
|
|
|
using Geekbot.net.Lib.Logger;
|
2018-04-30 23:44:19 +02:00
|
|
|
|
using Utf8Json;
|
2017-11-15 01:08:20 +01:00
|
|
|
|
|
2018-05-03 00:56:06 +02:00
|
|
|
|
namespace Geekbot.net.Lib.Localization
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
|
|
|
|
public class TranslationHandler : ITranslationHandler
|
|
|
|
|
{
|
2018-05-26 02:33:45 +02:00
|
|
|
|
private readonly DatabaseContext _database;
|
2018-01-20 01:38:49 +01:00
|
|
|
|
private readonly IGeekbotLogger _logger;
|
2018-05-26 02:55:18 +02:00
|
|
|
|
private readonly Dictionary<ulong, string> _serverLanguages;
|
2019-05-12 00:17:34 +02:00
|
|
|
|
private Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>> _translations;
|
2019-03-04 03:01:47 +01:00
|
|
|
|
|
2018-05-26 02:55:18 +02:00
|
|
|
|
public TranslationHandler(DatabaseContext database, IGeekbotLogger logger)
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2018-05-26 02:33:45 +02:00
|
|
|
|
_database = database;
|
2017-11-15 01:08:20 +01:00
|
|
|
|
_logger = logger;
|
2018-05-06 01:47:13 +02:00
|
|
|
|
_logger.Information(LogSource.Geekbot, "Loading Translations");
|
2017-11-15 01:08:20 +01:00
|
|
|
|
LoadTranslations();
|
2018-05-26 02:55:18 +02:00
|
|
|
|
_serverLanguages = new Dictionary<ulong, string>();
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LoadTranslations()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2018-05-03 00:56:06 +02:00
|
|
|
|
var translationFile = File.ReadAllText(Path.GetFullPath("./Lib/Localization/Translations.json"));
|
2019-05-12 00:17:34 +02:00
|
|
|
|
var rawTranslations = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>>>(translationFile);
|
|
|
|
|
var sortedPerLanguage = new Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>>();
|
2017-11-16 00:51:36 +01:00
|
|
|
|
foreach (var command in rawTranslations)
|
|
|
|
|
{
|
|
|
|
|
foreach (var str in command.Value)
|
|
|
|
|
{
|
|
|
|
|
foreach (var lang in str.Value)
|
|
|
|
|
{
|
|
|
|
|
if (!sortedPerLanguage.ContainsKey(lang.Key))
|
|
|
|
|
{
|
2019-05-12 00:17:34 +02:00
|
|
|
|
var commandDict = new Dictionary<string, Dictionary<string, List<string>>>();
|
|
|
|
|
var strDict = new Dictionary<string, List<string>>
|
2019-03-04 03:01:47 +01:00
|
|
|
|
{
|
|
|
|
|
{str.Key, lang.Value}
|
|
|
|
|
};
|
2017-11-16 00:51:36 +01:00
|
|
|
|
commandDict.Add(command.Key, strDict);
|
|
|
|
|
sortedPerLanguage.Add(lang.Key, commandDict);
|
|
|
|
|
}
|
|
|
|
|
if (!sortedPerLanguage[lang.Key].ContainsKey(command.Key))
|
|
|
|
|
{
|
2019-05-12 00:17:34 +02:00
|
|
|
|
var strDict = new Dictionary<string, List<string>>
|
|
|
|
|
{
|
|
|
|
|
{str.Key, lang.Value}
|
|
|
|
|
};
|
2017-11-16 00:51:36 +01:00
|
|
|
|
sortedPerLanguage[lang.Key].Add(command.Key, strDict);
|
|
|
|
|
}
|
2018-08-25 23:27:44 +02:00
|
|
|
|
if (!sortedPerLanguage[lang.Key][command.Key].ContainsKey(str.Key))
|
|
|
|
|
{
|
|
|
|
|
sortedPerLanguage[lang.Key][command.Key].Add(str.Key, lang.Value);
|
|
|
|
|
}
|
2017-11-16 00:51:36 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_translations = sortedPerLanguage;
|
|
|
|
|
|
2019-03-04 03:01:47 +01:00
|
|
|
|
SupportedLanguages = new List<string>();
|
2017-11-16 00:51:36 +01:00
|
|
|
|
foreach (var lang in sortedPerLanguage)
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2019-03-04 03:01:47 +01:00
|
|
|
|
SupportedLanguages.Add(lang.Key);
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2018-05-06 01:47:13 +02:00
|
|
|
|
_logger.Error(LogSource.Geekbot, "Failed to load Translations", e);
|
2018-05-06 02:00:45 +02:00
|
|
|
|
Environment.Exit(GeekbotExitCode.TranslationsFailed.GetHashCode());
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-16 00:51:36 +01:00
|
|
|
|
|
2018-06-13 22:18:57 +02:00
|
|
|
|
private async Task<string> GetServerLanguage(ulong guildId)
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2018-05-26 02:55:18 +02:00
|
|
|
|
try
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2018-05-26 02:55:18 +02:00
|
|
|
|
string lang;
|
|
|
|
|
try
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2018-05-26 02:55:18 +02:00
|
|
|
|
lang = _serverLanguages[guildId];
|
|
|
|
|
if (!string.IsNullOrEmpty(lang))
|
|
|
|
|
{
|
|
|
|
|
return lang;
|
|
|
|
|
}
|
|
|
|
|
throw new Exception();
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
2018-05-26 02:55:18 +02:00
|
|
|
|
catch
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2018-06-13 22:18:57 +02:00
|
|
|
|
lang = (await GetGuild(guildId)).Language ?? "EN";
|
2018-05-26 02:55:18 +02:00
|
|
|
|
_serverLanguages[guildId] = lang;
|
|
|
|
|
return lang;
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-26 02:55:18 +02:00
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2019-03-04 03:01:47 +01:00
|
|
|
|
_logger.Error(LogSource.Geekbot, "Could not get guild language", e);
|
2018-05-26 02:55:18 +02:00
|
|
|
|
return "EN";
|
|
|
|
|
}
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-06-13 22:18:57 +02:00
|
|
|
|
public async Task<string> GetString(ulong guildId, string command, string stringName)
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2019-05-12 00:17:34 +02:00
|
|
|
|
var serverLang = await GetServerLanguage(guildId);
|
|
|
|
|
return GetStrings(serverLang, command, stringName).First();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<string> GetStrings(string language, string command, string stringName)
|
|
|
|
|
{
|
|
|
|
|
var translation = _translations[language][command][stringName];
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(translation.First())) return translation;
|
2017-11-15 01:08:20 +01:00
|
|
|
|
translation = _translations[command][stringName]["EN"];
|
2019-05-12 00:17:34 +02:00
|
|
|
|
if (string.IsNullOrWhiteSpace(translation.First()))
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
2018-05-06 01:47:13 +02:00
|
|
|
|
_logger.Warning(LogSource.Geekbot, $"No translation found for {command} - {stringName}");
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
return translation;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-12 01:07:22 +02:00
|
|
|
|
private async Task<Dictionary<string, List<string>>> GetDict(ICommandContext context)
|
2017-11-16 00:51:36 +01:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var command = context.Message.Content.Split(' ').First().TrimStart('!').ToLower();
|
2019-03-04 03:01:47 +01:00
|
|
|
|
var serverLanguage = await GetServerLanguage(context.Guild?.Id ?? 0);
|
2019-05-12 01:07:22 +02:00
|
|
|
|
return _translations[serverLanguage][command];
|
2017-11-16 00:51:36 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2018-05-06 02:00:45 +02:00
|
|
|
|
_logger.Error(LogSource.Geekbot, "No translations for command found", e);
|
2019-05-12 01:07:22 +02:00
|
|
|
|
return new Dictionary<string, List<string>>();
|
2017-11-16 00:51:36 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-12 00:17:34 +02:00
|
|
|
|
|
|
|
|
|
public async Task<TranslationGuildContext> GetGuildContext(ICommandContext context)
|
|
|
|
|
{
|
|
|
|
|
var dict = await GetDict(context);
|
|
|
|
|
var language = await GetServerLanguage(context.Guild?.Id ?? 0);
|
|
|
|
|
return new TranslationGuildContext(this, language, dict);
|
|
|
|
|
}
|
2017-11-16 17:19:43 +01:00
|
|
|
|
|
2018-06-13 22:18:57 +02:00
|
|
|
|
public async Task<Dictionary<string, string>> GetDict(ICommandContext context, string command)
|
2017-11-16 17:19:43 +01:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2019-03-04 03:01:47 +01:00
|
|
|
|
var serverLanguage = await GetServerLanguage(context.Guild?.Id ?? 0);
|
2019-05-12 00:17:34 +02:00
|
|
|
|
return _translations[serverLanguage][command]
|
|
|
|
|
.ToDictionary(dict => dict.Key, dict => dict.Value.First());
|
2017-11-16 17:19:43 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2018-05-06 02:00:45 +02:00
|
|
|
|
_logger.Error(LogSource.Geekbot, "No translations for command found", e);
|
2017-11-16 17:19:43 +01:00
|
|
|
|
return new Dictionary<string, string>();
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-16 00:51:36 +01:00
|
|
|
|
|
2018-06-13 22:18:57 +02:00
|
|
|
|
public async Task<bool> SetLanguage(ulong guildId, string language)
|
2017-11-15 01:08:20 +01:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2019-03-04 03:01:47 +01:00
|
|
|
|
if (!SupportedLanguages.Contains(language)) return false;
|
2018-06-13 22:18:57 +02:00
|
|
|
|
var guild = await GetGuild(guildId);
|
2018-05-26 02:33:45 +02:00
|
|
|
|
guild.Language = language;
|
|
|
|
|
_database.GuildSettings.Update(guild);
|
2017-11-15 01:08:20 +01:00
|
|
|
|
_serverLanguages[guildId] = language;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2018-05-06 01:47:13 +02:00
|
|
|
|
_logger.Error(LogSource.Geekbot, "Error while changing language", e);
|
2017-11-15 01:08:20 +01:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 03:01:47 +01:00
|
|
|
|
public List<string> SupportedLanguages { get; private set; }
|
2018-05-26 02:33:45 +02:00
|
|
|
|
|
2018-06-13 22:18:57 +02:00
|
|
|
|
private async Task<GuildSettingsModel> GetGuild(ulong guildId)
|
2018-05-26 02:33:45 +02:00
|
|
|
|
{
|
|
|
|
|
var guild = _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong()));
|
|
|
|
|
if (guild != null) return guild;
|
|
|
|
|
_database.GuildSettings.Add(new GuildSettingsModel
|
|
|
|
|
{
|
|
|
|
|
GuildId = guildId.AsLong()
|
|
|
|
|
});
|
2018-06-13 22:18:57 +02:00
|
|
|
|
await _database.SaveChangesAsync();
|
2018-05-26 02:33:45 +02:00
|
|
|
|
return _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildId.AsLong()));
|
|
|
|
|
}
|
2017-11-15 01:08:20 +01:00
|
|
|
|
}
|
|
|
|
|
}
|