Nuked humanizer. Some of the strings might look worse but the output directory will no longer look terrible. Added stats for todo list command

This commit is contained in:
Kwoth
2024-05-02 22:14:25 +00:00
parent fc4858830c
commit 3ef05f8aa7
19 changed files with 104 additions and 66 deletions

View File

@@ -3,7 +3,6 @@ global using NonBlocking;
// packages // packages
global using Serilog; global using Serilog;
global using Humanizer;
// nadekobot // nadekobot
global using NadekoBot; global using NadekoBot;

View File

@@ -344,7 +344,7 @@ public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
return false; return false;
} }
if (sr.GetContentLength() > 8.Megabytes().Bytes) if (sr.GetContentLength() > 8.Megabytes())
{ {
return false; return false;
} }

View File

@@ -1,6 +1,5 @@
#nullable disable #nullable disable
using CommandLine; using CommandLine;
using Humanizer.Localisation;
using NadekoBot.Common.TypeReaders.Models; using NadekoBot.Common.TypeReaders.Models;
using NadekoBot.Modules.Administration.Services; using NadekoBot.Modules.Administration.Services;
using NadekoBot.Db.Models; using NadekoBot.Db.Models;
@@ -458,7 +457,7 @@ public partial class Administration
.AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true) .AddField(GetText(strs.username), user?.ToString() ?? userId.ToString(), true)
.AddField("ID", userId.ToString(), true) .AddField("ID", userId.ToString(), true)
.AddField(GetText(strs.duration), .AddField(GetText(strs.duration),
time.Time.Humanize(3, minUnit: TimeUnit.Minute, culture: Culture), time.Time.ToPrettyStringHm(),
true); true);
if (dmFailed) if (dmFailed)

View File

@@ -396,8 +396,8 @@ public partial class Gambling : GamblingModule<GamblingService>
("rps", _, _) => $"Rock Paper Scissors - {subType}", ("rps", _, _) => $"Rock Paper Scissors - {subType}",
(null, _, _) => null, (null, _, _) => null,
(_, null, _) => null, (_, null, _) => null,
(_, _, ulong userId) => $"{type.Titleize()} - {subType.Titleize()} | [{userId}]", (_, _, ulong userId) => $"{type} - {subType} | [{userId}]",
_ => $"{type.Titleize()} - {subType.Titleize()}" _ => $"{type} - {subType}"
}; };
[Cmd] [Cmd]

View File

