category list improvements and cleanups
continuous-integration/drone/push Build is passing Details

This commit is contained in:
LordMZTE 2021-01-05 15:13:19 +01:00
parent 34bc07c3c4
commit bb33d3b015
10 changed files with 57 additions and 31 deletions

View File

@ -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

View File

@ -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
View 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(())
}

View File

@ -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());

View File

@ -1,3 +1,4 @@
pub mod cats;
pub mod list;
pub mod search;
pub mod up;

View File

@ -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());

View File

@ -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")

View File

@ -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());

View File

@ -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,

View File

@ -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;
}