From 0b8c3b3f2bcdb91c49fbc6ba464c4040da4be672 Mon Sep 17 00:00:00 2001 From: Kwoth Date: Tue, 21 Dec 2021 05:16:53 +0100 Subject: [PATCH] Using humanizer to deal with time and string trimming in some cases. Removed unused methods. Currency output format improvement (will use guild locale now for some commands) --- src/NadekoBot/Common/Creds.cs | 1 - src/NadekoBot/GlobalUsings.cs | 2 + .../Administration/UserPunishCommands.cs | 7 +- src/NadekoBot/Modules/Gambling/Gambling.cs | 68 ++++++++++--------- .../Modules/Games/Common/Trivia/TriviaGame.cs | 2 +- .../Modules/Utility/RemindCommands.cs | 14 ++-- src/NadekoBot/NadekoBot.csproj | 1 + src/NadekoBot/Program.cs | 40 ++++++----- src/NadekoBot/Services/Impl/Localization.cs | 1 - src/NadekoBot/_Extensions/StringExtensions.cs | 39 +---------- 10 files changed, 76 insertions(+), 99 deletions(-) diff --git a/src/NadekoBot/Common/Creds.cs b/src/NadekoBot/Common/Creds.cs index 988ab31b9..e1f9d782c 100644 --- a/src/NadekoBot/Common/Creds.cs +++ b/src/NadekoBot/Common/Creds.cs @@ -111,7 +111,6 @@ Windows default public string ConnectionString { get; set; } } - // todo fixup patreon public sealed record PatreonSettings { public string ClientId { get; set; } diff --git a/src/NadekoBot/GlobalUsings.cs b/src/NadekoBot/GlobalUsings.cs index 22da4727e..e1d897d25 100644 --- a/src/NadekoBot/GlobalUsings.cs +++ b/src/NadekoBot/GlobalUsings.cs @@ -1,6 +1,8 @@ global using Serilog; +global using Humanizer; global using NadekoBot; + global using NadekoBot.Services; global using NadekoBot.Common; global using NadekoBot.Common.Attributes; diff --git a/src/NadekoBot/Modules/Administration/UserPunishCommands.cs b/src/NadekoBot/Modules/Administration/UserPunishCommands.cs index 77b5bb4a6..b78652ac9 100644 --- a/src/NadekoBot/Modules/Administration/UserPunishCommands.cs +++ b/src/NadekoBot/Modules/Administration/UserPunishCommands.cs @@ -1,4 +1,5 @@ using CommandLine; +using Humanizer.Localisation; using NadekoBot.Common.TypeReaders.Models; using NadekoBot.Services.Database.Models; using NadekoBot.Extensions; @@ -463,7 +464,11 @@ public partial class Administration .WithTitle("⛔️ " + GetText(strs.banned_user)) .AddField(GetText(strs.username), user.ToString(), true) .AddField("ID", user.Id.ToString(), true) - .AddField(GetText(strs.duration), $"{time.Time.Days}d {time.Time.Hours}h {time.Time.Minutes}m", true); + .AddField(GetText(strs.duration), + time.Time.Humanize(3, + minUnit: TimeUnit.Minute, + culture: _cultureInfo), + true); if (dmFailed) { diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index 64da8ef3f..a1b6e319e 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -34,14 +34,18 @@ public partial class Gambling : GamblingModule _configService = configService; } - private string n(long cur) => cur.ToString("N", _enUsCulture); + private string n(long cur) + { + var flowersCi = (CultureInfo)_cultureInfo.Clone(); + flowersCi.NumberFormat.CurrencySymbol = CurrencySign; + Log.Information(string.Join(",", flowersCi.NumberFormat.NativeDigits)); + return cur.ToString("C0", flowersCi); + } public string GetCurrency(ulong id) { - using (var uow = _db.GetDbContext()) - { - return n(uow.DiscordUser.GetUserCurrency(id)); - } + using var uow = _db.GetDbContext(); + return n(uow.DiscordUser.GetUserCurrency(id)); } [NadekoCommand, Aliases] @@ -56,12 +60,12 @@ public partial class Gambling : GamblingModule } var embed = _eb.Create() .WithTitle(GetText(strs.economy_state)) - .AddField(GetText(strs.currency_owned), ((BigInteger)(ec.Cash - ec.Bot)).ToString("N", _enUsCulture) + CurrencySign) + .AddField(GetText(strs.currency_owned), ((BigInteger)(ec.Cash - ec.Bot)).ToString("N", _cultureInfo) + CurrencySign) .AddField(GetText(strs.currency_one_percent), (onePercent * 100).ToString("F2") + "%") - .AddField(GetText(strs.currency_planted), (BigInteger)ec.Planted + CurrencySign) + .AddField(GetText(strs.currency_planted), (BigInteger)ec.Planted) .AddField(GetText(strs.owned_waifus_total), (BigInteger)ec.Waifus + CurrencySign) - .AddField(GetText(strs.bot_currency), ec.Bot.ToString("N", _enUsCulture) + CurrencySign) - .AddField(GetText(strs.total), ((BigInteger)(ec.Cash + ec.Planted + ec.Waifus)).ToString("N", _enUsCulture) + CurrencySign) + .AddField(GetText(strs.bot_currency), n(ec.Bot)) + .AddField(GetText(strs.total), ((BigInteger)(ec.Cash + ec.Planted + ec.Waifus)).ToString("N", _cultureInfo) + CurrencySign) .WithOkColor(); // ec.Cash already contains ec.Bot as it's the total of all values in the CurrencyAmount column of the DiscordUser table await ctx.Channel.EmbedAsync(embed).ConfigureAwait(false); @@ -87,7 +91,7 @@ public partial class Gambling : GamblingModule await _cs.AddAsync(ctx.User.Id, "Timely claim", val).ConfigureAwait(false); - await ReplyConfirmLocalizedAsync(strs.timely(n(val) + CurrencySign, period)); + await ReplyConfirmLocalizedAsync(strs.timely(n(val), period)); } [NadekoCommand, Aliases] @@ -114,7 +118,7 @@ public partial class Gambling : GamblingModule if (amount == 0) await ReplyConfirmLocalizedAsync(strs.timely_set_none).ConfigureAwait(false); else - await ReplyConfirmLocalizedAsync(strs.timely_set(Format.Bold(n(amount) + CurrencySign), Format.Bold(period.ToString()))).ConfigureAwait(false); + await ReplyConfirmLocalizedAsync(strs.timely_set(Format.Bold(n(amount)), Format.Bold(period.ToString()))).ConfigureAwait(false); } [NadekoCommand, Aliases] @@ -149,14 +153,6 @@ public partial class Gambling : GamblingModule await SendConfirmAsync("🎟 " + GetText(strs.raffled_user), $"**{usr.Username}#{usr.Discriminator}**", footer: $"ID: {usr.Id}").ConfigureAwait(false); } - [NadekoCommand, Aliases] - [Priority(1)] - public async Task Cash([Leftover] IUser user = null) - { - user = user ?? ctx.User; - await ConfirmLocalizedAsync(strs.has(Format.Bold(user.ToString()), $"{GetCurrency(user.Id)} {CurrencySign}")); - } - [NadekoCommand, Aliases] [Priority(2)] public Task CurrencyTransactions(int page = 1) => @@ -207,7 +203,15 @@ public partial class Gambling : GamblingModule [Priority(0)] public async Task Cash(ulong userId) { - await ReplyConfirmLocalizedAsync(strs.has(Format.Code(userId.ToString()), $"{GetCurrency(userId)} {CurrencySign}")); + await ReplyConfirmLocalizedAsync(strs.has(Format.Code(userId.ToString()), $"{GetCurrency(userId)}")); + } + + [NadekoCommand, Aliases] + [Priority(1)] + public async Task Cash([Leftover] IUser user = null) + { + user = user ?? ctx.User; + await ConfirmLocalizedAsync(strs.has(Format.Bold(user.ToString()), $"{GetCurrency(user.Id)}")); } [NadekoCommand, Aliases] @@ -224,7 +228,7 @@ public partial class Gambling : GamblingModule return; } await _cs.AddAsync(receiver, $"Gift from {ctx.User.Username} ({ctx.User.Id}) - {msg}.", amount, true).ConfigureAwait(false); - await ReplyConfirmLocalizedAsync(strs.gifted(n(amount) + CurrencySign, Format.Bold(receiver.ToString()))); + await ReplyConfirmLocalizedAsync(strs.gifted(n(amount), Format.Bold(receiver.ToString()))); } [NadekoCommand, Aliases] @@ -267,7 +271,7 @@ public partial class Gambling : GamblingModule $"Awarded by bot owner. ({ctx.User.Username}/{ctx.User.Id}) {msg ?? ""}", amount, gamble: ctx.Client.CurrentUser.Id != usrId).ConfigureAwait(false); - await ReplyConfirmLocalizedAsync(strs.awarded(n(amount) + CurrencySign, $"<@{usrId}>")); + await ReplyConfirmLocalizedAsync(strs.awarded(n(amount), $"<@{usrId}>")); } [NadekoCommand, Aliases] @@ -287,7 +291,7 @@ public partial class Gambling : GamblingModule .ConfigureAwait(false); await ReplyConfirmLocalizedAsync(strs.mass_award( - n(amount) + CurrencySign, + n(amount), Format.Bold(users.Count.ToString()), Format.Bold(role.Name))); } @@ -307,7 +311,7 @@ public partial class Gambling : GamblingModule .ConfigureAwait(false); await ReplyConfirmLocalizedAsync(strs.mass_take( - n(amount) + CurrencySign, + n(amount), Format.Bold(users.Count.ToString()), Format.Bold(role.Name))); } @@ -323,9 +327,9 @@ public partial class Gambling : GamblingModule if (await _cs.RemoveAsync(user, $"Taken by bot owner.({ctx.User.Username}/{ctx.User.Id})", amount, gamble: ctx.Client.CurrentUser.Id != user.Id).ConfigureAwait(false)) - await ReplyConfirmLocalizedAsync(strs.take(n(amount) + CurrencySign, Format.Bold(user.ToString()))).ConfigureAwait(false); + await ReplyConfirmLocalizedAsync(strs.take(n(amount), Format.Bold(user.ToString()))).ConfigureAwait(false); else - await ReplyErrorLocalizedAsync(strs.take_fail(n(amount) + CurrencySign, Format.Bold(user.ToString()), CurrencySign)); + await ReplyErrorLocalizedAsync(strs.take_fail(n(amount), Format.Bold(user.ToString()), CurrencySign)); } @@ -338,9 +342,9 @@ public partial class Gambling : GamblingModule if (await _cs.RemoveAsync(usrId, $"Taken by bot owner.({ctx.User.Username}/{ctx.User.Id})", amount, gamble: ctx.Client.CurrentUser.Id != usrId).ConfigureAwait(false)) - await ReplyConfirmLocalizedAsync(strs.take(amount + CurrencySign, $"<@{usrId}>")); + await ReplyConfirmLocalizedAsync(strs.take(n(amount), $"<@{usrId}>")); else - await ReplyErrorLocalizedAsync(strs.take_fail(amount + CurrencySign, Format.Code(usrId.ToString()), CurrencySign)); + await ReplyErrorLocalizedAsync(strs.take_fail(n(amount), Format.Code(usrId.ToString()), CurrencySign)); } private IUserMessage rdMsg = null; @@ -398,7 +402,7 @@ public partial class Gambling : GamblingModule await ReplyConfirmLocalizedAsync(strs.roll_duel_challenge( Format.Bold(ctx.User.ToString()), Format.Bold(u.ToString()), - Format.Bold(amount + CurrencySign))); + Format.Bold(n(amount)))); } async Task Game_OnGameTick(RollDuelGame arg) @@ -433,7 +437,7 @@ public partial class Gambling : GamblingModule var winner = rdGame.Winner == rdGame.P1 ? ctx.User : u; - description += $"\n**{winner}** Won {n((long)(rdGame.Amount * 2 * 0.98)) + CurrencySign}"; + description += $"\n**{winner}** Won {n((long)(rdGame.Amount * 2 * 0.98))}"; embed = embed.WithDescription(description); @@ -477,7 +481,7 @@ public partial class Gambling : GamblingModule { var win = (long)(amount * result.Multiplier); str += GetText(strs.br_win( - n(win) + CurrencySign, + n(win), result.Threshold + (result.Roll == 100 ? " 👑" : ""))); await _cs.AddAsync(ctx.User, "Betroll Gamble", win, false, gamble: true).ConfigureAwait(false); @@ -571,7 +575,7 @@ public partial class Gambling : GamblingModule var usrStr = x.ToString().TrimTo(20, true); var j = i; - embed.AddField("#" + (9 * curPage + j + 1) + " " + usrStr, n(x.CurrencyAmount) + " " + CurrencySign, true); + embed.AddField("#" + (9 * curPage + j + 1) + " " + usrStr, n(x.CurrencyAmount), true); } return embed; diff --git a/src/NadekoBot/Modules/Games/Common/Trivia/TriviaGame.cs b/src/NadekoBot/Modules/Games/Common/Trivia/TriviaGame.cs index bcfe9da03..6ab740e40 100644 --- a/src/NadekoBot/Modules/Games/Common/Trivia/TriviaGame.cs +++ b/src/NadekoBot/Modules/Games/Common/Trivia/TriviaGame.cs @@ -264,7 +264,7 @@ public class TriviaGame foreach (var kvp in Users.OrderByDescending(kvp => kvp.Value)) { - sb.AppendLine(GetText(strs.trivia_points(Format.Bold(kvp.Key.ToString()), kvp.Value)).SnPl(kvp.Value)); + sb.AppendLine(GetText(strs.trivia_points(Format.Bold(kvp.Key.ToString()), kvp.Value))); } return sb.ToString(); diff --git a/src/NadekoBot/Modules/Utility/RemindCommands.cs b/src/NadekoBot/Modules/Utility/RemindCommands.cs index edfdcbf81..7f44aab5c 100644 --- a/src/NadekoBot/Modules/Utility/RemindCommands.cs +++ b/src/NadekoBot/Modules/Utility/RemindCommands.cs @@ -1,4 +1,5 @@ -using NadekoBot.Services.Database.Models; +using Humanizer.Localisation; +using NadekoBot.Services.Database.Models; using NadekoBot.Db; using NadekoBot.Extensions; using NadekoBot.Modules.Administration.Services; @@ -85,14 +86,14 @@ public partial class Utility [UserPerm(GuildPerm.Administrator)] [Priority(0)] public Task RemindList(Server _, int page = 1) - => RemindList(page, true); + => RemindListInternal(page, true); [NadekoCommand, Aliases] [Priority(1)] public Task RemindList(int page = 1) - => RemindList(page, false); + => RemindListInternal(page, false); - private async Task RemindList(int page, bool isServer) + private async Task RemindListInternal(int page, bool isServer) { if (--page < 0) return; @@ -126,7 +127,8 @@ public partial class Utility var when = rem.When; var diff = when - DateTime.UtcNow; embed.AddField( - $"#{++i + page * 10} {rem.When:HH:mm yyyy-MM-dd} UTC (in {(int) diff.TotalHours}h {(int) diff.Minutes}m)", + $"#{++i + page * 10} {rem.When:HH:mm yyyy-MM-dd} UTC " + + $"(in {diff.Humanize(2, minUnit: TimeUnit.Minute, culture: _cultureInfo)})", $@"`Target:` {(rem.IsPrivate ? "DM" : "Channel")} `TargetId:` {rem.ChannelId} `Message:` {rem.Message?.TrimTo(50)}", false); @@ -229,7 +231,7 @@ public partial class Utility "⏰ " + GetText(strs.remind( Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username), Format.Bold(message), - $"{ts.Days}d {ts.Hours}h {ts.Minutes}min", + ts.Humanize(3, minUnit: TimeUnit.Second, culture: _cultureInfo), gTime, gTime))).ConfigureAwait(false); } catch diff --git a/src/NadekoBot/NadekoBot.csproj b/src/NadekoBot/NadekoBot.csproj index a6dca48e3..39310ad51 100644 --- a/src/NadekoBot/NadekoBot.csproj +++ b/src/NadekoBot/NadekoBot.csproj @@ -53,6 +53,7 @@ + diff --git a/src/NadekoBot/Program.cs b/src/NadekoBot/Program.cs index ce30b676e..2d6cbf411 100644 --- a/src/NadekoBot/Program.cs +++ b/src/NadekoBot/Program.cs @@ -2,27 +2,25 @@ var shardId = 0; int? totalShards = null; // 0 to read from creds.yml -if (args.Length > 0) -{ - if (!int.TryParse(args[0], out shardId)) - { - Console.Error.WriteLine("Invalid first argument (shard id): {0}", args[0]); - return; - } - - if (args.Length > 1) - { - if (!int.TryParse(args[1], out var shardCount)) - { - Console.Error.WriteLine("Invalid second argument (total shards): {0}", args[1]); - return; - } - - totalShards = shardCount; - } -} - - +// if (args.Length > 0) +// { +// if (!int.TryParse(args[0], out shardId)) +// { +// Console.Error.WriteLine("Invalid first argument (shard id): {0}", args[0]); +// return; +// } +// +// if (args.Length > 1) +// { +// if (!int.TryParse(args[1], out var shardCount)) +// { +// Console.Error.WriteLine("Invalid second argument (total shards): {0}", args[1]); +// return; +// } +// +// totalShards = shardCount; +// } +// } LogSetup.SetupLogger(shardId); Log.Information($"Pid: {pid}"); diff --git a/src/NadekoBot/Services/Impl/Localization.cs b/src/NadekoBot/Services/Impl/Localization.cs index cf558b86e..eaf3471a0 100644 --- a/src/NadekoBot/Services/Impl/Localization.cs +++ b/src/NadekoBot/Services/Impl/Localization.cs @@ -4,7 +4,6 @@ using NadekoBot.Db; namespace NadekoBot.Services; -// todo future use guild locale more in the code (from guild settings) (for dates, currency, etc?) public class Localization : ILocalization, INService { private readonly BotConfigService _bss; diff --git a/src/NadekoBot/_Extensions/StringExtensions.cs b/src/NadekoBot/_Extensions/StringExtensions.cs index e98f0d96f..eb045b4a1 100644 --- a/src/NadekoBot/_Extensions/StringExtensions.cs +++ b/src/NadekoBot/_Extensions/StringExtensions.cs @@ -27,27 +27,10 @@ public static class StringExtensions return Regex.Replace(input, "<.*?>", String.Empty); } - // todo future maybe use humanizer lib for this kind of work public static string TrimTo(this string str, int maxLength, bool hideDots = false) - { - if (maxLength < 0) - throw new ArgumentOutOfRangeException(nameof(maxLength), $"Argument {nameof(maxLength)} can't be negative."); - if (maxLength == 0) - return string.Empty; - if (maxLength <= 3) - return string.Concat(str.Select(c => '.')); - if (str.Length < maxLength) - return str; - - if (hideDots) - { - return string.Concat(str.Take(maxLength)); - } - else - { - return string.Concat(str.Take(maxLength - 1)) + "…"; - } - } + => hideDots + ? str?.Truncate(maxLength, string.Empty) + : str?.Truncate(maxLength); public static string ToTitleCase(this string str) { @@ -63,22 +46,6 @@ public static class StringExtensions .Replace(" The ", " the "); } - /// - /// Removes trailing S or ES (if specified) on the given string if the num is 1 - /// - /// - /// - /// - /// String with the correct singular/plural form - public static string SnPl(this string str, int? num, bool es = false) - { - if (str is null) - throw new ArgumentNullException(nameof(str)); - if (num is null) - throw new ArgumentNullException(nameof(num)); - return num == 1 ? str.Remove(str.Length - 1, es ? 2 : 1) : str; - } - //http://www.dotnetperls.com/levenshtein public static int LevenshteinDistance(this string s, string t) {