@@ -1,5 +1,4 @@
#nullable disable #nullable disable
using Humanizer.Localisation;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NadekoBot.Common.TypeReaders; using NadekoBot.Common.TypeReaders;
using NadekoBot.Db; using NadekoBot.Db;
@@ -81,7 +80,6 @@ public partial class Permissions
if (--page < 0) if (--page < 0)
return; return;
var channel = (ITextChannel)ctx.Channel;
var localSet = _service.GetCommandCooldowns(ctx.Guild.Id); var localSet = _service.GetCommandCooldowns(ctx.Guild.Id);
if (!localSet.Any()) if (!localSet.Any())
@@ -96,7 +94,7 @@ public partial class Permissions
.Page((items, _) => .Page((items, _) =>
{ {
var output = items.Select(x => var output = items.Select(x =>
$"{Format.Code(x.CommandName)}: {x.Seconds.Seconds().Humanize(maxUnit: TimeUnit.Second, culture: Culture)}"); $"{Format.Code(x.CommandName)}: {x.Seconds}s");
return _sender.CreateEmbed() return _sender.CreateEmbed()
.WithOkColor() .WithOkColor()

View File

@@ -105,10 +105,7 @@ public sealed class DefaultStockDataService : IStockDataService, INService
.ToList(); .ToList();
} }
private static CsvConfiguration _csvConfig = new(CultureInfo.InvariantCulture) private static CsvConfiguration _csvConfig = new(CultureInfo.InvariantCulture);
{
PrepareHeaderForMatch = args => args.Header.Humanize(LetterCasing.Title)
};
public async Task<IReadOnlyCollection<CandleData>> GetCandleDataAsync(string query) public async Task<IReadOnlyCollection<CandleData>> GetCandleDataAsync(string query)
{ {

View File

@@ -1,9 +1,7 @@
#nullable disable #nullable disable
using Humanizer.Localisation;
using NadekoBot.Db; using NadekoBot.Db;
using NadekoBot.Modules.Utility.Services; using NadekoBot.Modules.Utility.Services;
using NadekoBot.Db.Models; using NadekoBot.Db.Models;
using System.Resources;
namespace NadekoBot.Modules.Utility; namespace NadekoBot.Modules.Utility;
@@ -118,7 +116,7 @@ public partial class Utility
var diff = when - DateTime.UtcNow; var diff = when - DateTime.UtcNow;
embed.AddField( embed.AddField(
$"#{++i + (page * 10)} {rem.When:HH:mm yyyy-MM-dd} UTC " $"#{++i + (page * 10)} {rem.When:HH:mm yyyy-MM-dd} UTC "
+ $"(in {diff.Humanize(2, minUnit: TimeUnit.Minute, culture: Culture)})", + $"(in {diff.ToPrettyStringHm()})",
$@"`Target:` {(rem.IsPrivate ? "DM" : "Channel")} $@"`Target:` {(rem.IsPrivate ? "DM" : "Channel")}
`TargetId:` {rem.ChannelId} `TargetId:` {rem.ChannelId}
`Message:` {rem.Message?.TrimTo(50)}"); `Message:` {rem.Message?.TrimTo(50)}");
@@ -212,7 +210,7 @@ public partial class Utility
.Confirm($"\u23f0 {GetText(strs.remind( .Confirm($"\u23f0 {GetText(strs.remind(
Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username), Format.Bold(!isPrivate ? $"<#{targetId}>" : ctx.User.Username),
Format.Bold(message), Format.Bold(message),
ts.Humanize(3, minUnit: TimeUnit.Second, culture: Culture), ts.ToPrettyStringHm(),
gTime, gTime,
gTime))}") gTime))}")
.SendAsync(); .SendAsync();

View File

@@ -11,8 +11,7 @@ namespace NadekoBot.Modules.Utility.Services;
public class RemindService : INService, IReadyExecutor, IRemindService public class RemindService : INService, IReadyExecutor, IRemindService
{ {
private readonly Regex _regex = private readonly Regex _regex =
new( new(@"^(?:(?:at|on(?:\sthe)?)?\s*(?<date>(?:\d{2}:\d{2}\s)?\d{1,2}\.\d{1,2}(?:\.\d{2,4})?)|(?:in\s?)?\s*(?:(?<mo>\d+)(?:\s?(?:months?|mos?),?))?(?:(?:\sand\s|\s*)?(?<w>\d+)(?:\s?(?:weeks?|w),?))?(?:(?:\sand\s|\s*)?(?<d>\d+)(?:\s?(?:days?|d),?))?(?:(?:\sand\s|\s*)?(?<h>\d+)(?:\s?(?:hours?|h),?))?(?:(?:\sand\s|\s*)?(?<m>\d+)(?:\s?(?:minutes?|mins?|m),?))?)\s+(?:to:?\s+)?(?<what>(?:\r\n|[\r\n]|.)+)",
@"^(?:(?:at|on(?:\sthe)?)?\s*(?<date>(?:\d{2}:\d{2}\s)?\d{1,2}\.\d{1,2}(?:\.\d{2,4})?)|(?:in\s?)?\s*(?:(?<mo>\d+)(?:\s?(?:months?|mos?),?))?(?:(?:\sand\s|\s*)?(?<w>\d+)(?:\s?(?:weeks?|w),?))?(?:(?:\sand\s|\s*)?(?<d>\d+)(?:\s?(?:days?|d),?))?(?:(?:\sand\s|\s*)?(?<h>\d+)(?:\s?(?:hours?|h),?))?(?:(?:\sand\s|\s*)?(?<m>\d+)(?:\s?(?:minutes?|mins?|m),?))?)\s+(?:to:?\s+)?(?<what>(?:\r\n|[\r\n]|.)+)",
RegexOptions.Compiled | RegexOptions.Multiline); RegexOptions.Compiled | RegexOptions.Multiline);
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
@@ -62,7 +61,7 @@ public class RemindService : INService, IReadyExecutor, IRemindService
Log.Information("Executing {ReminderCount} reminders", reminders.Count); Log.Information("Executing {ReminderCount} reminders", reminders.Count);
// make groups of 5, with 1.5 second inbetween each one to ensure against ratelimits // make groups of 5, with 1.5 second in between each one to ensure against ratelimits
foreach (var group in reminders.Chunk(5)) foreach (var group in reminders.Chunk(5))
{ {
var executedReminders = group.ToList(); var executedReminders = group.ToList();

View File

@@ -44,7 +44,26 @@ public partial class Utility
return; return;
} }
await ShowTodosAsync(todos); await Response()
.Paginated()
.Items(todos)
.PageSize(9)
.AddFooter(false)
.Page((items, _) =>
{
var eb = _sender.CreateEmbed()
.WithOkColor()
.WithTitle(GetText(strs.todo_list));
ShowTodoItem(items, eb);
eb.WithFooter(GetText(strs.todo_stats(todos.Length,
todos.Count(x => x.IsDone),
todos.Count(x => !x.IsDone))));
return eb;
})
.SendAsync();
} }
@@ -81,23 +100,6 @@ public partial class Utility
} }
private Task ShowTodosAsync(TodoModel[] todos)
=> Response()
.Paginated()
.Items(todos)
.PageSize(9)
.Page((items, _) =>
{
var eb = _sender.CreateEmbed()
.WithOkColor()
.WithTitle(GetText(strs.todo_list));
ShowTodoItem(items, eb);
return eb;
})
.SendAsync();
private static void ShowTodoItem(IReadOnlyCollection<TodoModel> todos, EmbedBuilder eb) private static void ShowTodoItem(IReadOnlyCollection<TodoModel> todos, EmbedBuilder eb)
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
@@ -182,14 +184,19 @@ public partial class Utility
.Paginated() .Paginated()
.Items(list.Items) .Items(list.Items)
.PageSize(9) .PageSize(9)
.AddFooter(false)
.Page((items, _) => .Page((items, _) =>
{ {
var eb = _sender.CreateEmbed() var eb = _sender.CreateEmbed()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.todo_list)); .WithTitle(GetText(strs.todo_archived_list));
ShowTodoItem(items, eb); ShowTodoItem(items, eb);
eb.WithFooter(GetText(strs.todo_stats(list.Items.Count,
list.Items.Count(x => x.IsDone),
list.Items.Count(x => !x.IsDone))));
return eb; return eb;
}) })
.SendAsync(); .SendAsync();

