refactors and add timestamp to meme display
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
LordMZTE 2021-05-12 20:13:06 +02:00
parent 1463a3cf0d
commit 3c395a34a7
10 changed files with 70 additions and 30 deletions

View file

@ -16,18 +16,19 @@ name = "jm"
path = "src/main.rs" path = "src/main.rs"
[dependencies] [dependencies]
jm_client_core = { path = "../jm_client_core" }
anyhow = "1.0.34" anyhow = "1.0.34"
chrono = "0.4.19"
clap = "2.33.3" clap = "2.33.3"
env_logger = "0.8.2" env_logger = "0.8.2"
fuzzy-matcher = "0.3.7" fuzzy-matcher = "0.3.7"
jm_client_core = { path = "../jm_client_core" }
log = "0.4.11" log = "0.4.11"
opener = "0.4.1" opener = "0.4.1"
reqwest = { version = "0.10", features = ["stream"] }
structopt = "0.3.21" structopt = "0.3.21"
term-table = "1.3.0" term-table = "1.3.0"
term_size = "0.3.2" term_size = "0.3.2"
tokio = { version = "0.2.23", features = ["macros", "fs", "process"] } tokio = { version = "0.2.23", features = ["macros", "fs", "process"] }
url = "2.2.0" url = "2.2.0"
reqwest = { version = "0.10", features = ["stream"] }

View file

