More restructuring

This commit is contained in:
Kwoth
2023-03-26 14:44:25 +02:00
parent 01f70f0a24
commit 308ba36b2e
319 changed files with 681 additions and 218 deletions

View File

@@ -1,99 +0,0 @@
#nullable disable
using NadekoBot.Common.ModuleBehaviors;
using NadekoBot.Modules.Utility.Common;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace NadekoBot.Modules.Utility.Services;
public class ConverterService : INService, IReadyExecutor
{
private static readonly TypedKey<List<ConvertUnit>> _convertKey =
new("convert:units");
private readonly TimeSpan _updateInterval = new(12, 0, 0);
private readonly DiscordSocketClient _client;
private readonly IBotCache _cache;
private readonly IHttpClientFactory _httpFactory;
public ConverterService(
DiscordSocketClient client,
IBotCache cache,
IHttpClientFactory factory)
{
_client = client;
_cache = cache;
_httpFactory = factory;
}
public async Task OnReadyAsync()
{
if (_client.ShardId != 0)
return;
using var timer = new PeriodicTimer(_updateInterval);
do
{
try
{
await UpdateCurrency();
}
catch
{
// ignored
}
} while (await timer.WaitForNextTickAsync());
}
private async Task<Rates> GetCurrencyRates()
{
using var http = _httpFactory.CreateClient();
var res = await http.GetStringAsync("https://convertapi.nadeko.bot/latest");
return JsonSerializer.Deserialize<Rates>(res);
}
private async Task UpdateCurrency()
{
var unitTypeString = "currency";
var currencyRates = await GetCurrencyRates();
var baseType = new ConvertUnit
{
Triggers = new[] { currencyRates.Base },
Modifier = decimal.One,
UnitType = unitTypeString
};
var units = currencyRates.ConversionRates.Select(u => new ConvertUnit
{
Triggers = new[] { u.Key },
Modifier = u.Value,
UnitType = unitTypeString
})
.ToList();
var stream = File.OpenRead("data/units.json");
var defaultUnits = await JsonSerializer.DeserializeAsync<ConvertUnit[]>(stream);
if(defaultUnits is not null)
units.AddRange(defaultUnits);
units.Add(baseType);
await _cache.AddAsync(_convertKey, units);
}
public async Task<IReadOnlyList<ConvertUnit>> GetUnitsAsync()
=> (await _cache.GetAsync(_convertKey)).TryGetValue(out var list)
? list
: Array.Empty<ConvertUnit>();
}
public class Rates
{
[JsonPropertyName("base")]
public string Base { get; set; }
[JsonPropertyName("date")]
public DateTime Date { get; set; }
[JsonPropertyName("rates")]
public Dictionary<string, decimal> ConversionRates { get; set; }
}

View File

@@ -1,96 +0,0 @@
#nullable disable
using NadekoBot.Modules.Utility.Services;
namespace NadekoBot.Modules.Utility;
public partial class Utility
{
[Group]
public partial class UnitConverterCommands : NadekoModule<ConverterService>
{
[Cmd]
public async Task ConvertList()
{
var units = await _service.GetUnitsAsync();
var embed = _eb.Create().WithTitle(GetText(strs.convertlist)).WithOkColor();
foreach (var g in units.GroupBy(x => x.UnitType))
{
embed.AddField(g.Key.ToTitleCase(),
string.Join(", ", g.Select(x => x.Triggers.FirstOrDefault()).OrderBy(x => x)));
}
await ctx.Channel.EmbedAsync(embed);
}
[Cmd]
[Priority(0)]
public async Task Convert(string origin, string target, decimal value)
{
var units = await _service.GetUnitsAsync();
var originUnit = units.FirstOrDefault(x
=> x.Triggers.Select(y => y.ToUpperInvariant()).Contains(origin.ToUpperInvariant()));
var targetUnit = units.FirstOrDefault(x
=> x.Triggers.Select(y => y.ToUpperInvariant()).Contains(target.ToUpperInvariant()));
if (originUnit is null || targetUnit is null)
{
await ReplyErrorLocalizedAsync(strs.convert_not_found(Format.Bold(origin), Format.Bold(target)));
return;
}
if (originUnit.UnitType != targetUnit.UnitType)
{
await ReplyErrorLocalizedAsync(strs.convert_type_error(Format.Bold(originUnit.Triggers.First()),
Format.Bold(targetUnit.Triggers.First())));
return;
}
decimal res;
if (originUnit.Triggers == targetUnit.Triggers)
res = value;
else if (originUnit.UnitType == "temperature")
{
//don't really care too much about efficiency, so just convert to Kelvin, then to target
switch (originUnit.Triggers.First().ToUpperInvariant())
{
case "C":
res = value + 273.15m; //celcius!
break;
case "F":
res = (value + 459.67m) * (5m / 9m);
break;
default:
res = value;
break;
}
//from Kelvin to target
switch (targetUnit.Triggers.First().ToUpperInvariant())
{
case "C":
res -= 273.15m; //celcius!
break;
case "F":
res = (res * (9m / 5m)) - 459.67m;
break;
}
}
else
{
if (originUnit.UnitType == "currency")
res = value * targetUnit.Modifier / originUnit.Modifier;
else
res = value * originUnit.Modifier / targetUnit.Modifier;
}
res = Math.Round(res, 4);
await SendConfirmAsync(GetText(strs.convert(value,
originUnit.Triggers.Last(),
res,
targetUnit.Triggers.Last())));
}
}
}