mirror of https://github.com/MedzikUser/imgurs
add image info, update code
This commit is contained in:
parent
8fff3a2b4c
commit
7a4ca71d5a
|
@ -10,7 +10,6 @@ serde_derive = "1.0.134"
|
||||||
toml = "0.5.8"
|
toml = "0.5.8"
|
||||||
serde_json = "1.0.75"
|
serde_json = "1.0.75"
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
#anyhow = "1.0.53"
|
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
use crate::api::configuration::{api_url, ImgurHandle};
|
||||||
|
use crate::api::ImageInfo;
|
||||||
|
|
||||||
|
pub async fn get_image(c: ImgurHandle, image: &str) -> Result<ImageInfo, String> {
|
||||||
|
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
let res = c
|
||||||
|
.client
|
||||||
|
.get(api_url!(format!("image/{image}")))
|
||||||
|
.header("Authorization", format!("Client-ID {}", c.client_id))
|
||||||
|
.header(
|
||||||
|
"User-Agent",
|
||||||
|
format!("Imgurs/{:?}", VERSION.unwrap_or("unknown")),
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|err| err.to_string())?;
|
||||||
|
|
||||||
|
let status = res.status();
|
||||||
|
|
||||||
|
if status.is_client_error() || status.is_server_error() {
|
||||||
|
Err(format!(
|
||||||
|
"server returned non-successful status code = {status}."
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
let content: ImageInfo = res.json().await.map_err(|err| err.to_string())?;
|
||||||
|
Ok(content)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ImageInfo {
|
||||||
|
pub data: ImageInfoData,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ImageInfoData {
|
||||||
|
pub id: String,
|
||||||
|
pub title: Option<String>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub datetime: i32,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub img_type: String,
|
||||||
|
pub animated: bool,
|
||||||
|
pub width: i32,
|
||||||
|
pub height: i32,
|
||||||
|
pub size: i32,
|
||||||
|
pub views: i32,
|
||||||
|
pub bandwidth: i64,
|
||||||
|
pub favorite: bool,
|
||||||
|
pub deletehash: Option<String>,
|
||||||
|
pub link: String,
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
|
mod image_type;
|
||||||
|
|
||||||
pub mod configuration;
|
pub mod configuration;
|
||||||
pub mod delete_image;
|
pub mod delete_image;
|
||||||
|
pub mod get_image;
|
||||||
pub mod rate_limit;
|
pub mod rate_limit;
|
||||||
pub mod upload_image;
|
pub mod upload_image;
|
||||||
|
|
||||||
pub use configuration::ImgurHandle;
|
pub use configuration::ImgurHandle;
|
||||||
|
pub use image_type::*;
|
||||||
|
|
|
@ -5,6 +5,8 @@ use serde_derive::{Deserialize, Serialize};
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct RateLimitInfo {
|
pub struct RateLimitInfo {
|
||||||
pub data: RateLimitData,
|
pub data: RateLimitData,
|
||||||
|
pub success: bool,
|
||||||
|
pub status: i8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
|
@ -1,32 +1,8 @@
|
||||||
use crate::api::configuration::{api_url, ImgurHandle};
|
use crate::api::configuration::{api_url, ImgurHandle};
|
||||||
|
use crate::api::ImageInfo;
|
||||||
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct ImageInfo {
|
|
||||||
pub data: ImageInfoData,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct ImageInfoData {
|
|
||||||
pub id: String,
|
|
||||||
pub title: Option<String>,
|
|
||||||
pub description: Option<String>,
|
|
||||||
pub datetime: i32,
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub img_type: String,
|
|
||||||
pub animated: bool,
|
|
||||||
pub width: i32,
|
|
||||||
pub height: i32,
|
|
||||||
pub size: i32,
|
|
||||||
pub views: i32,
|
|
||||||
pub bandwidth: i64,
|
|
||||||
pub favorite: bool,
|
|
||||||
pub deletehash: String,
|
|
||||||
pub link: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn upload_image(c: ImgurHandle, image: &str) -> Result<ImageInfo, String> {
|
pub async fn upload_image(c: ImgurHandle, image: &str) -> Result<ImageInfo, String> {
|
||||||
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
use imgurs::api::{configuration::ImgurHandle, get_image::get_image};
|
||||||
|
|
||||||
|
use super::print_image_info;
|
||||||
|
|
||||||
|
use base64;
|
||||||
|
use log::error;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub async fn image_info(client: ImgurHandle, path: &str) {
|
||||||
|
let mut image: String = path.to_string();
|
||||||
|
|
||||||
|
if Path::new(path).exists() {
|
||||||
|
let bytes = fs::read(path).map_err(|err| err.to_string()).unwrap();
|
||||||
|
|
||||||
|
image = base64::encode(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
match get_image(client, &image).await {
|
||||||
|
Ok(i) => print_image_info(i),
|
||||||
|
|
||||||
|
Err(e) => {
|
||||||
|
error!("{e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,47 @@
|
||||||
pub mod credits;
|
pub mod credits;
|
||||||
pub mod delete_image;
|
pub mod delete_image;
|
||||||
|
pub mod info_image;
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
pub mod upload_image;
|
pub mod upload_image;
|
||||||
|
|
||||||
|
use chrono::prelude::DateTime;
|
||||||
|
use chrono::Utc;
|
||||||
|
use log::info;
|
||||||
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
|
use imgurs::api::ImageInfo;
|
||||||
|
|
||||||
|
pub fn print_image_info(i: ImageInfo) {
|
||||||
|
let d = UNIX_EPOCH + Duration::from_secs(i.data.datetime.try_into().unwrap());
|
||||||
|
let datetime = DateTime::<Utc>::from(d);
|
||||||
|
let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S").to_string();
|
||||||
|
|
||||||
|
if i.data.title != None {
|
||||||
|
info!(
|
||||||
|
"Title {}",
|
||||||
|
i.data.title.unwrap_or("unknown".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if i.data.description != None {
|
||||||
|
info!(
|
||||||
|
"Description {}",
|
||||||
|
i.data.description.unwrap_or("unknown".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if i.data.deletehash != None {
|
||||||
|
info!(
|
||||||
|
"Deletehash {}",
|
||||||
|
i.data.deletehash.unwrap_or("unknown".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("ID {}", i.data.id);
|
||||||
|
info!("Upload Date {} (UTC)", timestamp_str);
|
||||||
|
info!("Type {}", i.data.img_type);
|
||||||
|
info!("Width {}", i.data.width);
|
||||||
|
info!("Height {}", i.data.height);
|
||||||
|
info!("File Size {} KB", i.data.size / 1000);
|
||||||
|
info!("Views {}", i.data.views);
|
||||||
|
info!("Bandwidth {}", i.data.bandwidth);
|
||||||
|
info!("Link {}", i.data.link);
|
||||||
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@ use clap::{AppSettings, Parser, Subcommand};
|
||||||
|
|
||||||
use imgurs::api::configuration::ImgurHandle;
|
use imgurs::api::configuration::ImgurHandle;
|
||||||
|
|
||||||
use crate::cli::*;
|
use crate::cli::{credits::*, delete_image::*, info_image::*, upload_image::*};
|
||||||
|
|
||||||
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
||||||
|
const NAME: Option<&str> = option_env!("CARGO_PKG_NAME");
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(
|
#[clap(
|
||||||
name = "imgur",
|
name = NAME.unwrap_or("unknown"),
|
||||||
about = "Imgur API CLI", long_about = None,
|
about = "Imgur API CLI", long_about = None,
|
||||||
version = VERSION.unwrap_or("unknown")
|
version = VERSION.unwrap_or("unknown")
|
||||||
)]
|
)]
|
||||||
|
@ -19,7 +20,7 @@ struct Cli {
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
#[clap(about = "Get API Rate Limit")]
|
#[clap(about = "Get API ratelimit")]
|
||||||
Credits,
|
Credits,
|
||||||
|
|
||||||
#[clap(
|
#[clap(
|
||||||
|
@ -30,9 +31,12 @@ enum Commands {
|
||||||
|
|
||||||
#[clap(
|
#[clap(
|
||||||
setting(AppSettings::ArgRequiredElseHelp),
|
setting(AppSettings::ArgRequiredElseHelp),
|
||||||
about = "Upload image to imgur"
|
about = "Delete image from imgur"
|
||||||
)]
|
)]
|
||||||
Delete { delete_hash: String },
|
Delete { delete_hash: String },
|
||||||
|
|
||||||
|
#[clap(setting(AppSettings::ArgRequiredElseHelp), about = "Print image info")]
|
||||||
|
Info { id: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn parse(client: ImgurHandle) {
|
pub async fn parse(client: ImgurHandle) {
|
||||||
|
@ -40,15 +44,19 @@ pub async fn parse(client: ImgurHandle) {
|
||||||
|
|
||||||
match &args.command {
|
match &args.command {
|
||||||
Commands::Credits => {
|
Commands::Credits => {
|
||||||
credits::credits(client).await;
|
credits(client).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Commands::Upload { path } => {
|
Commands::Upload { path } => {
|
||||||
upload_image::upload_image(client, path).await;
|
upload_image(client, path).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Commands::Delete { delete_hash } => {
|
Commands::Delete { delete_hash } => {
|
||||||
delete_image::delete_image(client, delete_hash.to_string()).await;
|
delete_image(client, delete_hash.to_string()).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
Commands::Info { id } => {
|
||||||
|
image_info(client, id).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
|
use super::print_image_info;
|
||||||
use imgurs::api::configuration::ImgurHandle;
|
use imgurs::api::configuration::ImgurHandle;
|
||||||
|
|
||||||
use base64;
|
use base64;
|
||||||
use log::{error, info};
|
use log::error;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use chrono::prelude::DateTime;
|
|
||||||
use chrono::Utc;
|
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
|
||||||
|
|
||||||
pub async fn upload_image(client: ImgurHandle, path: &str) {
|
pub async fn upload_image(client: ImgurHandle, path: &str) {
|
||||||
let mut image: String = path.to_string();
|
let mut image: String = path.to_string();
|
||||||
|
|
||||||
|
@ -19,22 +16,7 @@ pub async fn upload_image(client: ImgurHandle, path: &str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
match imgurs::api::upload_image::upload_image(client, &image).await {
|
match imgurs::api::upload_image::upload_image(client, &image).await {
|
||||||
Ok(i) => {
|
Ok(i) => print_image_info(i),
|
||||||
let d = UNIX_EPOCH + Duration::from_secs(i.data.datetime.try_into().unwrap());
|
|
||||||
let datetime = DateTime::<Utc>::from(d);
|
|
||||||
let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S").to_string();
|
|
||||||
|
|
||||||
info!("ID {}", i.data.id);
|
|
||||||
info!("Upload Date {} (UTC)", timestamp_str);
|
|
||||||
info!("Type {}", i.data.img_type);
|
|
||||||
info!("Width {}", i.data.width);
|
|
||||||
info!("Height {}", i.data.height);
|
|
||||||
info!("File Size {} KB", i.data.size / 1000);
|
|
||||||
info!("Views {}", i.data.views);
|
|
||||||
info!("Bandwidth {}", i.data.bandwidth);
|
|
||||||
info!("Delete Hash {}", i.data.deletehash);
|
|
||||||
info!("Link {}", i.data.link);
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("{e}");
|
error!("{e}");
|
||||||
|
|
|
@ -3,7 +3,9 @@ mod config;
|
||||||
|
|
||||||
use cli::parse::parse;
|
use cli::parse::parse;
|
||||||
|
|
||||||
|
use log::error;
|
||||||
use simple_logger::SimpleLogger;
|
use simple_logger::SimpleLogger;
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
use imgurs::api::ImgurHandle;
|
use imgurs::api::ImgurHandle;
|
||||||
|
|
||||||
|
@ -11,7 +13,10 @@ use imgurs::api::ImgurHandle;
|
||||||
async fn main() {
|
async fn main() {
|
||||||
SimpleLogger::new().init().unwrap();
|
SimpleLogger::new().init().unwrap();
|
||||||
|
|
||||||
let config = config::toml::parse().unwrap();
|
let config = config::toml::parse().unwrap_or_else(|error| {
|
||||||
|
error!("Parse toml config: {}", error);
|
||||||
|
exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
let client = ImgurHandle::new((&config.imgur.id).to_string());
|
let client = ImgurHandle::new((&config.imgur.id).to_string());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue