diff --git a/NadekoBot/Modules/Search/Commands/ConverterCommand.cs b/NadekoBot/Modules/Search/Commands/ConverterCommand.cs new file mode 100644 index 00000000..bb08c5af --- /dev/null +++ b/NadekoBot/Modules/Search/Commands/ConverterCommand.cs @@ -0,0 +1,162 @@ +using Discord.Commands; +using NadekoBot.Commands; +using ScaredFingers.UnitsConversion; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; + +namespace NadekoBot.Modules.Search.Commands +{ + class ConverterCommand : DiscordCommand + { + + public ConverterCommand(DiscordModule module) : base(module) + { + if (unitTables == null) + { + CultureInfo ci = new CultureInfo("en-US"); + Thread.CurrentThread.CurrentCulture = ci; + unitTables = new List(); + unitTables.Add(UnitTable.LengthTable); + unitTables.Add(UnitTable.TemperatureTable); + unitTables.Add(UnitTable.VolumeTable); + unitTables.Add(UnitTable.WeightTable); + reInitCurrencyConverterTable(); + } + + } + + + internal override void Init(CommandGroupBuilder cgb) + { + cgb.CreateCommand(Module.Prefix + "convert") + .Description("Convert quantities from>to. Like `~convert m>km 1000`") + .Parameter("from-to", ParameterType.Required) + .Parameter("quantity", ParameterType.Optional) + .Do(ConvertFunc()); + cgb.CreateCommand(Module.Prefix + "convertlist") + .Description("List of the convertable dimensions and currencies.") + .Do(ConvertListFunc()); + } + + private Func ConvertListFunc() => + async e => + { + reInitCurrencyConverterTable(); + string msg = ""; + foreach (var tmpTable in unitTables) + { + int i = 1; + while (tmpTable.IsKnownUnit(i)) + { + msg += tmpTable.GetUnitName(i) + " (" + tmpTable.GetUnitSymbol(i) + "); "; + i++; + } + msg += "\n"; + } + foreach (var curr in exchangeRateProvider.Currencies) + { + msg += curr + "; "; + } + + await e.Channel.SendMessage(msg); + }; + + private Func ConvertFunc() => + async e => + { + try + { + await e.Channel.SendIsTyping(); + + string from = e.GetArg("from-to").ToLowerInvariant().Split('>')[0]; + string to = e.GetArg("from-to").ToLowerInvariant().Split('>')[1]; + + float quantity = 1.0f; + if (!float.TryParse(e.GetArg("quantity"), out quantity)) + { + quantity = 1.0f; + } + + int fromCode, toCode = 0; + UnitTable table = null; + ResolveUnitCodes(from, to, out table, out fromCode, out toCode); + + if (table != null) + { + Unit inUnit = new Unit(fromCode, quantity, table); + Unit outUnit = inUnit.Convert(toCode); + await e.Channel.SendMessage(inUnit.ToString() + " = " + outUnit.ToString()); + } + else + { + reInitCurrencyConverterTable(); + Unit inUnit = currTable.CreateUnit(quantity, from.ToUpperInvariant()); + Unit outUnit = inUnit.Convert(currTable.CurrencyCode(to.ToUpperInvariant())); + await e.Channel.SendMessage(inUnit.ToString() + " = " + outUnit.ToString()); + } + } + catch //(Exception ex) + { + //Console.WriteLine(ex.ToString()); + await e.Channel.SendMessage("Bad input format, or sth went wrong... Try to list them with `" + Module.Prefix + "`convertlist"); + } + }; + + private void reInitCurrencyConverterTable() + { + if (lastChanged == null || lastChanged.DayOfYear != DateTime.Now.DayOfYear) + { + exchangeRateProvider = new WebExchangeRatesProvider(); + currTable = new CurrencyExchangeTable(exchangeRateProvider); + lastChanged = DateTime.Now; + } + } + + private void ResolveUnitCodes(string from, string to, out UnitTable table, out int fromCode, out int toCode) + { + foreach (var tmpTable in unitTables) + { + int f = LookupUnit(tmpTable, from); + int t = LookupUnit(tmpTable, to); + if (f > 0 && t > 0) + { + table = tmpTable; + fromCode = f; + toCode = t; + return; + } + } + table = null; + fromCode = 0; + toCode = 0; + } + + private int LookupUnit(UnitTable table, string lookup) + { + string wellformedLookup = lookup.ToLowerInvariant().Replace("°", ""); + int i = 1; + while (table.IsKnownUnit(i)) + { + if (wellformedLookup == table.GetUnitName(i).ToLowerInvariant().Replace("°", "") || + wellformedLookup == table.GetUnitPlural(i).ToLowerInvariant().Replace("°", "") || + wellformedLookup == table.GetUnitSymbol(i).ToLowerInvariant().Replace("°", "")) + { + return i; + } + i++; + } + return 0; + } + + private static List unitTables; + + private static CurrencyExchangeRatesProvider exchangeRateProvider; + + private static CurrencyExchangeTable currTable; + + private static DateTime lastChanged; + } +} diff --git a/NadekoBot/Modules/Searches.cs b/NadekoBot/Modules/Searches.cs index 0693141e..8a522423 100644 --- a/NadekoBot/Modules/Searches.cs +++ b/NadekoBot/Modules/Searches.cs @@ -5,6 +5,7 @@ using NadekoBot.Classes.IMDB; using NadekoBot.Classes.JSONModels; using NadekoBot.Commands; using NadekoBot.Extensions; +using NadekoBot.Modules.Search.Commands; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -23,6 +24,7 @@ namespace NadekoBot.Modules { commands.Add(new LoLCommands(this)); commands.Add(new StreamNotifications(this)); + commands.Add(new ConverterCommand(this)); rng = new Random(); } diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj index d17ece46..4d233b8c 100644 --- a/NadekoBot/NadekoBot.csproj +++ b/NadekoBot/NadekoBot.csproj @@ -97,6 +97,10 @@ ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll True + + False + lib\ScaredFingers.UnitsConversion.dll + @@ -219,6 +223,7 @@ + @@ -480,6 +485,10 @@ Discord.Net + + + +