View File

@@ -110,7 +110,7 @@ public class ClubService : INService, IClubService
if (!temp.IsImage()) if (!temp.IsImage())
return SetClubIconResult.InvalidFileType; return SetClubIconResult.InvalidFileType;
if (temp.GetContentLength() > 5.Megabytes().Bytes) if (temp.GetContentLength() > 5.Megabytes())
return SetClubIconResult.TooLarge; return SetClubIconResult.TooLarge;
} }

View File

@@ -127,7 +127,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
{ {
_ = Task.Run(() => _levelUpQueue.RunAsync()); _ = Task.Run(() => _levelUpQueue.RunAsync());
using var timer = new PeriodicTimer(5.Seconds()); using var timer = new PeriodicTimer(TimeSpan.FromSeconds(5));
while (await timer.WaitForNextTickAsync()) while (await timer.WaitForNextTickAsync())
{ {
await UpdateXp(); await UpdateXp();
@@ -1364,7 +1364,7 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
using (var http = _httpFactory.CreateClient()) using (var http = _httpFactory.CreateClient())
using (var temp = await http.GetAsync(imgUrl, HttpCompletionOption.ResponseHeadersRead)) using (var temp = await http.GetAsync(imgUrl, HttpCompletionOption.ResponseHeadersRead))
{ {
if (!temp.IsImage() || temp.GetContentLength() > 11.Megabytes().Bytes) if (!temp.IsImage() || temp.GetContentLength() > 11 * 1024 * 1024)
return; return;
var imgData = await temp.Content.ReadAsByteArrayAsync(); var imgData = await temp.Content.ReadAsByteArrayAsync();

View File

@@ -77,11 +77,6 @@
<PackageReference Include="YamlDotNet" Version="15.1.2" /> <PackageReference Include="YamlDotNet" Version="15.1.2" />
<PackageReference Include="SharpToken" Version="2.0.2" /> <PackageReference Include="SharpToken" Version="2.0.2" />
<PackageReference Include="Humanizer" Version="2.14.1">
<PrivateAssets>all</PrivateAssets>
<Publish>True</Publish>
</PackageReference>
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" /> <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />

View File

@@ -1,6 +1,3 @@
using Humanizer.Localisation;
using System.Resources;
var pid = Environment.ProcessId; var pid = Environment.ProcessId;
var shardId = 0; var shardId = 0;

View File

@@ -35,7 +35,7 @@ public sealed class ImageCache : IImageCache, INService
var bytes = await http.GetByteArrayAsync(url); var bytes = await http.GetByteArrayAsync(url);
return bytes; return bytes;
}, },
expiry: 48.Hours()); expiry: TimeSpan.FromHours(48));
private async Task<byte[]?> GetRandomImageDataAsync(Uri[] urls) private async Task<byte[]?> GetRandomImageDataAsync(Uri[] urls)
{ {

View File

@@ -29,7 +29,17 @@ public static class StringExtensions
=> Regex.Replace(input, "<.*?>", string.Empty); => Regex.Replace(input, "<.*?>", string.Empty);
public static string? TrimTo(this string? str, int maxLength, bool hideDots = false) public static string? TrimTo(this string? str, int maxLength, bool hideDots = false)
=> hideDots ? str?.Truncate(maxLength, string.Empty) : str?.Truncate(maxLength); {
if (hideDots)
{
return str?.Substring(0, maxLength);
}
if (str is null || str.Length <= maxLength)
return str;
return string.Concat(str.AsSpan(0, maxLength - 1), "…");
}
public static string ToTitleCase(this string str) public static string ToTitleCase(this string str)
{ {

View File

@@ -9,7 +9,13 @@ public static class PatronExtensions
}; };
public static string ToFullName(this QuotaPer per) public static string ToFullName(this QuotaPer per)
=> per.Humanize(LetterCasing.LowerCase); => per switch
{
QuotaPer.PerDay => "per day",
QuotaPer.PerHour => "per hour",
QuotaPer.PerMonth => "per month",
_ => "Unknown",
};
public static DateTime DayOfNextMonth(this DateTime date, int day) public static DateTime DayOfNextMonth(this DateTime date, int day)
{ {

View File

@@ -1,5 +1,4 @@
#nullable disable #nullable disable
using Humanizer.Localisation;
using NadekoBot.Common.ModuleBehaviors; using NadekoBot.Common.ModuleBehaviors;
using System.Diagnostics; using System.Diagnostics;
@@ -178,13 +177,23 @@ public sealed class StatsService : IStatsService, IReadyExecutor, INService
public string GetUptimeString(string separator = ", ") public string GetUptimeString(string separator = ", ")
{ {
var time = GetUptime(); var time = GetUptime();
return time.Humanize(3, maxUnit: TimeUnit.Day, minUnit: TimeUnit.Minute);
if (time.Days > 0)
return $"{time.Days}d {time.Hours}h {time.Minutes}m";
if (time.Hours > 0)
return $"{time.Hours}h {time.Minutes}m";
if (time.Minutes > 0)
return $"{time.Minutes}m {time.Seconds}s";
return $"{time.Seconds}s";
} }
public double GetPrivateMemoryMegabytes() public double GetPrivateMemoryMegabytes()
{ {
_currentProcess.Refresh(); _currentProcess.Refresh();
return _currentProcess.PrivateMemorySize64 / 1.Megabytes().Bytes; return _currentProcess.PrivateMemorySize64 / 1.Megabytes();
} }
public GuildInfo GetGuildInfo(string name) public GuildInfo GetGuildInfo(string name)

View File

@@ -1,4 +1,3 @@
using Humanizer.Localisation;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Text.Json; using System.Text.Json;
@@ -60,7 +59,30 @@ public static class Extensions
/// <param name="span">Timespan to convert to string</param> /// <param name="span">Timespan to convert to string</param>
/// <returns>Formatted duration string</returns> /// <returns>Formatted duration string</returns>
public static string ToPrettyStringHm(this TimeSpan span) public static string ToPrettyStringHm(this TimeSpan span)
=> span.Humanize(2, minUnit: TimeUnit.Second); {
if(span > TimeSpan.FromHours(24))
return $"{span.Days:00}d:{span.Hours:00}h";
if (span > TimeSpan.FromMinutes(2))
return $"{span.Hours:00}h:{span.Minutes:00}m";
return $"{span.Minutes:00}m:{span.Seconds:00}s";
}
public static double Megabytes(this int mb)
=> mb * 1024d * 1024;
public static TimeSpan Hours(this int hours)
=> TimeSpan.FromHours(hours);
public static TimeSpan Minutes(this int minutes)
=> TimeSpan.FromMinutes(minutes);
public static TimeSpan Days(this int days)
=> TimeSpan.FromDays(days);
public static TimeSpan Seconds(this int seconds)
=> TimeSpan.FromSeconds(seconds);
public static bool TryGetUrlPath(this string input, out string path) public static bool TryGetUrlPath(this string input, out string path)
{ {

View File

@@ -1080,12 +1080,14 @@
"giveaway_list": "List of active giveways", "giveaway_list": "List of active giveways",
"todo_list_empty": "Your todo list is empty." , "todo_list_empty": "Your todo list is empty." ,
"todo_list": "Todo List", "todo_list": "Todo List",
"todo_add_max_limit": "You've reached the maximum amount of todos you can have.", "todo_stats": "{0} items | {1} completed | {2} remaining",
"todo_add_max_limit": "You'reached the maximum amount of todos you can have.",
"todo_not_found": "Todo not found.", "todo_not_found": "Todo not found.",
"todo_cleared": "All unarchived todos have been cleared.", "todo_cleared": "All unarchived todos have been cleared.",
"todo_no_todos": "There are no todos in your todo list.", "todo_no_todos": "There are no todos in your todo list.",
"todo_archive_max_limit": "You've reached the maximum amount of archived todos you can have.", "todo_archive_max_limit": "You've reached the maximum amount of archived todos you can have.",
"todo_archive_empty": "You have no archived todos.", "todo_archive_empty": "You have no archived todos.",
"todo_archive_list": "Archived Todo Lists", "todo_archive_list": "Archived Todo Lists",
"todo_archive_not_found": "Archived todo list not found." "todo_archive_not_found": "Archived todo list not found.",
"todo_archived_list": "Archived Todo List"
} }