refactor and users command
This commit is contained in:
parent
0a2d449b08
commit
5780d8eeab
9 changed files with 124 additions and 49 deletions
|
@ -12,6 +12,16 @@ pub struct CatsResp {
|
|||
pub categories: Vec<Category>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UsersResp {
|
||||
pub users: Vec<User>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct MemesResp {
|
||||
pub memes: Vec<Meme>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Category {
|
||||
pub id: String,
|
||||
|
@ -47,6 +57,29 @@ impl Into<Row<'_>> for &Meme {
|
|||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct MemesResp {
|
||||
pub memes: Vec<Meme>,
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
pub id: Option<String>,
|
||||
pub tokenhash: Option<String>,
|
||||
pub userdir: Option<String>,
|
||||
pub dayuploads: String,
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub fn get_id(&self) -> Option<&String> {
|
||||
self.id.as_ref()
|
||||
.or(self.tokenhash.as_ref())
|
||||
.or(self.userdir.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Row<'_>> for &User {
|
||||
fn into(self) -> Row<'static> {
|
||||
Row::new(vec![
|
||||
TableCell::new(&self.name),
|
||||
TableCell::new(&self.get_id().map(String::as_ref).unwrap_or("[No ID]")),
|
||||
TableCell::new(&self.dayuploads),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use anyhow::Result;
|
||||
use reqwest::Client;
|
||||
|
||||
use crate::util;
|
||||
use crate::util::{self, api};
|
||||
|
||||
pub async fn run(http: &Client, cat: Option<String>, user: Option<String>) -> Result<()> {
|
||||
let memes = util::memes(http).await?;
|
||||
let memes = api::memes(http).await?;
|
||||
|
||||
let memes = memes
|
||||
.iter()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
pub mod list;
|
||||
pub mod search;
|
||||
pub mod up;
|
||||
pub mod users;
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ use anyhow::Result;
|
|||
use log::info;
|
||||
use reqwest::Client;
|
||||
|
||||
use crate::util;
|
||||
use crate::util::{self, api};
|
||||
|
||||
pub async fn run(http: &Client, query: String) -> Result<()> {
|
||||
let memes = util::memes(http).await?;
|
||||
let memes = api::memes(http).await?;
|
||||
|
||||
let mut matches = vec![];
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use tokio::{fs::File, io::reader_stream};
|
|||
|
||||
use crate::{
|
||||
api::UpResp,
|
||||
util::{self, open_link},
|
||||
util::{open_link, api},
|
||||
};
|
||||
|
||||
pub async fn run(
|
||||
|
@ -20,7 +20,7 @@ pub async fn run(
|
|||
category: String,
|
||||
open: bool,
|
||||
) -> Result<()> {
|
||||
if !util::cats(http).await?.contains(&category) {
|
||||
if !api::cats(http).await?.contains(&category) {
|
||||
bail!(r#"category is invalid. use "cats" to list categories"#);
|
||||
}
|
||||
|
||||
|
|
16
cli/src/commands/users.rs
Normal file
16
cli/src/commands/users.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use reqwest::Client;
|
||||
use anyhow::Result;
|
||||
use crate::util::{self, api};
|
||||
|
||||
pub async fn run(http: &Client) -> Result<()> {
|
||||
let users = api::users(http).await?;
|
||||
let mut table = util::list_table();
|
||||
|
||||
for u in users {
|
||||
table.add_row(u.into())
|
||||
}
|
||||
|
||||
println!("{}", table.render());
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -53,6 +53,9 @@ enum Cmd {
|
|||
#[structopt(long, short, help = "filter by user")]
|
||||
user: Option<String>,
|
||||
},
|
||||
|
||||
#[structopt(about = "Lists all users")]
|
||||
Users,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -73,12 +76,13 @@ 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::cats(&http)
|
||||
Cmd::Cats => util::api::cats(&http)
|
||||
.await?
|
||||
.iter()
|
||||
.for_each(|c| println!("{}", c)),
|
||||
Cmd::Search { query } => commands::search::run(&http, query).await?,
|
||||
Cmd::List { category, user } => commands::list::run(&http, category, user).await?,
|
||||
Cmd::Users => commands::users::run(&http).await?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1,15 +1,66 @@
|
|||
use anyhow::Result;
|
||||
use log::info;
|
||||
use once_cell::sync::OnceCell;
|
||||
use reqwest::Client;
|
||||
use term_table::{Table, TableBuilder, TableStyle};
|
||||
use tokio::process::Command;
|
||||
|
||||
use crate::api::{CatsResp, Meme, MemesResp};
|
||||
#[macro_export]
|
||||
macro_rules! init_once_cell {
|
||||
($cell:ident, $init_fn:expr) => {
|
||||
match $cell.get() {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
let x = $init_fn;
|
||||
$cell.get_or_init(|| x)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cached api responses
|
||||
static CATS: OnceCell<Vec<String>> = OnceCell::new();
|
||||
static MEMES: OnceCell<Vec<Meme>> = OnceCell::new();
|
||||
/// ways to communicyte with the JM API
|
||||
pub mod api {
|
||||
use once_cell::sync::OnceCell;
|
||||
use log::info;
|
||||
use crate::api::{Meme, CatsResp, MemesResp, User, UsersResp};
|
||||
use reqwest::Client;
|
||||
use anyhow::Result;
|
||||
|
||||
// cached api responses
|
||||
static CATS: OnceCell<Vec<String>> = OnceCell::new();
|
||||
static MEMES: OnceCell<Vec<Meme>> = OnceCell::new();
|
||||
static USERS: OnceCell<Vec<User>> = OnceCell::new();
|
||||
|
||||
pub async fn cats(http: &Client) -> Result<&Vec<String>> {
|
||||
Ok(init_once_cell!(CATS, {
|
||||
info!("Requesting categories from server");
|
||||
let res = http
|
||||
.get("https://data.tilera.xyz/api/jensmemes/categories")
|
||||
.send()
|
||||
.await?;
|
||||
let cats = serde_json::from_slice::<CatsResp>(&res.bytes().await?)?;
|
||||
cats.categories.into_iter().map(|c| c.id).collect()
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn memes(http: &Client) -> Result<&Vec<Meme>> {
|
||||
Ok(init_once_cell!(MEMES, {
|
||||
info!("Requesting memes from server");
|
||||
let res = http
|
||||
.get("https://data.tilera.xyz/api/jensmemes/memes")
|
||||
.send()
|
||||
.await?;
|
||||
let memes = serde_json::from_slice::<MemesResp>(&res.bytes().await?)?;
|
||||
|
||||
memes.memes
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn users(http: &Client) -> Result<&Vec<User>> {
|
||||
Ok(init_once_cell!(USERS, {
|
||||
info!("Requesting users from server");
|
||||
let res = http.get("https://data.tilera.xyz/api/jensmemes/users").send().await?;
|
||||
let users = serde_json::from_slice::<UsersResp>(&res.bytes().await?)?;
|
||||
users.users
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn open_link(url: &str) -> anyhow::Result<()> {
|
||||
match std::env::var_os("BROWSER") {
|
||||
|
@ -22,38 +73,6 @@ pub async fn open_link(url: &str) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cats(http: &Client) -> Result<&Vec<String>> {
|
||||
Ok(match CATS.get() {
|
||||
None => {
|
||||
info!("Requesting categories from server");
|
||||
let res = http
|
||||
.get("https://data.tilera.xyz/api/jensmemes/categories")
|
||||
.send()
|
||||
.await?;
|
||||
let cats = serde_json::from_slice::<CatsResp>(&res.bytes().await?)?;
|
||||
|
||||
CATS.get_or_init(|| cats.categories.into_iter().map(|c| c.id).collect())
|
||||
},
|
||||
Some(x) => x,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn memes(http: &Client) -> Result<&Vec<Meme>> {
|
||||
Ok(match MEMES.get() {
|
||||
None => {
|
||||
info!("Requesting memes from server");
|
||||
let res = http
|
||||
.get("https://data.tilera.xyz/api/jensmemes/memes")
|
||||
.send()
|
||||
.await?;
|
||||
let memes = serde_json::from_slice::<MemesResp>(&res.bytes().await?)?;
|
||||
|
||||
MEMES.get_or_init(|| memes.memes)
|
||||
},
|
||||
Some(x) => x,
|
||||
})
|
||||
}
|
||||
|
||||
/// returns an empty table with the correct format settings for lists
|
||||
pub fn list_table<'a>() -> Table<'a> {
|
||||
TableBuilder::new()
|
||||
|
|
1
cli/test.json
Normal file
1
cli/test.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"status":200,"users":[{"name":"ACGaming#2986","tokenhash":"48f8912f48b94a78b1f0cb939d69a52f","userdir":"48f8912f48b94a78b1f0cb939d69a52f","id":"48f8912f48b94a78b1f0cb939d69a52f","dayuploads":"0"},{"name":"dytonpictures#6902","tokenhash":"8517773dea640ab54ce7c4f0e57062cf","userdir":"8517773dea640ab54ce7c4f0e57062cf","id":"8517773dea640ab54ce7c4f0e57062cf","dayuploads":"0"},{"name":"FISI | Johannes#3882","tokenhash":"1f4f5fff68a222d33f3cf4835a89b0f7","userdir":"1f4f5fff68a222d33f3cf4835a89b0f7","id":"1f4f5fff68a222d33f3cf4835a89b0f7","dayuploads":"0"},{"name":"Flogamer#5599","tokenhash":"b515ff80c705f4897b94ece312447891","userdir":"b515ff80c705f4897b94ece312447891","id":"b515ff80c705f4897b94ece312447891","dayuploads":"0"},{"name":"gold.ly#6685","tokenhash":"6c42dfd93466145a29b97854b394c62c","userdir":"6c42dfd93466145a29b97854b394c62c","id":"6c42dfd93466145a29b97854b394c62c","dayuploads":"0"},{"name":"Gordon Freeman#5706","tokenhash":"a6cf1ab6f2e58dce12390d02b36486fb","userdir":"a6cf1ab6f2e58dce12390d02b36486fb","id":"a6cf1ab6f2e58dce12390d02b36486fb","dayuploads":"0"},{"name":"Harry22218#4664","tokenhash":"c7dabba0cfbf18f9c1a323519a497500","userdir":"c7dabba0cfbf18f9c1a323519a497500","id":"c7dabba0cfbf18f9c1a323519a497500","dayuploads":"0"},{"name":"ITbyHF#0001","tokenhash":"584309714544fbe5961cdb4ddbc880d0","userdir":"584309714544fbe5961cdb4ddbc880d0","id":"584309714544fbe5961cdb4ddbc880d0","dayuploads":"2"},{"name":"ITbyHF#0152","tokenhash":"584309714544fbe5961cdb4ddbc880d0","userdir":null,"id":null,"dayuploads":"2"},{"name":"jonasled#0001","tokenhash":"480b1b7a2af6093e4f408676e746149d","userdir":"480b1b7a2af6093e4f408676e746149d","id":"480b1b7a2af6093e4f408676e746149d","dayuploads":"0"},{"name":"jonasled#8289","tokenhash":"480b1b7a2af6093e4f408676e746149d","userdir":"480b1b7a2af6093e4f408676e746149d","id":"480b1b7a2af6093e4f408676e746149d","dayuploads":"0"},{"name":"Justin#0738","tokenhash":"0403ae35f4fd4fc0747d539d29b4d733","userdir":"0403ae35f4fd4fc0747d539d29b4d733","id":"0403ae35f4fd4fc0747d539d29b4d733","dayuploads":"0"},{"name":"LordMZTE#9001","tokenhash":"e8453a9f812165a8686ad32c149774c6","userdir":"e8453a9f812165a8686ad32c149774c6","id":"e8453a9f812165a8686ad32c149774c6","dayuploads":"0"},{"name":"Lukforgame#2830","tokenhash":"b77d14ffe025e3d05b936b8fdc2304e9","userdir":"b77d14ffe025e3d05b936b8fdc2304e9","id":"b77d14ffe025e3d05b936b8fdc2304e9","dayuploads":"0"},{"name":"Penta#2590","tokenhash":"18f9a2b5f6afc7a146343ed15903dc36","userdir":"18f9a2b5f6afc7a146343ed15903dc36","id":"18f9a2b5f6afc7a146343ed15903dc36","dayuploads":"0"},{"name":"Realtox#1212","tokenhash":"f36daa5295a543ccc818a2b26217efbd","userdir":"f36daa5295a543ccc818a2b26217efbd","id":"f36daa5295a543ccc818a2b26217efbd","dayuploads":"0"},{"name":"tilera#1999","tokenhash":"d9d03ec0275ad5181bb1e3fc5cbc5205","userdir":"d9d03ec0275ad5181bb1e3fc5cbc5205","id":"d9d03ec0275ad5181bb1e3fc5cbc5205","dayuploads":"2"},{"name":"tilera#3241","tokenhash":"be241a36103d0059cd1293e47f4daf1a","userdir":"be241a36103d0059cd1293e47f4daf1a","id":"be241a36103d0059cd1293e47f4daf1a","dayuploads":"0"},{"name":"Velentix#2279","tokenhash":"96ee47b8455b8a88d1039252b113ca13","userdir":null,"id":null,"dayuploads":"0"}]}
|
Loading…
Reference in a new issue