diff --git a/assyst-core/src/command/arguments.rs b/assyst-core/src/command/arguments.rs index c5e0fb7..764030e 100644 --- a/assyst-core/src/command/arguments.rs +++ b/assyst-core/src/command/arguments.rs @@ -37,6 +37,33 @@ pub trait ParseArgument: Sized { } } +impl ParseArgument for i64 { + async fn parse_raw_message(ctxt: &mut RawMessageParseCtxt<'_>, label: Label) -> Result { + let word = ctxt.next_word(label)?; + Ok(word.parse()?) + } + + async fn parse_command_option( + ctxt: &mut InteractionCommandParseCtxt<'_>, + label: Label, + ) -> Result { + let next = &ctxt.option_by_name(&label.unwrap().0)?.value; + if let CommandOptionValue::Integer(option) = next { + Ok(*option as i64) + } else { + // cloning is fine since this should (ideally) never happen + Err(TagParseError::MismatchedCommandOptionType(( + "i64".to_owned(), + next.clone(), + ))) + } + } + + fn as_command_option(name: &str) -> CommandOption { + IntegerBuilder::new(name, "integer option").required(true).build() + } +} + impl ParseArgument for u64 { async fn parse_raw_message(ctxt: &mut RawMessageParseCtxt<'_>, label: Label) -> Result { let word = ctxt.next_word(label)?; diff --git a/assyst-core/src/command/image/mod.rs b/assyst-core/src/command/image/mod.rs index 5ebcc09..1b5b099 100644 --- a/assyst-core/src/command/image/mod.rs +++ b/assyst-core/src/command/image/mod.rs @@ -780,6 +780,27 @@ pub async fn scramble(ctxt: CommandCtxt<'_>, source: Image) -> anyhow::Result<() Ok(()) } +#[command( + description = "set how many times a gif loops", + aliases = ["loop"], + cooldown = Duration::from_secs(6), + access = Availability::Public, + category = Category::Image, + usage = "[image] [loop count (-1 for infinite)]", + examples = ["https://link.to.my/image.png 3", "https://link.to.my/image.png -1"], + send_processing = true +)] +pub async fn setloop(ctxt: CommandCtxt<'_>, source: Image, loops: i64) -> anyhow::Result<()> { + let result = ctxt + .flux_handler() + .set_loop(source.0, ctxt.data.author.id.get(), ctxt.data.guild_id.map(|x| x.get()), loops) + .await?; + + ctxt.reply(result).await?; + + Ok(()) +} + #[command( description = "speed up or slow down a gif or video", aliases = ["gspeed", "gifspeed"], diff --git a/assyst-core/src/command/registry.rs b/assyst-core/src/command/registry.rs index ad19968..20a49b7 100644 --- a/assyst-core/src/command/registry.rs +++ b/assyst-core/src/command/registry.rs @@ -71,6 +71,7 @@ declare_commands!( image::reverse_command, image::rotate_command, image::scramble_command, + image::setloop_command, image::speechbubble::speechbubble_command, image::speed_command, image::spin_command, diff --git a/assyst-flux-iface/src/jobs.rs b/assyst-flux-iface/src/jobs.rs index a73e02c..7b49d05 100644 --- a/assyst-flux-iface/src/jobs.rs +++ b/assyst-flux-iface/src/jobs.rs @@ -550,6 +550,20 @@ impl FluxHandler { self.run_flux(request, limits.time).await } + pub async fn set_loop(&self, media: Vec, user_id: u64, guild_id: Option, loops: i64) -> FluxResult { + let limits = self.get_request_limits(user_id, guild_id).await?; + + let mut request = FluxRequest::new_with_input_and_limits(media, &limits); + + let mut options = HashMap::new(); + options.insert("loops".to_owned(), loops.to_string()); + + request.operation("set-loop".to_owned(), options); + request.output(); + + self.run_flux(request, limits.time).await + } + pub async fn scramble(&self, media: Vec, user_id: u64, guild_id: Option) -> FluxResult { let limits = self.get_request_limits(user_id, guild_id).await?; diff --git a/assyst-flux-iface/src/lib.rs b/assyst-flux-iface/src/lib.rs index 60a15fb..586452f 100644 --- a/assyst-flux-iface/src/lib.rs +++ b/assyst-flux-iface/src/lib.rs @@ -171,9 +171,9 @@ impl FluxHandler { if !output.status.success() { bail!( - "Something went wrong ({}): {}", - output.status.to_string(), - string_from_likely_utf8(output.stderr).trim() + "{} ({})", + string_from_likely_utf8(output.stderr).trim(), + output.status.to_string() ); }