category list improvements and cleanups
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
34bc07c3c4
commit
bb33d3b015
10 changed files with 57 additions and 31 deletions
|
@ -2,3 +2,5 @@
|
|||
|
||||
## cli
|
||||
- optimized listing by not searching on the client but on the server
|
||||
- categories now shown with name instead of just ID
|
||||
|
||||
|
|
|
@ -1,34 +1,41 @@
|
|||
use crate::util::IntoTableRow;
|
||||
use anyhow::{anyhow, Result};
|
||||
use serde::Deserialize;
|
||||
use term_table::{row::Row, table_cell::TableCell};
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct UpResp {
|
||||
pub files: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct CatsResp {
|
||||
pub categories: Vec<Category>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct UsersResp {
|
||||
pub users: Vec<User>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct MemesResp {
|
||||
pub memes: Vec<Meme>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Category {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
impl IntoTableRow for Category {
|
||||
fn into_table_row(&self) -> Row<'_> {
|
||||
Row::new(vec![TableCell::new(&self.id), TableCell::new(&self.name)])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Meme {
|
||||
pub id: String,
|
||||
pub link: String,
|
||||
|
@ -46,8 +53,8 @@ impl Meme {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Row<'_>> for &Meme {
|
||||
fn into(self) -> Row<'static> {
|
||||
impl IntoTableRow for Meme {
|
||||
fn into_table_row(&self) -> Row<'_> {
|
||||
Row::new(vec![
|
||||
TableCell::new(&self.link),
|
||||
TableCell::new(&self.category),
|
||||
|
@ -56,7 +63,7 @@ impl Into<Row<'_>> for &Meme {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq)]
|
||||
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
pub id: Option<String>,
|
||||
|
@ -74,8 +81,8 @@ impl User {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<Row<'_>> for &User {
|
||||
fn into(self) -> Row<'static> {
|
||||
impl IntoTableRow for User {
|
||||
fn into_table_row(&self) -> Row<'_> {
|
||||
Row::new(vec![
|
||||
TableCell::new(&self.name),
|
||||
TableCell::new(&self.get_id().map(String::as_ref).unwrap_or("[No ID]")),
|
||||
|
|
18
cli/src/commands/cats.rs
Normal file
18
cli/src/commands/cats.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::util::{self, api, IntoTableRow};
|
||||
use reqwest::Client;
|
||||
|
||||
pub async fn run(http: &Client) -> anyhow::Result<()> {
|
||||
// clone required, because for sorting the immutable reference will not work
|
||||
let mut cats = api::cats(http).await?.clone();
|
||||
cats.sort_by(|a, b| a.id.cmp(&b.id));
|
||||
|
||||
let mut table = util::list_table();
|
||||
|
||||
for cat in &cats {
|
||||
table.add_row(cat.into_table_row());
|
||||
}
|
||||
|
||||
println!("{}", table.render());
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use reqwest::Client;
|
||||
|
||||
use crate::util::{self, api, MemeSorting};
|
||||
use crate::util::{self, api, IntoTableRow, MemeSorting};
|
||||
|
||||
pub async fn run(
|
||||
http: &Client,
|
||||
|
@ -42,7 +42,7 @@ pub async fn run(
|
|||
let mut table = util::list_table();
|
||||
|
||||
for m in memes {
|
||||
table.add_row(m.into());
|
||||
table.add_row(m.into_table_row());
|
||||
}
|
||||
|
||||
println!("{}", table.render());
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
pub mod cats;
|
||||
pub mod list;
|
||||
pub mod search;
|
||||
pub mod up;
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
|||
use log::info;
|
||||
use reqwest::Client;
|
||||
|
||||
use crate::util::{self, api};
|
||||
use crate::util::{self, api, IntoTableRow};
|
||||
|
||||
pub async fn run(
|
||||
http: &Client,
|
||||
|
@ -49,7 +49,7 @@ pub async fn run(
|
|||
let mut table = util::list_table();
|
||||
|
||||
for m in matches {
|
||||
table.add_row(m.0.into());
|
||||
table.add_row(m.0.into_table_row());
|
||||
}
|
||||
|
||||
println!("{}", table.render());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{bail, Result};
|
||||
use anyhow::Result;
|
||||
use log::info;
|
||||
use reqwest::{
|
||||
multipart::{Form, Part},
|
||||
|
@ -9,7 +9,7 @@ use tokio::{fs::File, io::reader_stream};
|
|||
|
||||
use crate::{
|
||||
api::UpResp,
|
||||
util::{api, open_link},
|
||||
util::{self, open_link},
|
||||
};
|
||||
|
||||
pub async fn run(
|
||||
|
@ -20,9 +20,7 @@ pub async fn run(
|
|||
category: String,
|
||||
open: bool,
|
||||
) -> Result<()> {
|
||||
if !api::cats(http).await?.contains(&category) {
|
||||
bail!(r#"category is invalid. use "cats" to list categories"#);
|
||||
}
|
||||
util::assert_category_exists(http, &category).await?;
|
||||
|
||||
let res = http
|
||||
.post("https://data.tilera.xyz/api/jensmemes/upload")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::util::{self, api};
|
||||
use crate::util::{self, api, IntoTableRow};
|
||||
use anyhow::Result;
|
||||
use reqwest::Client;
|
||||
|
||||
|
@ -7,7 +7,7 @@ pub async fn run(http: &Client) -> Result<()> {
|
|||
let mut table = util::list_table();
|
||||
|
||||
for u in users {
|
||||
table.add_row(u.into())
|
||||
table.add_row(u.into_table_row())
|
||||
}
|
||||
|
||||
println!("{}", table.render());
|
||||
|
|
|
@ -92,10 +92,7 @@ async fn main() -> Result<()> {
|
|||
let name = name.unwrap_or_else(|| file.clone());
|
||||
commands::up::run(&http, token, file, name, category, open).await?;
|
||||
},
|
||||
Cmd::Cats => util::api::cats(&http)
|
||||
.await?
|
||||
.iter()
|
||||
.for_each(|c| println!("{}", c)),
|
||||
Cmd::Cats => commands::cats::run(&http).await?,
|
||||
Cmd::Search {
|
||||
query,
|
||||
user,
|
||||
|
|
|
@ -25,7 +25,7 @@ pub mod consts {
|
|||
|
||||
/// ways to communicyte with the JM API
|
||||
pub mod api {
|
||||
use crate::api::{CatsResp, Meme, MemesResp, User, UsersResp};
|
||||
use crate::api::{Category, CatsResp, Meme, MemesResp, User, UsersResp};
|
||||
use anyhow::Result;
|
||||
use lazy_static::lazy_static;
|
||||
use log::info;
|
||||
|
@ -39,14 +39,14 @@ pub mod api {
|
|||
|
||||
// cached api responses
|
||||
static USERS: OnceCell<Vec<User>> = OnceCell::new();
|
||||
static CATS: OnceCell<Vec<String>> = OnceCell::new();
|
||||
static CATS: OnceCell<Vec<Category>> = OnceCell::new();
|
||||
lazy_static! {
|
||||
// is this type long enough yet?
|
||||
static ref MEMES: Mutex<HashMap<(Option<String>, Option<String>), Arc<Vec<Meme>>>> =
|
||||
Mutex::new(HashMap::new());
|
||||
}
|
||||
|
||||
pub async fn cats(http: &Client) -> Result<&Vec<String>> {
|
||||
pub async fn cats(http: &Client) -> Result<&Vec<Category>> {
|
||||
Ok(init_once_cell!(CATS, {
|
||||
info!("Requesting categories from server");
|
||||
let res = http
|
||||
|
@ -54,7 +54,7 @@ pub mod api {
|
|||
.send()
|
||||
.await?;
|
||||
let cats = serde_json::from_slice::<CatsResp>(&res.bytes().await?)?;
|
||||
cats.categories.into_iter().map(|c| c.id).collect()
|
||||
cats.categories.into_iter().collect()
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -177,8 +177,11 @@ pub async fn assert_user_exists(http: &Client, user: &str) -> anyhow::Result<()>
|
|||
Ok(())
|
||||
}
|
||||
pub async fn assert_category_exists(http: &Client, cat: &str) -> anyhow::Result<()> {
|
||||
if !api::cats(http).await?.iter().any(|c| c == cat) {
|
||||
if !api::cats(http).await?.iter().any(|c| c.id == cat) {
|
||||
bail!(consts::NO_SUCH_CATEGORY_ERROR);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub trait IntoTableRow {
|
||||
fn into_table_row(&self) -> term_table::row::Row;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue