Allow multiple image outputs on !image/!nsfw

This commit is contained in:
Natsu Kagami 2021-01-16 02:25:47 +09:00
parent 8d4c3e01d8
commit 0cbf74fb82
Signed by: nki
GPG key ID: 7306B3D3C3AD6E51

View file

@ -48,19 +48,43 @@ async fn message_command(
rating: Rating,
) -> CommandResult {
let tags = args.remains().unwrap_or("touhou");
let image = get_image(
let images = get_image(
ctx.data.read().await.get::<HTTPClient>().unwrap(),
rating,
tags,
)
.await?;
match image {
None => msg.reply(&ctx, "🖼️ No image found...\n💡 Tip: In danbooru, character names follow Japanese standards (last name before first name), so **Hakurei Reimu** might give you an image while **Reimu Hakurei** won't.").await,
Some(url) => msg.reply(
&ctx,
format!("🖼️ Here's the image you requested!\n\n{}", url),
).await,
}?;
if images.is_empty() {
msg.reply(&ctx, "🖼️ No image found...\n💡 Tip: In danbooru, character names follow Japanese standards (last name before first name), so **Hakurei Reimu** might give you an image while **Reimu Hakurei** won't.").await?;
return Ok(());
}
let images = std::sync::Arc::new(images);
paginate_fn(
move |page, ctx, msg: &mut Message| {
let images = images.clone();
Box::pin(async move {
let page = page as usize;
if page >= images.len() {
Ok(false)
} else {
msg.edit(ctx, |f| {
f.content(format!(
"[🖼️ **{}/{}**] Here's the image you requested!\n\n{}", page + 1,
images.len(),
images[page]
))
})
.await
.map(|_| true)
.map_err(|e| e.into())
}
})
},
ctx,
msg.channel_id,
std::time::Duration::from_secs(120),
)
.await?;
Ok(())
}
@ -69,7 +93,7 @@ async fn get_image(
client: &<HTTPClient as TypeMapKey>::Value,
rating: Rating,
tags: &str,
) -> Result<Option<String>, Error> {
) -> Result<Vec<String>, Error> {
// Fix the tags: change whitespaces to +
let tags = tags.split_whitespace().collect::<Vec<_>>().join("_");
let req = client
@ -78,19 +102,21 @@ async fn get_image(
rating.to_string(),
tags
))
.query(&[("limit", "1"), ("random", "true")])
.query(&[("limit", "50"), ("random", "true")])
.build()?;
println!("{:?}", req.url());
let response: Vec<PostResponse> = client.execute(req).await?.json().await?;
Ok(response
.into_iter()
.next()
.map(|v| format!("https://danbooru.donmai.us/posts/{}", v.id)))
.filter_map(|v| {
v.id.map(|id| format!("https://danbooru.donmai.us/posts/{}", id))
})
.collect())
}
#[derive(Deserialize, Debug)]
struct PostResponse {
id: u64,
id: Option<u64>,
}
#[derive(Copy, Clone, Debug)]