btcpayserver/BTCPayServer.Rating/CurrencyNameTable.cs

140 lines
5.0 KiB
C#
Raw Normal View History

2020-06-29 04:44:35 +02:00
using System;
2017-09-13 08:47:34 +02:00
using System.Collections.Generic;
2020-06-28 10:55:27 +02:00
using System.Globalization;
2017-09-13 08:47:34 +02:00
using System.IO;
using System.Linq;
2020-06-28 10:55:27 +02:00
using System.Reflection;
2017-09-13 08:47:34 +02:00
using System.Text;
2020-06-28 10:55:27 +02:00
using NBitcoin;
using Newtonsoft.Json;
2017-09-13 08:47:34 +02:00
namespace BTCPayServer.Services.Rates
2017-09-13 08:47:34 +02:00
{
public class CurrencyData
2017-09-13 08:47:34 +02:00
{
public string Name { get; set; }
public string Code { get; set; }
public int Divisibility { get; set; }
public string Symbol { get; set; }
public bool Crypto { get; set; }
}
public class CurrencyNameTable
{
public static CurrencyNameTable Instance = new();
public CurrencyNameTable()
{
_Currencies = LoadCurrency().ToDictionary(k => k.Code, StringComparer.InvariantCultureIgnoreCase);
}
static readonly Dictionary<string, IFormatProvider> _CurrencyProviders = new();
2018-05-20 16:37:18 +02:00
public NumberFormatInfo GetNumberFormatInfo(string currency, bool useFallback)
{
var data = GetCurrencyProvider(currency);
if (data is NumberFormatInfo nfi)
return nfi;
2018-05-20 16:22:20 +02:00
if (data is CultureInfo ci)
return ci.NumberFormat;
2018-05-20 16:37:18 +02:00
if (!useFallback)
return null;
2018-05-20 16:22:20 +02:00
return CreateFallbackCurrencyFormatInfo(currency);
}
2018-05-20 16:22:20 +02:00
private NumberFormatInfo CreateFallbackCurrencyFormatInfo(string currency)
{
2018-05-20 16:37:18 +02:00
var usd = GetNumberFormatInfo("USD", false);
2018-05-20 16:22:20 +02:00
var currencyInfo = (NumberFormatInfo)usd.Clone();
currencyInfo.CurrencySymbol = currency;
return currencyInfo;
}
public NumberFormatInfo GetNumberFormatInfo(string currency)
{
var curr = GetCurrencyProvider(currency);
if (curr is CultureInfo cu)
return cu.NumberFormat;
if (curr is NumberFormatInfo ni)
return ni;
return null;
}
2017-10-27 11:58:43 +02:00
public IFormatProvider GetCurrencyProvider(string currency)
{
lock (_CurrencyProviders)
{
if (_CurrencyProviders.Count == 0)
{
foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures).Where(c => !c.IsNeutralCulture))
{
try
{
_CurrencyProviders.TryAdd(new RegionInfo(culture.LCID).ISOCurrencySymbol, culture);
}
catch { }
}
foreach (var curr in _Currencies.Where(pair => pair.Value.Crypto))
{
2020-06-28 10:55:27 +02:00
AddCurrency(_CurrencyProviders, curr.Key, curr.Value.Divisibility, curr.Value.Symbol ?? curr.Value.Code);
}
2017-10-27 11:58:43 +02:00
}
2019-06-09 17:46:29 +02:00
return _CurrencyProviders.TryGet(currency.ToUpperInvariant());
2017-10-27 11:58:43 +02:00
}
}
private void AddCurrency(Dictionary<string, IFormatProvider> currencyProviders, string code, int divisibility, string symbol)
{
var culture = new CultureInfo("en-US");
var number = new NumberFormatInfo();
number.CurrencyDecimalDigits = divisibility;
number.CurrencySymbol = symbol;
number.CurrencyDecimalSeparator = culture.NumberFormat.CurrencyDecimalSeparator;
number.CurrencyGroupSeparator = culture.NumberFormat.CurrencyGroupSeparator;
number.CurrencyGroupSizes = culture.NumberFormat.CurrencyGroupSizes;
number.CurrencyNegativePattern = 8;
number.CurrencyPositivePattern = 3;
number.NegativeSign = culture.NumberFormat.NegativeSign;
currencyProviders.TryAdd(code, number);
}
2017-09-13 08:47:34 +02:00
readonly Dictionary<string, CurrencyData> _Currencies;
2017-09-13 08:47:34 +02:00
static CurrencyData[] LoadCurrency()
{
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BTCPayServer.Rating.Currencies.json");
string content = null;
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
content = reader.ReadToEnd();
}
var currencies = JsonConvert.DeserializeObject<CurrencyData[]>(content);
return currencies;
}
2017-09-13 08:47:34 +02:00
public IEnumerable<CurrencyData> Currencies => _Currencies.Values;
2018-05-20 16:37:18 +02:00
public CurrencyData GetCurrencyData(string currency, bool useFallback)
{
ArgumentNullException.ThrowIfNull(currency);
CurrencyData result;
if (!_Currencies.TryGetValue(currency.ToUpperInvariant(), out result))
2018-05-20 16:37:18 +02:00
{
if (useFallback)
2018-05-20 16:37:18 +02:00
{
var usd = GetCurrencyData("USD", false);
result = new CurrencyData()
{
Code = currency,
Crypto = true,
Name = currency,
Divisibility = usd.Divisibility
};
}
}
return result;
}
2017-09-13 08:47:34 +02:00
}
2017-09-13 08:47:34 +02:00
}