refactor and users command

This commit is contained in:
LordMZTE 2020-12-19 19:43:23 +01:00
parent 0a2d449b08
commit 5780d8eeab
9 changed files with 124 additions and 49 deletions

View file

@ -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),
])
}
}

View file

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

View file

@ -1,3 +1,5 @@
pub mod list;
pub mod search;
pub mod up;
pub mod users;

View file

@ -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![];

View file

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

View file

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

View file

@ -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
View 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"}]}