2017-07-17 19:42:36 +00:00
|
|
|
|
using System;
|
2017-05-27 23:51:22 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
2017-07-17 19:42:36 +00:00
|
|
|
|
using Discord.WebSocket;
|
|
|
|
|
using NadekoBot.Services;
|
|
|
|
|
using NadekoBot.Services.Database.Models;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using NLog;
|
2017-05-27 23:51:22 +00:00
|
|
|
|
|
2017-07-17 19:42:36 +00:00
|
|
|
|
namespace NadekoBot.Modules.Utility.Services
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
2017-10-04 22:51:12 +00:00
|
|
|
|
public class ConverterService : INService, IUnloadableService
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
2017-06-23 23:41:24 +00:00
|
|
|
|
public List<ConvertUnit> Units { get; } = new List<ConvertUnit>();
|
2017-05-27 23:51:22 +00:00
|
|
|
|
private readonly Logger _log;
|
2017-06-23 23:41:24 +00:00
|
|
|
|
private readonly Timer _currencyUpdater;
|
2017-05-27 23:51:22 +00:00
|
|
|
|
private readonly TimeSpan _updateInterval = new TimeSpan(12, 0, 0);
|
2017-05-29 04:13:22 +00:00
|
|
|
|
private readonly DbService _db;
|
2017-07-10 19:35:45 +00:00
|
|
|
|
private readonly ConvertUnit[] fileData;
|
2017-05-27 23:51:22 +00:00
|
|
|
|
|
2017-06-23 23:41:24 +00:00
|
|
|
|
public ConverterService(DiscordSocketClient client, DbService db)
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
|
|
|
|
_log = LogManager.GetCurrentClassLogger();
|
|
|
|
|
_db = db;
|
|
|
|
|
|
2017-07-05 14:41:51 +00:00
|
|
|
|
if (client.ShardId == 0)
|
|
|
|
|
{
|
|
|
|
|
try
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
2017-07-10 19:35:45 +00:00
|
|
|
|
fileData = JsonConvert.DeserializeObject<List<MeasurementUnit>>(
|
2017-07-05 14:41:51 +00:00
|
|
|
|
File.ReadAllText("data/units.json"))
|
|
|
|
|
.Select(u => new ConvertUnit()
|
|
|
|
|
{
|
|
|
|
|
Modifier = u.Modifier,
|
|
|
|
|
UnitType = u.UnitType,
|
|
|
|
|
InternalTrigger = string.Join("|", u.Triggers)
|
|
|
|
|
}).ToArray();
|
|
|
|
|
|
|
|
|
|
using (var uow = _db.UnitOfWork)
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
2017-07-05 14:41:51 +00:00
|
|
|
|
if (uow.ConverterUnits.Empty())
|
|
|
|
|
{
|
2017-07-10 19:35:45 +00:00
|
|
|
|
uow.ConverterUnits.AddRange(fileData);
|
2017-07-05 14:41:51 +00:00
|
|
|
|
|
|
|
|
|
Units = uow.ConverterUnits.GetAll().ToList();
|
|
|
|
|
uow.Complete();
|
|
|
|
|
}
|
2017-05-27 23:51:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-05 14:41:51 +00:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
_log.Warn("Could not load units: " + ex.Message);
|
|
|
|
|
}
|
2017-05-27 23:51:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-05 14:41:51 +00:00
|
|
|
|
_currencyUpdater = new Timer(async (shouldLoad) => await UpdateCurrency((bool)shouldLoad),
|
|
|
|
|
client.ShardId == 0,
|
|
|
|
|
TimeSpan.FromSeconds(1),
|
|
|
|
|
_updateInterval);
|
2017-05-27 23:51:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-23 23:41:24 +00:00
|
|
|
|
private async Task<Rates> GetCurrencyRates()
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
|
|
|
|
using (var http = new HttpClient())
|
|
|
|
|
{
|
|
|
|
|
var res = await http.GetStringAsync("http://api.fixer.io/latest").ConfigureAwait(false);
|
|
|
|
|
return JsonConvert.DeserializeObject<Rates>(res);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-23 23:41:24 +00:00
|
|
|
|
private async Task UpdateCurrency(bool shouldLoad)
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var unitTypeString = "currency";
|
2017-06-23 23:41:24 +00:00
|
|
|
|
if (shouldLoad)
|
2017-05-27 23:51:22 +00:00
|
|
|
|
{
|
2017-06-23 23:41:24 +00:00
|
|
|
|
var currencyRates = await GetCurrencyRates();
|
|
|
|
|
var baseType = new ConvertUnit()
|
|
|
|
|
{
|
|
|
|
|
Triggers = new[] { currencyRates.Base },
|
|
|
|
|
Modifier = decimal.One,
|
|
|
|
|
UnitType = unitTypeString
|
|
|
|
|
};
|
|
|
|
|
var range = currencyRates.ConversionRates.Select(u => new ConvertUnit()
|
|
|
|
|
{
|
|
|
|
|
InternalTrigger = u.Key,
|
|
|
|
|
Modifier = u.Value,
|
|
|
|
|
UnitType = unitTypeString
|
|
|
|
|
}).ToArray();
|
|
|
|
|
var toRemove = Units.Where(u => u.UnitType == unitTypeString);
|
2017-05-27 23:51:22 +00:00
|
|
|
|
|
2017-06-23 23:41:24 +00:00
|
|
|
|
using (var uow = _db.UnitOfWork)
|
|
|
|
|
{
|
2017-08-02 20:07:19 +00:00
|
|
|
|
if(toRemove.Any())
|
|
|
|
|
uow.ConverterUnits.RemoveRange(toRemove.ToArray());
|
2017-06-23 23:41:24 +00:00
|
|
|
|
uow.ConverterUnits.Add(baseType);
|
|
|
|
|
uow.ConverterUnits.AddRange(range);
|
2017-05-27 23:51:22 +00:00
|
|
|
|
|
2017-06-23 23:41:24 +00:00
|
|
|
|
await uow.CompleteAsync().ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
Units.RemoveAll(u => u.UnitType == unitTypeString);
|
|
|
|
|
Units.Add(baseType);
|
|
|
|
|
Units.AddRange(range);
|
2017-07-10 19:35:45 +00:00
|
|
|
|
Units.AddRange(fileData);
|
2017-06-23 23:41:24 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
using (var uow = _db.UnitOfWork)
|
|
|
|
|
{
|
|
|
|
|
Units.RemoveAll(u => u.UnitType == unitTypeString);
|
|
|
|
|
Units.AddRange(uow.ConverterUnits.GetAll().ToArray());
|
|
|
|
|
}
|
2017-05-27 23:51:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
_log.Warn("Failed updating currency. Ignore this.");
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-04 22:51:12 +00:00
|
|
|
|
|
|
|
|
|
public Task Unload()
|
|
|
|
|
{
|
|
|
|
|
_currencyUpdater.Change(Timeout.Infinite, Timeout.Infinite);
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
2017-05-27 23:51:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class MeasurementUnit
|
|
|
|
|
{
|
|
|
|
|
public List<string> Triggers { get; set; }
|
|
|
|
|
public string UnitType { get; set; }
|
|
|
|
|
public decimal Modifier { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Rates
|
|
|
|
|
{
|
|
|
|
|
public string Base { get; set; }
|
|
|
|
|
public DateTime Date { get; set; }
|
|
|
|
|
[JsonProperty("rates")]
|
|
|
|
|
public Dictionary<string, decimal> ConversionRates { get; set; }
|
|
|
|
|
}
|
|
|
|
|
}
|