@ -1,4 +1,4 @@
use crate::util::{self, IntoTableRow}; use crate::table::{self, IntoTableRow};
use jm_client_core::util::api; use jm_client_core::util::api;
use reqwest::Client; use reqwest::Client;
@ -7,7 +7,7 @@ pub async fn run(http: &Client) -> anyhow::Result<()> {
let mut cats = api::cats(http).await?.clone(); let mut cats = api::cats(http).await?.clone();
cats.sort_by(|a, b| a.id.cmp(&b.id)); cats.sort_by(|a, b| a.id.cmp(&b.id));
let mut table = util::list_table(); let mut table = table::list_table();
for cat in &cats { for cat in &cats {
table.add_row(cat.into_table_row()); table.add_row(cat.into_table_row());

View file

@ -5,7 +5,7 @@ use std::{
process::{Command, Stdio}, process::{Command, Stdio},
}; };
use crate::util::IntoTableRow; use crate::table::{self, IntoTableRow};
use jm_client_core::util::{self, api, MemeSorting}; use jm_client_core::util::{self, api, MemeSorting};
pub async fn run( pub async fn run(
@ -45,7 +45,7 @@ pub async fn run(
s.sort_with(&mut memes); s.sort_with(&mut memes);
} }
let mut table = crate::util::list_table(); let mut table = table::list_table();
for m in memes.iter() { for m in memes.iter() {
table.add_row(m.into_table_row()); table.add_row(m.into_table_row());

View file

@ -3,7 +3,7 @@ use log::info;
use reqwest::Client; use reqwest::Client;
use std::io::Write; use std::io::Write;
use crate::util::IntoTableRow; use crate::table::{self, IntoTableRow};
use jm_client_core::util::{self, api}; use jm_client_core::util::{self, api};
pub async fn run( pub async fn run(
@ -51,7 +51,7 @@ pub async fn run(
matches.sort_by(|a, b| b.1.cmp(&a.1)); matches.sort_by(|a, b| b.1.cmp(&a.1));
let res = match (firsturl, cat) { let res = match (firsturl, cat) {
(false, false) => { (false, false) => {
let mut table = crate::util::list_table(); let mut table = table::list_table();
for m in matches { for m in matches {
table.add_row(m.0.into_table_row()); table.add_row(m.0.into_table_row());

View file

@ -1,11 +1,11 @@
use crate::util::IntoTableRow; use crate::table::{self, IntoTableRow};
use anyhow::Result; use anyhow::Result;
use jm_client_core::util::api; use jm_client_core::util::api;
use reqwest::Client; use reqwest::Client;
pub async fn run(http: &Client) -> Result<()> { pub async fn run(http: &Client) -> Result<()> {
let users = api::users(http).await?; let users = api::users(http).await?;
let mut table = crate::util::list_table(); let mut table = table::list_table();
for u in users { for u in users {
table.add_row(u.into_table_row()) table.add_row(u.into_table_row())

View file

@ -3,8 +3,8 @@ use jm_client_core::util::MemeSorting;
use reqwest::Client; use reqwest::Client;
use structopt::StructOpt; use structopt::StructOpt;
mod api;
mod commands; mod commands;
mod table;
mod util; mod util;
#[derive(StructOpt)] #[derive(StructOpt)]
@ -75,7 +75,7 @@ enum Cmd {
#[structopt( #[structopt(
long, long,
short, short,
help = "how to sort the results. can be id, user, category or link" help = "how to sort the results. can be id, user, category, timestamp or link"
)] )]
sort: Option<MemeSorting>, sort: Option<MemeSorting>,

View file

@ -1,6 +1,20 @@
use crate::util::IntoTableRow; use chrono::{Local, TimeZone};
use jm_client_core::api::{Category, Meme, User}; use jm_client_core::api::{Category, Meme, User};
use term_table::{row::Row, table_cell::TableCell}; use term_table::{row::Row, table_cell::TableCell, Table, TableBuilder, TableStyle};
/// returns an empty table with the correct format settings for lists
pub fn list_table<'a>() -> Table<'a> {
TableBuilder::new()
.style(TableStyle::simple())
.separate_rows(false)
.has_top_boarder(false)
.has_bottom_boarder(false)
.build()
}
pub trait IntoTableRow {
fn into_table_row(&self) -> term_table::row::Row;
}
impl IntoTableRow for Category { impl IntoTableRow for Category {
fn into_table_row(&self) -> Row<'_> { fn into_table_row(&self) -> Row<'_> {
@ -14,6 +28,7 @@ impl IntoTableRow for Meme {
TableCell::new(&self.link), TableCell::new(&self.link),
TableCell::new(&self.category), TableCell::new(&self.category),
TableCell::new(&self.user), TableCell::new(&self.user),
TableCell::new(Local.timestamp(self.timestamp, 0).format("%F %R")),
]) ])
} }
} }

View file

@ -1,4 +1,3 @@
use term_table::{Table, TableBuilder, TableStyle};
use tokio::process::Command; use tokio::process::Command;
pub async fn open_link(url: &str) -> anyhow::Result<()> { pub async fn open_link(url: &str) -> anyhow::Result<()> {
@ -11,17 +10,3 @@ pub async fn open_link(url: &str) -> anyhow::Result<()> {
Ok(()) Ok(())
} }
/// returns an empty table with the correct format settings for lists
pub fn list_table<'a>() -> Table<'a> {
TableBuilder::new()
.style(TableStyle::simple())
.separate_rows(false)
.has_top_boarder(false)
.has_bottom_boarder(false)
.build()
}
pub trait IntoTableRow {
fn into_table_row(&self) -> term_table::row::Row;
}

View file

@ -1,5 +1,5 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use serde::Deserialize; use serde::{Deserialize, Deserializer, de::{self, Visitor}};
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)] #[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct UpResp { pub struct UpResp {
@ -34,6 +34,8 @@ pub struct Meme {
pub path: String, pub path: String,
pub category: String, pub category: String,
pub user: String, pub user: String,
#[serde(deserialize_with = "deserialize_timestamp")]
pub timestamp: i64,
} }
impl Meme { impl Meme {
@ -62,3 +64,37 @@ impl User {
.or(self.userdir.as_ref()) .or(self.userdir.as_ref())
} }
} }
fn deserialize_timestamp<'de, D>(deserializer: D) -> Result<i64, D::Error>
where
D: Deserializer<'de>,
{
struct Vis;
impl<'de> Visitor<'de> for Vis {
type Value = i64;
fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
fmt.write_str(
"A timestamp in the form of a string or i64 (because tilera doesn't know integers \
exist)",
)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(v)
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: de::Error,
{
v.parse().map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &self))
}
}
deserializer.deserialize_any(Vis)
}

View file

@ -152,6 +152,7 @@ pub enum MemeSorting {
Link, Link,
Category, Category,
User, User,
Timestamp,
} }
impl MemeSorting { impl MemeSorting {
@ -171,6 +172,7 @@ impl MemeSorting {
Self::Link => sort!(memes, link), Self::Link => sort!(memes, link),
Self::Category => sort!(memes, category), Self::Category => sort!(memes, category),
Self::User => sort!(memes, user), Self::User => sort!(memes, user),
Self::Timestamp => memes.sort_by(|a, b| b.timestamp.cmp(&a.timestamp)),
} }
} }
} }
@ -184,6 +186,7 @@ impl FromStr for MemeSorting {
"link" => Ok(Self::Link), "link" => Ok(Self::Link),
"category" => Ok(Self::Category), "category" => Ok(Self::Category),
"user" => Ok(Self::User), "user" => Ok(Self::User),
"timestamp" => Ok(Self::Timestamp),
_ => bail!("Invalid Meme sorting! options are id, link, category and user!"), _ => bail!("Invalid Meme sorting! options are id, link, category and user!"),
} }
} }