Reenabled converter commands. Improved rewards reload on bots with multiple shards.
This commit is contained in:
		@@ -1,94 +1,93 @@
 | 
			
		||||
//using Discord;
 | 
			
		||||
//using Discord.Commands;
 | 
			
		||||
//using NadekoBot.Attributes;
 | 
			
		||||
//using NadekoBot.Extensions;
 | 
			
		||||
//using NadekoBot.Services.Utility;
 | 
			
		||||
//using System;
 | 
			
		||||
//using System.Linq;
 | 
			
		||||
//using System.Threading.Tasks;
 | 
			
		||||
////todo Rewrite
 | 
			
		||||
//namespace NadekoBot.Modules.Utility
 | 
			
		||||
//{
 | 
			
		||||
//    public partial class Utility
 | 
			
		||||
//    {
 | 
			
		||||
//        [Group]
 | 
			
		||||
//        public class UnitConverterCommands : NadekoSubmodule
 | 
			
		||||
//        {
 | 
			
		||||
//            private readonly ConverterService _service;
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services.Utility;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
namespace NadekoBot.Modules.Utility
 | 
			
		||||
{
 | 
			
		||||
    public partial class Utility
 | 
			
		||||
    {
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class UnitConverterCommands : NadekoSubmodule
 | 
			
		||||
        {
 | 
			
		||||
            private readonly ConverterService _service;
 | 
			
		||||
 | 
			
		||||
//            public UnitConverterCommands(ConverterService service)
 | 
			
		||||
//            {
 | 
			
		||||
//                _service = service;
 | 
			
		||||
//            }
 | 
			
		||||
            public UnitConverterCommands(ConverterService service)
 | 
			
		||||
            {
 | 
			
		||||
                _service = service;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
//            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
//            public async Task ConvertList()
 | 
			
		||||
//            {
 | 
			
		||||
//                var res = _service.Units.GroupBy(x => x.UnitType)
 | 
			
		||||
//                               .Aggregate(new EmbedBuilder().WithTitle(GetText("convertlist"))
 | 
			
		||||
//                                                            .WithColor(NadekoBot.OkColor),
 | 
			
		||||
//                                          (embed, g) => embed.AddField(efb =>
 | 
			
		||||
//                                                                         efb.WithName(g.Key.ToTitleCase())
 | 
			
		||||
//                                                                         .WithValue(String.Join(", ", g.Select(x => x.Triggers.FirstOrDefault())
 | 
			
		||||
//                                                                                                       .OrderBy(x => x)))));
 | 
			
		||||
//                await Context.Channel.EmbedAsync(res);
 | 
			
		||||
//            }
 | 
			
		||||
//            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
//            public async Task Convert(string origin, string target, decimal value)
 | 
			
		||||
//            {
 | 
			
		||||
//                var originUnit = _service.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(origin.ToLowerInvariant()));
 | 
			
		||||
//                var targetUnit = _service.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant()));
 | 
			
		||||
//                if (originUnit == null || targetUnit == null)
 | 
			
		||||
//                {
 | 
			
		||||
//                    await ReplyErrorLocalized("convert_not_found", Format.Bold(origin), Format.Bold(target)).ConfigureAwait(false);
 | 
			
		||||
//                    return;
 | 
			
		||||
//                }
 | 
			
		||||
//                if (originUnit.UnitType != targetUnit.UnitType)
 | 
			
		||||
//                {
 | 
			
		||||
//                    await ReplyErrorLocalized("convert_type_error", Format.Bold(originUnit.Triggers.First()), Format.Bold(targetUnit.Triggers.First())).ConfigureAwait(false);
 | 
			
		||||
//                    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 = 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);
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            public async Task ConvertList()
 | 
			
		||||
            {
 | 
			
		||||
                var res = _service.Units.GroupBy(x => x.UnitType)
 | 
			
		||||
                               .Aggregate(new EmbedBuilder().WithTitle(GetText("convertlist"))
 | 
			
		||||
                                                            .WithColor(NadekoBot.OkColor),
 | 
			
		||||
                                          (embed, g) => embed.AddField(efb =>
 | 
			
		||||
                                                                         efb.WithName(g.Key.ToTitleCase())
 | 
			
		||||
                                                                         .WithValue(String.Join(", ", g.Select(x => x.Triggers.FirstOrDefault())
 | 
			
		||||
                                                                                                       .OrderBy(x => x)))));
 | 
			
		||||
                await Context.Channel.EmbedAsync(res);
 | 
			
		||||
            }
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            public async Task Convert(string origin, string target, decimal value)
 | 
			
		||||
            {
 | 
			
		||||
                var originUnit = _service.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(origin.ToLowerInvariant()));
 | 
			
		||||
                var targetUnit = _service.Units.Find(x => x.Triggers.Select(y => y.ToLowerInvariant()).Contains(target.ToLowerInvariant()));
 | 
			
		||||
                if (originUnit == null || targetUnit == null)
 | 
			
		||||
                {
 | 
			
		||||
                    await ReplyErrorLocalized("convert_not_found", Format.Bold(origin), Format.Bold(target)).ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (originUnit.UnitType != targetUnit.UnitType)
 | 
			
		||||
                {
 | 
			
		||||
                    await ReplyErrorLocalized("convert_type_error", Format.Bold(originUnit.Triggers.First()), Format.Bold(targetUnit.Triggers.First())).ConfigureAwait(false);
 | 
			
		||||
                    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 = 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 Context.Channel.SendConfirmAsync(GetText("convert", value, (originUnit.Triggers.First()).SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2)));
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
                await Context.Channel.SendConfirmAsync(GetText("convert", value, (originUnit.Triggers.First()).SnPl(value.IsInteger() ? (int)value : 2), res, (targetUnit.Triggers.First() + "s").SnPl(res.IsInteger() ? (int)res : 2)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -290,7 +290,10 @@ namespace NadekoBot
 | 
			
		||||
 | 
			
		||||
            Task SetClientReady()
 | 
			
		||||
            {
 | 
			
		||||
                clientReady.TrySetResult(true);
 | 
			
		||||
                var _ = Task.Run(() =>
 | 
			
		||||
                {
 | 
			
		||||
                    clientReady.TrySetResult(true);
 | 
			
		||||
                });
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -90,5 +90,6 @@
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Folder Include="Modules\Music\Classes\" />
 | 
			
		||||
    <Folder Include="Utility\Services\" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -126,7 +126,6 @@ namespace NadekoBot.Services.Impl
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            //todo carbonitex update
 | 
			
		||||
            if (sc != null)
 | 
			
		||||
            {
 | 
			
		||||
                _carbonitexTimer = new Timer(async (state) =>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
@@ -11,27 +13,29 @@ using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Utility
 | 
			
		||||
{
 | 
			
		||||
    //todo periodically load from the database, update only on shard 0
 | 
			
		||||
    public class ConverterService
 | 
			
		||||
    {
 | 
			
		||||
        public List<ConvertUnit> Units { get; set; } = new List<ConvertUnit>();
 | 
			
		||||
        public List<ConvertUnit> Units { get; } = new List<ConvertUnit>();
 | 
			
		||||
        private readonly Logger _log;
 | 
			
		||||
        private Timer _timer;
 | 
			
		||||
        private readonly Timer _currencyUpdater;
 | 
			
		||||
        private readonly Timer _currencyLoader;
 | 
			
		||||
        private readonly TimeSpan _updateInterval = new TimeSpan(12, 0, 0);
 | 
			
		||||
        private readonly DbService _db;
 | 
			
		||||
 | 
			
		||||
        public ConverterService(DbService db)
 | 
			
		||||
        public ConverterService(DiscordSocketClient client, DbService db)
 | 
			
		||||
        {
 | 
			
		||||
            _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
            _db = db;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var data = JsonConvert.DeserializeObject<List<MeasurementUnit>>(File.ReadAllText("data/units.json")).Select(u => new ConvertUnit()
 | 
			
		||||
                {
 | 
			
		||||
                    Modifier = u.Modifier,
 | 
			
		||||
                    UnitType = u.UnitType,
 | 
			
		||||
                    InternalTrigger = string.Join("|", u.Triggers)
 | 
			
		||||
                }).ToArray();
 | 
			
		||||
                var data = JsonConvert.DeserializeObject<List<MeasurementUnit>>(
 | 
			
		||||
                    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)
 | 
			
		||||
                {
 | 
			
		||||
@@ -48,10 +52,10 @@ namespace NadekoBot.Services.Utility
 | 
			
		||||
                _log.Warn("Could not load units: " + ex.Message);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _timer = new Timer(async (obj) => await UpdateCurrency(), null, _updateInterval, _updateInterval);
 | 
			
		||||
            _currencyUpdater = new Timer(async (shouldLoad) => await UpdateCurrency((bool)shouldLoad), client.ShardId == 0, _updateInterval, _updateInterval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<Rates> UpdateCurrencyRates()
 | 
			
		||||
        private async Task<Rates> GetCurrencyRates()
 | 
			
		||||
        {
 | 
			
		||||
            using (var http = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
@@ -60,38 +64,48 @@ namespace NadekoBot.Services.Utility
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task UpdateCurrency()
 | 
			
		||||
        private async Task UpdateCurrency(bool shouldLoad)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                var currencyRates = await UpdateCurrencyRates();
 | 
			
		||||
                var unitTypeString = "currency";
 | 
			
		||||
                var range = currencyRates.ConversionRates.Select(u => new ConvertUnit()
 | 
			
		||||
                if (shouldLoad)
 | 
			
		||||
                {
 | 
			
		||||
                    InternalTrigger = u.Key,
 | 
			
		||||
                    Modifier = u.Value,
 | 
			
		||||
                    UnitType = unitTypeString
 | 
			
		||||
                }).ToArray();
 | 
			
		||||
                var baseType = new ConvertUnit()
 | 
			
		||||
                {
 | 
			
		||||
                    Triggers = new[] { currencyRates.Base },
 | 
			
		||||
                    Modifier = decimal.One,
 | 
			
		||||
                    UnitType = unitTypeString
 | 
			
		||||
                };
 | 
			
		||||
                var toRemove = Units.Where(u => u.UnitType == unitTypeString);
 | 
			
		||||
                    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);
 | 
			
		||||
 | 
			
		||||
                using (var uow = _db.UnitOfWork)
 | 
			
		||||
                {
 | 
			
		||||
                    uow.ConverterUnits.RemoveRange(toRemove.ToArray());
 | 
			
		||||
                    uow.ConverterUnits.Add(baseType);
 | 
			
		||||
                    uow.ConverterUnits.AddRange(range);
 | 
			
		||||
                    using (var uow = _db.UnitOfWork)
 | 
			
		||||
                    {
 | 
			
		||||
                        uow.ConverterUnits.RemoveRange(toRemove.ToArray());
 | 
			
		||||
                        uow.ConverterUnits.Add(baseType);
 | 
			
		||||
                        uow.ConverterUnits.AddRange(range);
 | 
			
		||||
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                        await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    Units.RemoveAll(u => u.UnitType == unitTypeString);
 | 
			
		||||
                    Units.Add(baseType);
 | 
			
		||||
                    Units.AddRange(range);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    using (var uow = _db.UnitOfWork)
 | 
			
		||||
                    {
 | 
			
		||||
                        Units.RemoveAll(u => u.UnitType == unitTypeString);
 | 
			
		||||
                        Units.AddRange(uow.ConverterUnits.GetAll().ToArray());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Units.RemoveAll(u => u.UnitType == unitTypeString);
 | 
			
		||||
                Units.Add(baseType);
 | 
			
		||||
                Units.AddRange(range);
 | 
			
		||||
                _log.Info("Updated Currency");
 | 
			
		||||
            }
 | 
			
		||||
            catch
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,15 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using Discord.WebSocket;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Services.Utility.Patreon;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using NLog;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Immutable;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@@ -24,12 +27,13 @@ namespace NadekoBot.Services.Utility
 | 
			
		||||
        private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1);
 | 
			
		||||
        private readonly Logger _log;
 | 
			
		||||
 | 
			
		||||
        public readonly TimeSpan Interval = TimeSpan.FromMinutes(15);
 | 
			
		||||
        private IBotCredentials _creds;
 | 
			
		||||
        public readonly TimeSpan Interval = TimeSpan.FromMinutes(3);
 | 
			
		||||
        private readonly IBotCredentials _creds;
 | 
			
		||||
        private readonly DbService _db;
 | 
			
		||||
        private readonly CurrencyService _currency;
 | 
			
		||||
 | 
			
		||||
        public PatreonRewardsService(IBotCredentials creds, DbService db, CurrencyService currency)
 | 
			
		||||
        public PatreonRewardsService(IBotCredentials creds, DbService db, CurrencyService currency,
 | 
			
		||||
            DiscordSocketClient client)
 | 
			
		||||
        {
 | 
			
		||||
            _creds = creds;
 | 
			
		||||
            _db = db;
 | 
			
		||||
@@ -37,58 +41,63 @@ namespace NadekoBot.Services.Utility
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(creds.PatreonAccessToken))
 | 
			
		||||
                return;
 | 
			
		||||
            _log = LogManager.GetCurrentClassLogger();
 | 
			
		||||
            Updater = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, Interval);
 | 
			
		||||
            Updater = new Timer(async (load) => await RefreshPledges((bool)load), client.ShardId == 0, TimeSpan.Zero, Interval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task LoadPledges()
 | 
			
		||||
        public async Task RefreshPledges(bool shouldLoad)
 | 
			
		||||
        {
 | 
			
		||||
            LastUpdate = DateTime.UtcNow;
 | 
			
		||||
            await getPledgesLocker.WaitAsync(1000).ConfigureAwait(false);
 | 
			
		||||
            try
 | 
			
		||||
            if (shouldLoad)
 | 
			
		||||
            {
 | 
			
		||||
                var rewards = new List<PatreonPledge>();
 | 
			
		||||
                var users = new List<PatreonUser>();
 | 
			
		||||
                using (var http = new HttpClient())
 | 
			
		||||
                LastUpdate = DateTime.UtcNow;
 | 
			
		||||
                await getPledgesLocker.WaitAsync().ConfigureAwait(false);
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    http.DefaultRequestHeaders.Clear();
 | 
			
		||||
                    http.DefaultRequestHeaders.Add("Authorization", "Bearer " + _creds.PatreonAccessToken);
 | 
			
		||||
                    var data = new PatreonData()
 | 
			
		||||
                    var rewards = new List<PatreonPledge>();
 | 
			
		||||
                    var users = new List<PatreonUser>();
 | 
			
		||||
                    using (var http = new HttpClient())
 | 
			
		||||
                    {
 | 
			
		||||
                        Links = new PatreonDataLinks()
 | 
			
		||||
                        http.DefaultRequestHeaders.Clear();
 | 
			
		||||
                        http.DefaultRequestHeaders.Add("Authorization", "Bearer " + _creds.PatreonAccessToken);
 | 
			
		||||
                        var data = new PatreonData()
 | 
			
		||||
                        {
 | 
			
		||||
                            next = "https://api.patreon.com/oauth2/api/campaigns/334038/pledges"
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    do
 | 
			
		||||
                            Links = new PatreonDataLinks()
 | 
			
		||||
                            {
 | 
			
		||||
                                next = "https://api.patreon.com/oauth2/api/campaigns/334038/pledges"
 | 
			
		||||
                            }
 | 
			
		||||
                        };
 | 
			
		||||
                        do
 | 
			
		||||
                        {
 | 
			
		||||
                            var res = await http.GetStringAsync(data.Links.next)
 | 
			
		||||
                                .ConfigureAwait(false);
 | 
			
		||||
                            data = JsonConvert.DeserializeObject<PatreonData>(res);
 | 
			
		||||
                            var pledgers = data.Data.Where(x => x["type"].ToString() == "pledge");
 | 
			
		||||
                            rewards.AddRange(pledgers.Select(x => JsonConvert.DeserializeObject<PatreonPledge>(x.ToString()))
 | 
			
		||||
                                .Where(x => x.attributes.declined_since == null));
 | 
			
		||||
                            users.AddRange(data.Included
 | 
			
		||||
                                .Where(x => x["type"].ToString() == "user")
 | 
			
		||||
                                .Select(x => JsonConvert.DeserializeObject<PatreonUser>(x.ToString())));
 | 
			
		||||
                        } while (!string.IsNullOrWhiteSpace(data.Links.next));
 | 
			
		||||
                    }
 | 
			
		||||
                    Pledges = rewards.Join(users, (r) => r.relationships?.patron?.data?.id, (u) => u.id, (x, y) => new PatreonUserAndReward()
 | 
			
		||||
                    {
 | 
			
		||||
                        var res = await http.GetStringAsync(data.Links.next)
 | 
			
		||||
                            .ConfigureAwait(false);
 | 
			
		||||
                        data = JsonConvert.DeserializeObject<PatreonData>(res);
 | 
			
		||||
                        var pledgers = data.Data.Where(x => x["type"].ToString() == "pledge");
 | 
			
		||||
                        rewards.AddRange(pledgers.Select(x => JsonConvert.DeserializeObject<PatreonPledge>(x.ToString()))
 | 
			
		||||
                            .Where(x => x.attributes.declined_since == null));
 | 
			
		||||
                        users.AddRange(data.Included
 | 
			
		||||
                            .Where(x => x["type"].ToString() == "user")
 | 
			
		||||
                            .Select(x => JsonConvert.DeserializeObject<PatreonUser>(x.ToString())));
 | 
			
		||||
                    } while (!string.IsNullOrWhiteSpace(data.Links.next));
 | 
			
		||||
                        User = y,
 | 
			
		||||
                        Reward = x,
 | 
			
		||||
                    }).ToImmutableArray();
 | 
			
		||||
                    File.WriteAllText("./patreon_rewards.json", JsonConvert.SerializeObject(Pledges));
 | 
			
		||||
                }
 | 
			
		||||
                Pledges = rewards.Join(users, (r) => r.relationships?.patron?.data?.id, (u) => u.id, (x, y) => new PatreonUserAndReward()
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    User = y,
 | 
			
		||||
                    Reward = x,
 | 
			
		||||
                }).ToImmutableArray();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                _log.Warn(ex);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                var _ = Task.Run(async () =>
 | 
			
		||||
                    _log.Warn(ex);
 | 
			
		||||
                }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false);
 | 
			
		||||
                    getPledgesLocker.Release();
 | 
			
		||||
                });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                Pledges = JsonConvert.DeserializeObject<PatreonUserAndReward[]>(File.ReadAllText("./patreon_rewards.json"))
 | 
			
		||||
                    .ToImmutableArray();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user