feat: implement system front commands

This commit is contained in:
dusk 2025-09-26 14:58:59 +00:00
parent 4e0c56f6cb
commit 104083aac1
No known key found for this signature in database
5 changed files with 35 additions and 28 deletions

View file

@ -159,6 +159,9 @@ public partial class CommandTree
Commands.SwitchEditOut(_, _) => ctx.Execute<Switch>(SwitchEditOut, m => m.SwitchEditOut(ctx)),
Commands.SwitchDelete(var param, var flags) => ctx.Execute<Switch>(SwitchDelete, m => m.SwitchDelete(ctx, flags.all)),
Commands.SwitchCopy(var param, var flags) => ctx.Execute<Switch>(SwitchCopy, m => m.SwitchEdit(ctx, param.targets, true, flags.first, flags.remove, flags.append, flags.prepend)),
Commands.SystemFronter(var param, var flags) => ctx.Execute<SystemFront>(SystemFronter, m => m.Fronter(ctx, param.target)),
Commands.SystemFronterHistory(var param, var flags) => ctx.Execute<SystemFront>(SystemFrontHistory, m => m.FrontHistory(ctx, param.target, flags.clear)),
Commands.SystemFronterPercent(var param, var flags) => ctx.Execute<SystemFront>(SystemFrontPercent, m => m.FrontPercent(ctx, param.target, flags.duration, flags.fronters_only, flags.flat)),
_ =>
// this should only ever occur when deving if commands are not implemented...
ctx.Reply(
@ -407,19 +410,6 @@ public partial class CommandTree
await ctx.CheckSystem(target).Execute<SystemList>(SystemList, m => m.MemberList(ctx, target));
else if (ctx.Match("find", "search", "query", "fd", "s"))
await ctx.CheckSystem(target).Execute<SystemList>(SystemFind, m => m.MemberList(ctx, target));
else if (ctx.Match("f", "front", "fronter", "fronters"))
{
if (ctx.Match("h", "history"))
await ctx.CheckSystem(target).Execute<SystemFront>(SystemFrontHistory, m => m.SystemFrontHistory(ctx, target));
else if (ctx.Match("p", "percent", "%"))
await ctx.CheckSystem(target).Execute<SystemFront>(SystemFrontPercent, m => m.FrontPercent(ctx, system: target));
else
await ctx.CheckSystem(target).Execute<SystemFront>(SystemFronter, m => m.SystemFronter(ctx, target));
}
else if (ctx.Match("fh", "fronthistory", "history", "switches"))
await ctx.CheckSystem(target).Execute<SystemFront>(SystemFrontHistory, m => m.SystemFrontHistory(ctx, target));
else if (ctx.Match("fp", "frontpercent", "front%", "frontbreakdown"))
await ctx.CheckSystem(target).Execute<SystemFront>(SystemFrontPercent, m => m.FrontPercent(ctx, system: target));
else if (ctx.Match("groups", "gs"))
await ctx.CheckSystem(target).Execute<Groups>(GroupList, g => g.ListSystemGroups(ctx, target));
else if (ctx.Match("id"))

View file

@ -15,7 +15,7 @@ public class SystemFront
_embeds = embeds;
}
public async Task SystemFronter(Context ctx, PKSystem system)
public async Task Fronter(Context ctx, PKSystem system)
{
if (system == null) throw Errors.NoSystemError(ctx.DefaultPrefix);
ctx.CheckSystemPrivacy(system.Id, system.FrontPrivacy);
@ -26,9 +26,9 @@ public class SystemFront
await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system.Id)));
}
public async Task SystemFrontHistory(Context ctx, PKSystem system)
public async Task FrontHistory(Context ctx, PKSystem system, bool clear = false)
{
if (ctx.MatchFlag("clear", "c") || ctx.PeekArgument() == "clear")
if (clear)
{
await new Switch().SwitchDelete(ctx, true);
return;
@ -106,7 +106,7 @@ public class SystemFront
);
}
public async Task FrontPercent(Context ctx, PKSystem? system = null, PKGroup? group = null)
public async Task FrontPercent(Context ctx, PKSystem? system = null, string durationStr = "30d", 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);
@ -116,11 +116,6 @@ public class SystemFront
var totalSwitches = await ctx.Repository.GetSwitchCount(system.Id);
if (totalSwitches == 0) throw Errors.NoRegisteredSwitches;
var ignoreNoFronters = ctx.MatchFlag("fo", "fronters-only");
var showFlat = ctx.MatchFlag("flat");
var durationStr = ctx.RemainderOrNull() ?? "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 (?)

View file

@ -223,6 +223,18 @@ pub fn edit() -> impl Iterator<Item = Command> {
.help("Changes a specific privacy setting for your system"),
].into_iter();
let system_front = tokens!(system_target, ("front", ["fronter", "fronters", "f"]));
let system_front_cmd = [
command!(system_front => "system_fronter"),
command!(system_front, ("history", ["h"]) => "system_fronter_history")
.flag(("clear", ["c"])),
command!(system_front, ("percent", ["p", "%"]) => "system_fronter_percent")
.flag(("duration", OpaqueString))
.flag(("fronters-only", ["fo"]))
.flag("flat"),
]
.into_iter();
system_new_cmd
.chain(system_name_self_cmd)
.chain(system_server_name_self_cmd)
@ -248,4 +260,5 @@ pub fn edit() -> impl Iterator<Item = Command> {
.chain(system_server_avatar_cmd)
.chain(system_banner_cmd)
.chain(system_info_cmd)
.chain(system_front_cmd)
}

View file

@ -58,10 +58,14 @@ pub fn parse_command(
match &result {
// todo: better error messages for these?
TokenMatchResult::MissingParameter { name } => {
return Err(format!("Expected parameter `{name}` in command `{prefix}{input} {found_token}`."));
return Err(format!(
"Expected parameter `{name}` in command `{prefix}{input} {found_token}`."
));
}
TokenMatchResult::ParameterMatchError { input: raw, msg } => {
return Err(format!("Parameter `{raw}` in command `{prefix}{input}` could not be parsed: {msg}."));
return Err(format!(
"Parameter `{raw}` in command `{prefix}{input}` could not be parsed: {msg}."
));
}
// don't use a catch-all here, we want to make sure compiler errors when new errors are added
TokenMatchResult::MatchedParameter { .. } | TokenMatchResult::MatchedValue => {}
@ -109,7 +113,9 @@ pub fn parse_command(
raw_flags.push((current_token_idx, matched_flag));
}
// if we have a command, stop parsing and return it (only if there is no remaining input)
if current_pos >= input.len() && let Some(command) = local_tree.command() {
if current_pos >= input.len()
&& let Some(command) = local_tree.command()
{
// match the flags against this commands flags
let mut flags: HashMap<String, Option<ParameterValue>> = HashMap::new();
let mut misplaced_flags: Vec<MatchedFlag> = Vec::new();
@ -182,8 +188,11 @@ pub fn parse_command(
write!(
&mut error,
" {} seem to be applicable in this command (`{prefix}{command}`).",
(invalid_flags.len() > 1).then_some("don't").unwrap_or("doesn't")
).expect("oom");
(invalid_flags.len() > 1)
.then_some("don't")
.unwrap_or("doesn't")
)
.expect("oom");
return Err(error);
}
println!("{} {flags:?} {params:?}", command.cb);

View file

@ -76,7 +76,7 @@ impl Token {
msg: err,
}
}
},
}
}),
// don't add a _ match here!
}