refactors and add timestamp to meme display
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
1463a3cf0d
commit
3c395a34a7
10 changed files with 70 additions and 30 deletions
|
@ -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"] }
|
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
||||||
|
|
|
@ -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")),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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!"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue