mirror of https://github.com/MedzikUser/imgurs
refactor code
This commit is contained in:
parent
6da2dc252f
commit
831f816447
|
@ -864,6 +864,7 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"simple_logger",
|
"simple_logger",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
"validator",
|
"validator",
|
||||||
|
@ -1852,9 +1853,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "1.7.0"
|
version = "1.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
|
checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
28
Cargo.toml
28
Cargo.toml
|
@ -34,28 +34,12 @@ validator = "0.15.0"
|
||||||
colored = "2.0.0"
|
colored = "2.0.0"
|
||||||
clap_mangen = "0.1.6"
|
clap_mangen = "0.1.6"
|
||||||
discord-webhook = "0.1.0"
|
discord-webhook = "0.1.0"
|
||||||
|
thiserror = "1.0.31"
|
||||||
|
clap = { version = "3.1.18", features = ["derive"] }
|
||||||
|
log = { version = "0.4.17", features = ["release_max_level_info", "max_level_debug"] }
|
||||||
|
simple_logger = { version = "2.1.0", default-features = false, features = ["colors"] }
|
||||||
|
reqwest = { version = "0.11.10", default-features = false, features = ["json", "rustls-tls"] }
|
||||||
|
tokio = { version = "1.19.2", features = ["macros", "rt-multi-thread"] }
|
||||||
|
|
||||||
[target.'cfg(not(all(unix, not(any(target_os="macos", target_os="android", target_os="emscripten")))))'.dependencies]
|
[target.'cfg(not(all(unix, not(any(target_os="macos", target_os="android", target_os="emscripten")))))'.dependencies]
|
||||||
arboard = "2.1.1"
|
arboard = "2.1.1"
|
||||||
|
|
||||||
[dependencies.clap]
|
|
||||||
version = "3.1.18"
|
|
||||||
features = ["derive", "cargo", "std"]
|
|
||||||
|
|
||||||
[dependencies.log]
|
|
||||||
version = "0.4.17"
|
|
||||||
features = ["release_max_level_info", "max_level_debug"]
|
|
||||||
|
|
||||||
[dependencies.simple_logger]
|
|
||||||
version = "2.1.0"
|
|
||||||
default-features = false
|
|
||||||
features = ["colors"]
|
|
||||||
|
|
||||||
[dependencies.reqwest]
|
|
||||||
version = "0.11.10"
|
|
||||||
default-features = false
|
|
||||||
features = ["json", "rustls-tls"]
|
|
||||||
|
|
||||||
[dependencies.tokio]
|
|
||||||
version = "1.19.2"
|
|
||||||
features = ["macros", "rt-multi-thread"]
|
|
||||||
|
|
16
README.md
16
README.md
|
@ -1,8 +1,18 @@
|
||||||
|
[github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
|
||||||
|
[total-lines]: https://img.shields.io/tokei/lines/github/MedzikUser/HomeDisk?style=for-the-badge&logo=github&color=fede00
|
||||||
|
[code-size]: https://img.shields.io/github/languages/code-size/MedzikUser/HomeDisk?style=for-the-badge&color=c8df52&logo=github
|
||||||
|
[crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
|
||||||
|
[docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
|
||||||
|
[ci]: https://img.shields.io/github/workflow/status/MedzikUser/rust-crypto-utils/Rust/main?style=for-the-badge&logo=github
|
||||||
|
|
||||||
# Imgurs - CLI and Library for Imgur API
|
# Imgurs - CLI and Library for Imgur API
|
||||||
|
|
||||||
![](https://img.shields.io/github/license/MedzikUser/imgurs)
|
[![github]](https://github.com/MedzikUser/imgurs)
|
||||||
![](https://img.shields.io/tokei/lines/github/MedzikUser/imgurs)
|
[![total-lines]](https://github.com/MedzikUser/HomeDisk)
|
||||||
![](https://img.shields.io/github/languages/code-size/MedzikUser/imgurs)
|
[![code-size]](https://github.com/MedzikUser/HomeDisk)
|
||||||
|
[![crates-io]](https://crates.io/crates/imgurs)
|
||||||
|
[![docs-rs]](https://docs.rs/imgurs)
|
||||||
|
[![ci]](https://github.com/MedzikUser/imgurs/actions/workflows/rust.yml)
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,20 @@ macro_rules! api_url (
|
||||||
);
|
);
|
||||||
);
|
);
|
||||||
|
|
||||||
use std::{fmt, fs, io, path::Path};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
pub(crate) use api_url;
|
pub(crate) use api_url;
|
||||||
|
|
||||||
|
use std::{fmt, fs, path::Path};
|
||||||
|
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
|
||||||
use super::*;
|
use crate::{Result, Error, requests::{self, RateLimitInfo}, ImageInfo};
|
||||||
|
|
||||||
|
/// Imgur Client
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ImgurClient {
|
pub struct ImgurClient {
|
||||||
|
/// Client id for a Imgur API
|
||||||
pub client_id: String,
|
pub client_id: String,
|
||||||
|
/// HTTP Client
|
||||||
pub client: Client,
|
pub client: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +28,7 @@ impl fmt::Debug for ImgurClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImgurClient {
|
impl ImgurClient {
|
||||||
/// Create new Imgur Client
|
/// Create a new Imgur Client
|
||||||
/// ```
|
/// ```
|
||||||
/// use imgurs::ImgurClient;
|
/// use imgurs::ImgurClient;
|
||||||
///
|
///
|
||||||
|
@ -51,21 +55,16 @@ impl ImgurClient {
|
||||||
let mut image = path.to_string();
|
let mut image = path.to_string();
|
||||||
|
|
||||||
// check if the specified file exists if not then check if it is a url
|
// check if the specified file exists if not then check if it is a url
|
||||||
if Path::new(&path).exists() {
|
if Path::new(path).exists() {
|
||||||
let bytes = fs::read(&path)?;
|
let bytes = fs::read(path)?;
|
||||||
image = base64::encode(bytes)
|
image = base64::encode(bytes)
|
||||||
}
|
}
|
||||||
// validate adress url
|
// validate url adress
|
||||||
else if !validator::validate_url(&*path) {
|
else if !validator::validate_url(path) {
|
||||||
let err = io::Error::new(
|
Err(Error::InvalidUrlOrFile(path.to_string()))?;
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("{path} is not url or file path"),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(err.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
upload_image(self, image).await
|
requests::upload_image(self, image).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete image from Imgur
|
/// Delete image from Imgur
|
||||||
|
@ -83,10 +82,10 @@ impl ImgurClient {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn delete_image(&self, delete_hash: &str) -> Result<()> {
|
pub async fn delete_image(&self, delete_hash: &str) -> Result<()> {
|
||||||
delete_image(self, delete_hash).await
|
requests::delete_image(self, delete_hash).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Client Rate Limit
|
/// Get Rame Limit of this Imgur Client
|
||||||
/// ```
|
/// ```
|
||||||
/// use imgurs::ImgurClient;
|
/// use imgurs::ImgurClient;
|
||||||
///
|
///
|
||||||
|
@ -98,10 +97,10 @@ impl ImgurClient {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn rate_limit(&self) -> Result<RateLimitInfo> {
|
pub async fn rate_limit(&self) -> Result<RateLimitInfo> {
|
||||||
rate_limit(self).await
|
requests::rate_limit(self).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get Imgur image info
|
/// Get image info from a Imgur
|
||||||
/// ```
|
/// ```
|
||||||
/// use imgurs::ImgurClient;
|
/// use imgurs::ImgurClient;
|
||||||
///
|
///
|
||||||
|
@ -113,6 +112,6 @@ impl ImgurClient {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn image_info(&self, id: &str) -> Result<ImageInfo> {
|
pub async fn image_info(&self, id: &str) -> Result<ImageInfo> {
|
||||||
get_image(self, id).await
|
requests::get_image(self, id).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Client Errors
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Imgur API returned non-successful status code
|
||||||
|
#[error("server reponse non-successful status code - {0}, body = `{1}`")]
|
||||||
|
ApiError(u16, String),
|
||||||
|
/// Imgur API returned non-successful status code (body is too long)
|
||||||
|
#[error("server reponse non-successful status code - {0}, (response body is too long)")]
|
||||||
|
ApiErrorBodyTooLong(u16),
|
||||||
|
/// Invalid file path or URL adress
|
||||||
|
#[error("{0} is not url or file path")]
|
||||||
|
InvalidUrlOrFile(String),
|
||||||
|
/// Reqwest error
|
||||||
|
#[error("reqwest error - {0}")]
|
||||||
|
ReqwestError(reqwest::Error),
|
||||||
|
/// Io Error
|
||||||
|
#[error("io error - {0}")]
|
||||||
|
IoError(std::io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// reqwest::Error
|
||||||
|
impl From<reqwest::Error> for Error {
|
||||||
|
fn from(err: reqwest::Error) -> Self {
|
||||||
|
Error::ReqwestError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// reqwest::Error
|
||||||
|
impl From<std::io::Error> for Error {
|
||||||
|
fn from(err: std::io::Error) -> Self {
|
||||||
|
Error::IoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `Result` alias where the `Err` case is `imgurs::Error`.
|
||||||
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
@ -1,29 +0,0 @@
|
||||||
use std::io;
|
|
||||||
|
|
||||||
use reqwest::Method;
|
|
||||||
|
|
||||||
use super::{client::api_url, send_api_request, ImageInfo, ImgurClient};
|
|
||||||
|
|
||||||
pub async fn get_image(client: &ImgurClient, image: &str) -> anyhow::Result<ImageInfo> {
|
|
||||||
// get imgur api url
|
|
||||||
let uri = api_url!(format!("image/{image}"));
|
|
||||||
|
|
||||||
// send request to imgur api
|
|
||||||
let res = send_api_request(client, Method::GET, uri, None).await?;
|
|
||||||
|
|
||||||
// get response http code
|
|
||||||
let status = res.status();
|
|
||||||
|
|
||||||
// check if an error has occurred
|
|
||||||
if status.is_client_error() || status.is_server_error() {
|
|
||||||
let err = io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("server returned non-successful status code = {status}"),
|
|
||||||
);
|
|
||||||
|
|
||||||
Err(err.into())
|
|
||||||
} else {
|
|
||||||
let content: ImageInfo = res.json().await?;
|
|
||||||
Ok(content)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Image Info Response
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct ImageInfo {
|
pub struct ImageInfo {
|
||||||
pub data: ImageInfoData,
|
pub data: ImageInfoData,
|
||||||
|
@ -7,6 +8,7 @@ pub struct ImageInfo {
|
||||||
pub status: i32,
|
pub status: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Image Info Reponse (`data` json)
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct ImageInfoData {
|
pub struct ImageInfoData {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|
|
@ -1,52 +1,12 @@
|
||||||
mod delete_image;
|
pub mod requests;
|
||||||
mod get_image;
|
|
||||||
mod image_type;
|
|
||||||
mod rate_limit;
|
|
||||||
mod upload_image;
|
|
||||||
|
|
||||||
pub mod client;
|
mod client;
|
||||||
|
mod error;
|
||||||
|
mod image_type;
|
||||||
|
mod send_api_request;
|
||||||
|
|
||||||
pub use client::ImgurClient;
|
pub use client::ImgurClient;
|
||||||
pub use delete_image::*;
|
pub use error::*;
|
||||||
pub use get_image::*;
|
|
||||||
pub use image_type::*;
|
pub use image_type::*;
|
||||||
pub use rate_limit::*;
|
pub use send_api_request::*;
|
||||||
pub use upload_image::*;
|
pub(crate) use client::api_url;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use reqwest::{Method, Response};
|
|
||||||
|
|
||||||
// send request to imgur api
|
|
||||||
pub async fn send_api_request(
|
|
||||||
config: &ImgurClient,
|
|
||||||
method: Method,
|
|
||||||
uri: String,
|
|
||||||
form: Option<HashMap<&str, String>>,
|
|
||||||
) -> anyhow::Result<Response> {
|
|
||||||
// get request client
|
|
||||||
let client = &config.client;
|
|
||||||
|
|
||||||
// create request buidler
|
|
||||||
let mut req = client.request(method, uri.as_str());
|
|
||||||
|
|
||||||
// get program version
|
|
||||||
let version: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
|
||||||
let version = version.unwrap_or("unknown");
|
|
||||||
|
|
||||||
// add `Authorization` and `User-Agent` to request
|
|
||||||
req = req
|
|
||||||
.header("Authorization", format!("Client-ID {}", config.client_id))
|
|
||||||
.header("User-Agent", format!("Imgur/{:?}", version));
|
|
||||||
|
|
||||||
// if exists add hashmap to request
|
|
||||||
if form != None {
|
|
||||||
req = req.form(&form.unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
// build request
|
|
||||||
let req = req.build()?;
|
|
||||||
|
|
||||||
// send request
|
|
||||||
Ok(client.execute(req).await?)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use std::io;
|
|
||||||
|
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
|
|
||||||
use super::{client::api_url, send_api_request, ImgurClient};
|
use crate::{Error, Result, api_url, send_api_request, ImgurClient};
|
||||||
|
|
||||||
pub async fn delete_image(client: &ImgurClient, delete_hash: &str) -> anyhow::Result<()> {
|
pub async fn delete_image(client: &ImgurClient, delete_hash: &str) -> Result<()> {
|
||||||
// get imgur api url
|
// get imgur api url
|
||||||
let uri = api_url!(format!("image/{delete_hash}"));
|
let uri = api_url!(format!("image/{delete_hash}"));
|
||||||
|
|
||||||
|
@ -16,18 +14,9 @@ pub async fn delete_image(client: &ImgurClient, delete_hash: &str) -> anyhow::Re
|
||||||
|
|
||||||
// check if an error has occurred
|
// check if an error has occurred
|
||||||
if status.is_client_error() || status.is_server_error() {
|
if status.is_client_error() || status.is_server_error() {
|
||||||
let mut body = res.text().await?;
|
let body = res.text().await?;
|
||||||
|
|
||||||
if body.chars().count() > 30 {
|
Err(Error::ApiError(status.as_u16(), body))?;
|
||||||
body = "body is too length".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
let err = io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("server returned non-successful status code = {status}, body = {body}"),
|
|
||||||
);
|
|
||||||
|
|
||||||
return Err(err.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
|
@ -0,0 +1,24 @@
|
||||||
|
use reqwest::Method;
|
||||||
|
|
||||||
|
use crate::{Error, Result, api_url, send_api_request, ImgurClient, ImageInfo};
|
||||||
|
|
||||||
|
pub async fn get_image(client: &ImgurClient, image: &str) -> Result<ImageInfo> {
|
||||||
|
// get imgur api url
|
||||||
|
let uri = api_url!(format!("image/{image}"));
|
||||||
|
|
||||||
|
// send request to imgur api
|
||||||
|
let res = send_api_request(client, Method::GET, uri, None).await?;
|
||||||
|
|
||||||
|
// get response http code
|
||||||
|
let status = res.status();
|
||||||
|
|
||||||
|
// check if an error has occurred
|
||||||
|
if status.is_client_error() || status.is_server_error() {
|
||||||
|
let body = res.text().await?;
|
||||||
|
|
||||||
|
return Err(Error::ApiError(status.as_u16(), body));
|
||||||
|
}
|
||||||
|
|
||||||
|
// return `ImageInfo`
|
||||||
|
Ok(res.json().await?)
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
mod delete_image;
|
||||||
|
mod get_image;
|
||||||
|
mod rate_limit;
|
||||||
|
mod upload_image;
|
||||||
|
|
||||||
|
pub use delete_image::*;
|
||||||
|
pub use get_image::*;
|
||||||
|
pub use rate_limit::*;
|
||||||
|
pub use upload_image::*;
|
|
@ -1,9 +1,7 @@
|
||||||
use std::io;
|
|
||||||
|
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{client::api_url, send_api_request, ImgurClient};
|
use crate::{Error, Result, api_url, send_api_request, ImgurClient};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct RateLimitInfo {
|
pub struct RateLimitInfo {
|
||||||
|
@ -26,7 +24,7 @@ pub struct RateLimitData {
|
||||||
pub client_remaining: i32,
|
pub client_remaining: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn rate_limit(client: &ImgurClient) -> anyhow::Result<RateLimitInfo> {
|
pub async fn rate_limit(client: &ImgurClient) -> Result<RateLimitInfo> {
|
||||||
// get imgur api url
|
// get imgur api url
|
||||||
let uri = api_url!("credits");
|
let uri = api_url!("credits");
|
||||||
|
|
||||||
|
@ -40,14 +38,9 @@ pub async fn rate_limit(client: &ImgurClient) -> anyhow::Result<RateLimitInfo> {
|
||||||
if status.is_client_error() || status.is_server_error() {
|
if status.is_client_error() || status.is_server_error() {
|
||||||
let body = res.text().await?;
|
let body = res.text().await?;
|
||||||
|
|
||||||
let err = io::Error::new(
|
return Err(Error::ApiError(status.as_u16(), body));
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("server returned non-successful status code = {status}, body = {body}"),
|
|
||||||
);
|
|
||||||
|
|
||||||
Err(err.into())
|
|
||||||
} else {
|
|
||||||
let content = res.json::<RateLimitInfo>().await?;
|
|
||||||
Ok(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return `RateLimitInfo`
|
||||||
|
Ok(res.json().await?)
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
use std::{collections::HashMap, io};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
|
|
||||||
use super::{client::api_url, send_api_request, ImageInfo, ImgurClient};
|
use crate::{Error, Result, api_url, send_api_request, ImgurClient, ImageInfo};
|
||||||
|
|
||||||
pub async fn upload_image(client: &ImgurClient, image: String) -> anyhow::Result<ImageInfo> {
|
pub async fn upload_image(client: &ImgurClient, image: String) -> Result<ImageInfo> {
|
||||||
// create http form (hashmap)
|
// create http form (hashmap)
|
||||||
let mut form = HashMap::new();
|
let mut form = HashMap::new();
|
||||||
// insert image to form
|
// insert image to form
|
||||||
|
@ -21,20 +21,16 @@ pub async fn upload_image(client: &ImgurClient, image: String) -> anyhow::Result
|
||||||
|
|
||||||
// check if an error has occurred
|
// check if an error has occurred
|
||||||
if status.is_client_error() || status.is_server_error() {
|
if status.is_client_error() || status.is_server_error() {
|
||||||
let mut body = res.text().await?;
|
let body = res.text().await?;
|
||||||
|
|
||||||
if body.chars().count() > 200 {
|
// if body is too long do not return it (imgur sometimes returns whole Request)
|
||||||
body = "server returned too long".to_string()
|
if body.chars().count() > 50 {
|
||||||
|
Err(Error::ApiErrorBodyTooLong(status.as_u16()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let err = io::Error::new(
|
return Err(Error::ApiError(status.as_u16(), body));
|
||||||
io::ErrorKind::Other,
|
|
||||||
format!("server returned non-successful status code = {status}, body = {body}"),
|
|
||||||
);
|
|
||||||
|
|
||||||
Err(err.into())
|
|
||||||
} else {
|
|
||||||
let content: ImageInfo = res.json().await?;
|
|
||||||
Ok(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return `ImageInfo`
|
||||||
|
Ok(res.json().await?)
|
||||||
}
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use reqwest::{Method, Response};
|
||||||
|
|
||||||
|
use crate::{ImgurClient, Result};
|
||||||
|
|
||||||
|
/// Send request to a Imgur API
|
||||||
|
pub async fn send_api_request(
|
||||||
|
config: &ImgurClient,
|
||||||
|
method: Method,
|
||||||
|
uri: String,
|
||||||
|
form: Option<HashMap<&str, String>>,
|
||||||
|
) -> Result<Response> {
|
||||||
|
// get http client
|
||||||
|
let client = &config.client;
|
||||||
|
|
||||||
|
// create Request buidler
|
||||||
|
let mut req = client.request(method, uri.as_str());
|
||||||
|
|
||||||
|
// get imgurs version
|
||||||
|
let version: &str = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
|
||||||
|
|
||||||
|
// add `Authorization` and `User-Agent` to Request
|
||||||
|
req = req
|
||||||
|
.header("Authorization", format!("Client-ID {}", config.client_id))
|
||||||
|
.header("User-Agent", format!("Imgur/{:?}", version));
|
||||||
|
|
||||||
|
// if exists add HashMap to Request
|
||||||
|
if form != None {
|
||||||
|
req = req.form(&form.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
// build Request
|
||||||
|
let req = req.build()?;
|
||||||
|
|
||||||
|
// send Request
|
||||||
|
Ok(client.execute(req).await?)
|
||||||
|
}
|
|
@ -5,13 +5,12 @@ use std::io::{self, stdout};
|
||||||
|
|
||||||
use crate::cli::{credits::*, delete_image::*, info_image::*, upload_image::*};
|
use crate::cli::{credits::*, delete_image::*, info_image::*, upload_image::*};
|
||||||
|
|
||||||
// get program name and varsion from Cargo.toml
|
// get version from Cargo.toml
|
||||||
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 = NAME.unwrap_or("unknown"),
|
name = "imgurs",
|
||||||
about = "Imgur API CLI", long_about = None,
|
about = "Imgur API CLI", long_about = None,
|
||||||
version = VERSION.unwrap_or("unknown")
|
version = VERSION.unwrap_or("unknown")
|
||||||
)]
|
)]
|
||||||
|
@ -48,6 +47,7 @@ fn print_completions<G: Generator>(gen: G, app: &mut Command) {
|
||||||
generate(gen, app, app.get_name().to_string(), &mut stdout())
|
generate(gen, app, app.get_name().to_string(), &mut stdout())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
pub async fn parse(client: ImgurClient) {
|
pub async fn parse(client: ImgurClient) {
|
||||||
let args = Cli::parse();
|
let args = Cli::parse();
|
||||||
|
|
||||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -1,3 +1,11 @@
|
||||||
|
//! [![github]](https://github.com/MedzikUser/imgurs)
|
||||||
|
//! [![crates-io]](https://crates.io/crates/imgurs)
|
||||||
|
//! [![docs-rs]](https://docs.rs/imgurs)
|
||||||
|
//!
|
||||||
|
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
|
||||||
|
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
|
||||||
|
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
|
||||||
|
//!
|
||||||
//! This crate is an unofficial implementation of the [Imgur API](https://imgur.com) in Rust.
|
//! This crate is an unofficial implementation of the [Imgur API](https://imgur.com) in Rust.
|
||||||
//!
|
//!
|
||||||
//! # Installation
|
//! # Installation
|
||||||
|
@ -17,7 +25,7 @@
|
||||||
//! # Example Usage
|
//! # Example Usage
|
||||||
//!
|
//!
|
||||||
//! ## Create new ImgurClient
|
//! ## Create new ImgurClient
|
||||||
//! ```ignore
|
//! ```
|
||||||
//! use imgurs::ImgurClient;
|
//! use imgurs::ImgurClient;
|
||||||
//!
|
//!
|
||||||
//! let client = ImgurClient::new("client id");
|
//! let client = ImgurClient::new("client id");
|
||||||
|
@ -34,7 +42,7 @@
|
||||||
//!
|
//!
|
||||||
//! ## Delete Image
|
//! ## Delete Image
|
||||||
//! ```ignore
|
//! ```ignore
|
||||||
//! client.delete_image("SuPeRsEcReTDeLeTeHaSh").await?; // delete hash
|
//! client.delete_image("Delete Hash").await?; // delete hash
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ## Get Image Info
|
//! ## Get Image Info
|
||||||
|
|
|
@ -4,8 +4,7 @@ use simple_logger::SimpleLogger;
|
||||||
mod cli;
|
mod cli;
|
||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
#[tokio::main]
|
fn main() {
|
||||||
async fn main() {
|
|
||||||
SimpleLogger::new().init().expect("init SimpleLogger");
|
SimpleLogger::new().init().expect("init SimpleLogger");
|
||||||
better_panic::install();
|
better_panic::install();
|
||||||
|
|
||||||
|
@ -15,5 +14,5 @@ async fn main() {
|
||||||
// create imgur client
|
// create imgur client
|
||||||
let client = ImgurClient::new(&config.imgur.id);
|
let client = ImgurClient::new(&config.imgur.id);
|
||||||
|
|
||||||
cli::parse(client).await
|
cli::parse(client)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue