mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 13:06:50 +00:00
169 lines
No EOL
6.6 KiB
C#
169 lines
No EOL
6.6 KiB
C#
using System.Text;
|
|
|
|
using NodaTime;
|
|
|
|
using PluralKit.Core;
|
|
|
|
namespace PluralKit.Bot;
|
|
|
|
public class SystemFront
|
|
{
|
|
private readonly EmbedService _embeds;
|
|
|
|
public SystemFront(EmbedService embeds)
|
|
{
|
|
_embeds = embeds;
|
|
}
|
|
|
|
public async Task Fronter(Context ctx, PKSystem system)
|
|
{
|
|
if (system == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
|
|
ctx.CheckSystemPrivacy(system.Id, system.FrontPrivacy);
|
|
|
|
var sw = await ctx.Repository.GetLatestSwitch(system.Id);
|
|
if (sw == null) throw Errors.NoRegisteredSwitches;
|
|
|
|
await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system.Id)));
|
|
}
|
|
|
|
public async Task FrontHistory(Context ctx, PKSystem system, bool showMemberId, bool clear = false)
|
|
{
|
|
if (clear)
|
|
{
|
|
await new Switch().SwitchDelete(ctx, true);
|
|
return;
|
|
}
|
|
|
|
if (system == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
|
|
ctx.CheckSystemPrivacy(system.Id, system.FrontHistoryPrivacy);
|
|
|
|
var totalSwitches = await ctx.Repository.GetSwitchCount(system.Id);
|
|
if (totalSwitches == 0) throw Errors.NoRegisteredSwitches;
|
|
|
|
var sws = ctx.Repository.GetSwitches(system.Id)
|
|
.Scan(new FrontHistoryEntry(null, null),
|
|
(lastEntry, newSwitch) => new FrontHistoryEntry(lastEntry.ThisSwitch?.Timestamp, newSwitch));
|
|
|
|
var embedTitle = system.NameFor(ctx) != null
|
|
? $"Front history of {system.NameFor(ctx)} (`{system.Hid}`)"
|
|
: $"Front history of `{system.Hid}`";
|
|
|
|
if (ctx.Guild != null)
|
|
{
|
|
var guildSettings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, system.Id);
|
|
if (guildSettings.DisplayName != null)
|
|
embedTitle = $"Front history of {guildSettings.DisplayName} (`{system.Hid}`)";
|
|
}
|
|
|
|
await ctx.Paginate(
|
|
sws,
|
|
totalSwitches,
|
|
10,
|
|
embedTitle,
|
|
system.Color,
|
|
async (builder, switches) =>
|
|
{
|
|
var sb = new StringBuilder();
|
|
foreach (var entry in switches)
|
|
{
|
|
var lastSw = entry.LastTime;
|
|
|
|
var sw = entry.ThisSwitch;
|
|
|
|
// Fetch member list and format
|
|
|
|
var members = await ctx.Database.Execute(c => ctx.Repository.GetSwitchMembers(c, sw.Id)).ToListAsync();
|
|
var membersStr = members.Any()
|
|
? string.Join(", ", members.Select(m => $"**{m.NameFor(ctx)}**{(showMemberId ? $" (`{m.DisplayHid(ctx.Config)}`)" : "")}"))
|
|
: "**no fronter**";
|
|
|
|
var switchSince = SystemClock.Instance.GetCurrentInstant() - sw.Timestamp;
|
|
|
|
// If this isn't the latest switch, we also show duration
|
|
string stringToAdd;
|
|
if (lastSw != null)
|
|
{
|
|
// Calculate the time between the last switch (that we iterated - ie. the next one on the timeline) and the current one
|
|
var switchDuration = lastSw.Value - sw.Timestamp;
|
|
stringToAdd =
|
|
$"{membersStr} ({sw.Timestamp.FormatZoned(ctx.Zone)}, {switchSince.FormatDuration()} ago, for {switchDuration.FormatDuration()})\n";
|
|
}
|
|
else
|
|
{
|
|
stringToAdd =
|
|
$"{membersStr} ({sw.Timestamp.FormatZoned(ctx.Zone)}, {switchSince.FormatDuration()} ago)\n";
|
|
}
|
|
|
|
if (sb.Length + stringToAdd.Length >= 4096)
|
|
break;
|
|
sb.Append(stringToAdd);
|
|
}
|
|
|
|
builder.Description(sb.ToString());
|
|
}
|
|
);
|
|
}
|
|
|
|
public async Task FrontPercent(Context ctx, PKSystem? system, string? durationStr, bool ignoreNoFronters = false, bool showFlat = false, PKGroup? group = null)
|
|
{
|
|
if (system == null && group == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
|
|
if (system == null) system = await GetGroupSystem(ctx, group);
|
|
|
|
ctx.CheckSystemPrivacy(system.Id, system.FrontHistoryPrivacy);
|
|
|
|
var totalSwitches = await ctx.Repository.GetSwitchCount(system.Id);
|
|
if (totalSwitches == 0) throw Errors.NoRegisteredSwitches;
|
|
|
|
if (durationStr == null)
|
|
durationStr = "30d";
|
|
|
|
// Picked the UNIX epoch as a random date
|
|
// even though we don't store switch timestamps in UNIX time
|
|
// I assume most people won't have switches logged previously to that (?)
|
|
if (durationStr == "full")
|
|
durationStr = "1970-01-01";
|
|
|
|
var now = SystemClock.Instance.GetCurrentInstant();
|
|
|
|
var rangeStart = DateUtils.ParseDateTime(durationStr, true, ctx.Zone);
|
|
if (rangeStart == null) throw Errors.InvalidDateTime(durationStr);
|
|
if (rangeStart.Value.ToInstant() > now) throw Errors.FrontPercentTimeInFuture;
|
|
|
|
var title = new StringBuilder("Frontpercent of ");
|
|
SystemGuildSettings guildSettings = null;
|
|
if (ctx.Guild != null)
|
|
guildSettings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, system.Id);
|
|
if (group != null)
|
|
title.Append($"{group.NameFor(ctx)} (`{group.DisplayHid(ctx.Config)}`)");
|
|
else if (ctx.Guild != null && guildSettings.DisplayName != null)
|
|
title.Append($"{guildSettings.DisplayName} (`{system.DisplayHid(ctx.Config)}`)");
|
|
else if (system.NameFor(ctx) != null)
|
|
title.Append($"{system.NameFor(ctx)} (`{system.DisplayHid(ctx.Config)}`)");
|
|
else
|
|
title.Append($"`{system.DisplayHid(ctx.Config)}`");
|
|
|
|
var frontpercent = await ctx.Database.Execute(c => ctx.Repository.GetFrontBreakdown(c, system.Id, group?.Id, rangeStart.Value.ToInstant(), now));
|
|
await ctx.Reply(embed: await _embeds.CreateFrontPercentEmbed(frontpercent, system, group, ctx.Zone,
|
|
ctx.LookupContextFor(system.Id), title.ToString(), ignoreNoFronters, showFlat));
|
|
}
|
|
|
|
private async Task<PKSystem> GetGroupSystem(Context ctx, PKGroup target)
|
|
{
|
|
var system = ctx.System;
|
|
if (system?.Id == target.System)
|
|
return system;
|
|
return await ctx.Repository.GetSystem(target.System)!;
|
|
}
|
|
|
|
private struct FrontHistoryEntry
|
|
{
|
|
public readonly Instant? LastTime;
|
|
public readonly PKSwitch ThisSwitch;
|
|
|
|
public FrontHistoryEntry(Instant? lastTime, PKSwitch thisSwitch)
|
|
{
|
|
LastTime = lastTime;
|
|
ThisSwitch = thisSwitch;
|
|
}
|
|
}
|
|
} |