From 7e23877fd8784082329c488a9c2daa1cb677bef3 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Sat, 1 Apr 2017 21:51:25 +0200 Subject: [PATCH] .clparew (Claim patreon rewards) added, needs testing --- .../Utility/Commands/PatreonCommands.cs | 324 +++++++++--------- .../Resources/CommandStrings.Designer.cs | 4 +- src/NadekoBot/Resources/CommandStrings.resx | 4 +- .../Resources/ResponseStrings.Designer.cs | 36 +- src/NadekoBot/Resources/ResponseStrings.resx | 18 +- .../Services/Database/Models/RewardedUser.cs | 20 +- 6 files changed, 204 insertions(+), 202 deletions(-) diff --git a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs index 76dd9ee0..6415dd8f 100644 --- a/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/PatreonCommands.cs @@ -1,181 +1,183 @@ -//using System.Collections.Generic; -//using System.Linq; -//using System.Net.Http; -//using System.Threading.Tasks; -//using Discord.Commands; -//using NadekoBot.Attributes; -//using NadekoBot.Modules.Utility.Models; -//using Newtonsoft.Json; -//using System.Threading; -//using System; -//using System.Collections.Immutable; -//using NadekoBot.Services; -//using NadekoBot.Services.Database.Models; -//using NadekoBot.Extensions; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Discord.Commands; +using NadekoBot.Attributes; +using NadekoBot.Modules.Utility.Models; +using Newtonsoft.Json; +using System.Threading; +using System; +using System.Collections.Immutable; +using NadekoBot.Services; +using NadekoBot.Services.Database.Models; +using NadekoBot.Extensions; -//namespace NadekoBot.Modules.Utility -//{ -// public partial class Utility -// { -// [Group] -// public class PatreonCommands : NadekoSubmodule -// { -// private static readonly PatreonThingy patreon; +namespace NadekoBot.Modules.Utility +{ + public partial class Utility + { + [Group] + public class PatreonCommands : NadekoSubmodule + { + private static readonly PatreonThingy patreon; -// static PatreonCommands() -// { -// patreon = PatreonThingy.Instance; -// } -// [NadekoCommand, Usage, Description, Aliases] -// public async Task ClaimPatreonRewards() -// { -// if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) -// return; -// if (DateTime.UtcNow.Day < 5) -// { -// await ReplyErrorLocalized("claimpatreon_too_early").ConfigureAwait(false); -// } -// int amount = 0; -// try -// { -// amount = await patreon.ClaimReward(Context.User.Id).ConfigureAwait(false); -// } -// catch (Exception ex) -// { -// _log.Warn(ex); -// } + static PatreonCommands() + { + patreon = PatreonThingy.Instance; + } + [NadekoCommand, Usage, Description, Aliases] + public async Task ClaimPatreonRewards() + { + if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) + return; + if (DateTime.UtcNow.Day < 5) + { + await ReplyErrorLocalized("clpa_too_early").ConfigureAwait(false); + } + int amount = 0; + try + { + amount = await patreon.ClaimReward(Context.User.Id).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn(ex); + } -// if (amount > 0) -// { -// await ReplyConfirmLocalized("claimpatreon_success", amount).ConfigureAwait(false); -// return; -// } + if (amount > 0) + { + await ReplyConfirmLocalized("clpa_success", amount + NadekoBot.BotConfig.CurrencySign).ConfigureAwait(false); + return; + } -// await Context.Channel.EmbedAsync(new Discord.EmbedBuilder().WithOkColor() -// .WithDescription(GetText("claimpatreon_fail")) -// .AddField(efb => efb.WithName("").WithValue("")) -// .AddField(efb => efb.WithName("").WithValue("")) -// .AddField(efb => efb.WithName("").WithValue(""))) -// .ConfigureAwait(false); + await Context.Channel.EmbedAsync(new Discord.EmbedBuilder().WithOkColor() + .WithDescription(GetText("clpa_fail")) + .AddField(efb => efb.WithName(GetText("clpa_fail_already_title")).WithValue(GetText("clpa_fail_already"))) + .AddField(efb => efb.WithName(GetText("clpa_fail_wait_title")).WithValue(GetText("clpa_fail_wait"))) + .AddField(efb => efb.WithName(GetText("clpa_fail_sup_title")).WithValue(GetText("clpa_fail_sup")))) + .ConfigureAwait(false); + } + } -// await ReplyErrorLocalized("claimpatreon_fail").ConfigureAwait(false); -// } -// } + public class PatreonThingy + { + public static PatreonThingy _instance = new PatreonThingy(); + public static PatreonThingy Instance => _instance; -// public class PatreonThingy -// { -// public static PatreonThingy _instance = new PatreonThingy(); -// public static PatreonThingy Instance => _instance; + private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1); -// private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1); + public ImmutableArray Pledges { get; private set; } -// public ImmutableArray Pledges { get; private set; } + private readonly Timer update; + private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); -// private readonly Timer update; -// private readonly SemaphoreSlim claimLockJustInCase = new SemaphoreSlim(1, 1); + private PatreonThingy() + { + if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) + return; + update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); + } -// private PatreonThingy() -// { -// if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.PatreonAccessToken)) -// return; -// update = new Timer(async (_) => await LoadPledges(), null, TimeSpan.Zero, TimeSpan.FromHours(3)); -// } + public async Task LoadPledges() + { + await getPledgesLocker.WaitAsync(1000).ConfigureAwait(false); + try + { + var rewards = new List(); + var users = new List(); + using (var http = new HttpClient()) + { + http.DefaultRequestHeaders.Clear(); + http.DefaultRequestHeaders.Add("Authorization", "Bearer " + NadekoBot.Credentials.PatreonAccessToken); + var data = new PatreonData() + { + 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(res); + var pledgers = data.Data.Where(x => x["type"].ToString() == "pledge"); + rewards.AddRange(pledgers.Select(x => JsonConvert.DeserializeObject(x.ToString())) + .Where(x => x.attributes.declined_since == null)); + users.AddRange(data.Included + .Where(x => x["type"].ToString() == "user") + .Select(x => JsonConvert.DeserializeObject(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() + { + User = y, + Reward = x, + }).ToImmutableArray(); + } + finally + { + var _ = Task.Run(async () => + { + await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false); + getPledgesLocker.Release(); + }); + } + } -// public async Task LoadPledges() -// { -// await getPledgesLocker.WaitAsync(1000).ConfigureAwait(false); -// try -// { -// var rewards = new List(); -// var users = new List(); -// using (var http = new HttpClient()) -// { -// http.DefaultRequestHeaders.Clear(); -// http.DefaultRequestHeaders.Add("Authorization", "Bearer " + NadekoBot.Credentials.PatreonAccessToken); -// var data = new PatreonData() -// { -// 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(res); -// var pledgers = data.Data.Where(x => x["type"].ToString() == "pledge"); -// rewards.AddRange(pledgers.Select(x => JsonConvert.DeserializeObject(x.ToString())) -// .Where(x => x.attributes.declined_since == null)); -// users.AddRange(data.Included -// .Where(x => x["type"].ToString() == "user") -// .Select(x => JsonConvert.DeserializeObject(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() -// { -// User = y, -// Reward = x, -// }).ToImmutableArray(); -// } -// finally -// { -// var _ = Task.Run(async () => -// { -// await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false); -// getPledgesLocker.Release(); -// }); + public async Task ClaimReward(ulong userId) + { + await claimLockJustInCase.WaitAsync(); + try + { + var data = Pledges.FirstOrDefault(x => x.User.id == userId.ToString()); -// } -// } + if (data == null) + return 0; -// public async Task ClaimReward(ulong userId) -// { -// await claimLockJustInCase.WaitAsync(); -// try -// { -// var data = Pledges.FirstOrDefault(x => x.User.id == userId.ToString()); + var amount = data.Reward.attributes.amount_cents; -// if (data == null) -// return 0; + using (var uow = DbHandler.UnitOfWork()) + { + var users = uow._context.Set(); + var usr = users.FirstOrDefault(x => x.UserId == userId); -// var amount = data.Reward.attributes.amount_cents; + if (usr == null) + { + users.Add(new RewardedUser() + { + UserId = userId, + LastReward = DateTime.UtcNow, + AmountRewardedThisMonth = amount, + }); -// using (var uow = DbHandler.UnitOfWork()) -// { -// var users = uow._context.Set(); -// var usr = users.FirstOrDefault(x => x.UserId == userId); + await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward", amount, uow).ConfigureAwait(false); -// if (usr == null) -// { -// users.Add(new RewardedUser() -// { -// UserId = userId, -// LastReward = DateTime.UtcNow, -// AmountRewardedThisMonth = amount, -// }); -// await uow.CompleteAsync().ConfigureAwait(false); -// return amount; -// } + await uow.CompleteAsync().ConfigureAwait(false); + return amount; + } -// if (usr.AmountRewardedThisMonth < amount) -// { -// var toAward = amount - usr.AmountRewardedThisMonth; + if (usr.AmountRewardedThisMonth < amount) + { + var toAward = amount - usr.AmountRewardedThisMonth; -// usr.LastReward = DateTime.UtcNow; -// usr.AmountRewardedThisMonth = amount; + usr.LastReward = DateTime.UtcNow; + usr.AmountRewardedThisMonth = amount; -// await uow.CompleteAsync().ConfigureAwait(false); -// return toAward; -// } -// } -// return 0; -// } -// finally -// { -// claimLockJustInCase.Release(); -// } -// } -// } -// } -//} + await CurrencyHandler.AddCurrencyAsync(usr.UserId, "Patreon reward", toAward, uow).ConfigureAwait(false); + + await uow.CompleteAsync().ConfigureAwait(false); + return toAward; + } + } + return 0; + } + finally + { + claimLockJustInCase.Release(); + } + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index ef7c365a..76dac5be 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -1707,7 +1707,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to claimpatreonrewards. + /// Looks up a localized string similar to clparew. /// public static string claimpatreonrewards_cmd { get { @@ -1716,7 +1716,7 @@ namespace NadekoBot.Resources { } /// - /// Looks up a localized string similar to If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. + /// Looks up a localized string similar to Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key.. /// public static string claimpatreonrewards_desc { get { diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 64236de1..f3662ef3 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -3322,10 +3322,10 @@ `{0}warnpunish 5 Ban` or `{0}warnpunish 3` - claimpatreonrewards + clparew - If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. + Claim patreon rewards. If you're subscribed to bot owner's patreon you can user this command to claim your rewards - assuming bot owner did setup has their patreon key. `{0}claimpatreonrewards` diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 5befa0b0..48394268 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -6028,81 +6028,81 @@ namespace NadekoBot.Resources { /// /// Looks up a localized string similar to Failed claiming rewards due to one of the following reasons:. /// - public static string utility_claimpatreon_fail { + public static string utility_clpa_fail { get { - return ResourceManager.GetString("utility_claimpatreon_fail", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail", resourceCulture); } } /// /// Looks up a localized string similar to Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge.. /// - public static string utility_claimpatreon_fail_already { + public static string utility_clpa_fail_already { get { - return ResourceManager.GetString("utility_claimpatreon_fail_already", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_already", resourceCulture); } } /// /// Looks up a localized string similar to Already rewarded. /// - public static string utility_claimpatreon_fail_already_title { + public static string utility_clpa_fail_already_title { get { - return ResourceManager.GetString("utility_claimpatreon_fail_already_title", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_already_title", resourceCulture); } } /// /// Looks up a localized string similar to In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link.. /// - public static string utility_claimpatreon_fail_sup { + public static string utility_clpa_fail_sup { get { - return ResourceManager.GetString("utility_claimpatreon_fail_sup", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_sup", resourceCulture); } } /// /// Looks up a localized string similar to Not supporting. /// - public static string utility_claimpatreon_fail_sup_title { + public static string utility_clpa_fail_sup_title { get { - return ResourceManager.GetString("utility_claimpatreon_fail_sup_title", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_sup_title", resourceCulture); } } /// /// Looks up a localized string similar to You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later.. /// - public static string utility_claimpatreon_fail_wait { + public static string utility_clpa_fail_wait { get { - return ResourceManager.GetString("utility_claimpatreon_fail_wait", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_wait", resourceCulture); } } /// /// Looks up a localized string similar to Wait some time. /// - public static string utility_claimpatreon_fail_wait_title { + public static string utility_clpa_fail_wait_title { get { - return ResourceManager.GetString("utility_claimpatreon_fail_wait_title", resourceCulture); + return ResourceManager.GetString("utility_clpa_fail_wait_title", resourceCulture); } } /// /// Looks up a localized string similar to You've received {0}. Thanks for supporting the project!. /// - public static string utility_claimpatreon_success { + public static string utility_clpa_success { get { - return ResourceManager.GetString("utility_claimpatreon_success", resourceCulture); + return ResourceManager.GetString("utility_clpa_success", resourceCulture); } } /// /// Looks up a localized string similar to Rewards can be claimed on or after 5th of each month.. /// - public static string utility_claimpatreon_too_early { + public static string utility_clpa_too_early { get { - return ResourceManager.GetString("utility_claimpatreon_too_early", resourceCulture); + return ResourceManager.GetString("utility_clpa_too_early", resourceCulture); } } diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 0a523218..105efa2b 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -2369,31 +2369,31 @@ Owner ID: {2} Slowmode will no longer ignore user {0} - + Failed claiming rewards due to one of the following reasons: - + Maybe you have already received your reward for this month. You can receive rewards only once a month unless you increase your pledge. - + Already rewarded - + In order to be eligible for the reward, you must support the project on patreon. Use {0} command to get the link. - + Not supporting - + You have to wait a few hours after making your pledge, if you didn't, waiut a bit and then try again later. - + Wait some time - + You've received {0}. Thanks for supporting the project! - + Rewards can be claimed on or after 5th of each month. \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/Models/RewardedUser.cs b/src/NadekoBot/Services/Database/Models/RewardedUser.cs index e71843b1..535f1354 100644 --- a/src/NadekoBot/Services/Database/Models/RewardedUser.cs +++ b/src/NadekoBot/Services/Database/Models/RewardedUser.cs @@ -1,11 +1,11 @@ -//using System; +using System; -//namespace NadekoBot.Services.Database.Models -//{ -// public class RewardedUser -// { -// public ulong UserId { get; set; } -// public int AmountRewardedThisMonth { get; set; } -// public DateTime LastReward { get; set; } -// } -//} +namespace NadekoBot.Services.Database.Models +{ + public class RewardedUser + { + public ulong UserId { get; set; } + public int AmountRewardedThisMonth { get; set; } + public DateTime LastReward { get; set; } + } +}