2021-04-06 20:46:21 +02:00
|
|
|
use anyhow::{Context, Result};
|
2020-12-06 14:57:14 +01:00
|
|
|
use log::info;
|
2021-04-06 20:46:21 +02:00
|
|
|
use std::io::Write;
|
2020-12-05 22:20:08 +01:00
|
|
|
|
2021-05-27 18:01:30 +02:00
|
|
|
use crate::{
|
|
|
|
table::{self, AsTableRow},
|
|
|
|
util,
|
|
|
|
};
|
|
|
|
use jm_client_core::JMClient;
|
2020-12-05 22:20:08 +01:00
|
|
|
|
2020-12-21 23:06:50 +01:00
|
|
|
pub async fn run(
|
2021-05-27 18:01:30 +02:00
|
|
|
client: &JMClient,
|
2020-12-21 23:06:50 +01:00
|
|
|
query: String,
|
|
|
|
user: Option<String>,
|
2021-04-06 20:46:21 +02:00
|
|
|
category: Option<String>,
|
|
|
|
firsturl: bool,
|
|
|
|
cat: bool,
|
2020-12-21 23:06:50 +01:00
|
|
|
) -> Result<()> {
|
|
|
|
let (memes, ..) = tokio::try_join!(
|
2021-05-27 18:01:30 +02:00
|
|
|
async { client.get_memes().await.map_err(|e| e.into()) },
|
2020-12-21 23:06:50 +01:00
|
|
|
async {
|
|
|
|
if let Some(u) = user.as_ref() {
|
2021-05-27 18:01:30 +02:00
|
|
|
util::assert_user_exists(client, u).await
|
2020-12-21 23:06:50 +01:00
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
},
|
|
|
|
async {
|
2021-04-06 20:46:21 +02:00
|
|
|
if let Some(c) = category.as_ref() {
|
2021-05-27 18:01:30 +02:00
|
|
|
util::assert_category_exists(client, c).await
|
2020-12-21 23:06:50 +01:00
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)?;
|
2020-12-05 22:20:08 +01:00
|
|
|
|
|
|
|
let mut matches = vec![];
|
|
|
|
|
2020-12-06 14:57:14 +01:00
|
|
|
info!("Starting search with query '{}'", query);
|
2020-12-21 23:06:50 +01:00
|
|
|
|
2021-05-27 18:01:30 +02:00
|
|
|
let memes = memes
|
|
|
|
.iter()
|
|
|
|
.filter(|m| category.as_ref().map(|c| &m.category == c).unwrap_or(true))
|
|
|
|
.filter(|m| user.as_ref().map(|u| &m.user == u).unwrap_or(true));
|
|
|
|
|
|
|
|
for meme in memes {
|
2020-12-06 14:57:14 +01:00
|
|
|
let file_name = meme.file_name()?;
|
|
|
|
if let Some(score) = fuzzy_matcher::clangd::fuzzy_match(file_name, &query) {
|
|
|
|
info!("Found matching meme '{}' with score {}", file_name, score);
|
2020-12-05 22:20:08 +01:00
|
|
|
matches.push((meme, score));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-05 22:31:02 +01:00
|
|
|
matches.sort_by(|a, b| b.1.cmp(&a.1));
|
2021-04-06 20:46:21 +02:00
|
|
|
let res = match (firsturl, cat) {
|
|
|
|
(false, false) => {
|
2021-05-12 20:13:06 +02:00
|
|
|
let mut table = table::list_table();
|
2020-12-05 22:20:08 +01:00
|
|
|
|
2021-04-06 20:46:21 +02:00
|
|
|
for m in matches {
|
2021-05-27 18:01:30 +02:00
|
|
|
table.add_row(m.0.as_table_row());
|
2021-04-06 20:46:21 +02:00
|
|
|
}
|
|
|
|
table.render().into_bytes()
|
|
|
|
},
|
2020-12-05 22:20:08 +01:00
|
|
|
|
2021-04-06 20:46:21 +02:00
|
|
|
(true, _) => matches
|
|
|
|
.first()
|
|
|
|
.context("No matches found")?
|
|
|
|
.0
|
|
|
|
.link
|
|
|
|
.clone()
|
|
|
|
.into_bytes(),
|
|
|
|
(_, true) => {
|
|
|
|
let url = &matches.first().context("No results found")?.0.link;
|
2021-05-27 18:01:30 +02:00
|
|
|
client.http.get(url).send().await?.bytes().await?.to_vec()
|
2021-04-06 20:46:21 +02:00
|
|
|
},
|
|
|
|
};
|
2020-12-05 22:20:08 +01:00
|
|
|
|
2021-04-06 20:46:21 +02:00
|
|
|
let stdout = std::io::stdout();
|
|
|
|
let mut handle = stdout.lock();
|
|
|
|
handle.write_all(&res)?;
|
2020-12-05 22:20:08 +01:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|