diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml index 035c91d..697ea64 100644 --- a/.github/workflows/fmt.yml +++ b/.github/workflows/fmt.yml @@ -4,7 +4,6 @@ on: push: branches: - main - paths-ignore: - '*.md' @@ -16,9 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - name: Checkout + uses: actions/checkout@v2 - - name: Setup GIT + - name: Setup Git run: | git config --global user.name "MedzikUserBot" git config --global user.email "rm99iv9s@duck.com" @@ -43,7 +43,7 @@ jobs: git diff-index --quiet HEAD || git commit -m "rustfmt" - name: Push changes - uses: ad-m/github-push-action@a3fd843e49cd58d296bdd2431c4853569a1b900f + uses: ad-m/github-push-action@b007e7b818e33b04afd056e4c4b57ba917145d7a with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: 'main' diff --git a/Cargo.lock b/Cargo.lock index e58d843..c631c99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,7 +44,7 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d76e1fe0171b6d0857afca5671db12a44e71e80823db13ab39f776fb09ad079" dependencies = [ - "clipboard-win", + "clipboard-win 4.4.1", "core-graphics", "image", "log", @@ -328,6 +328,40 @@ dependencies = [ "syn", ] +[[package]] +name = "clipboard" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7" +dependencies = [ + "clipboard-win 2.2.0", + "objc", + "objc-foundation", + "objc_id", + "x11-clipboard", +] + +[[package]] +name = "clipboard-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac0b9a9fdf4e6100bfcdc6587c9c26a6a1d1d8247e74684c18a113d635d3dc78" +dependencies = [ + "clipboard", + "libc", + "which", + "x11-clipboard", +] + +[[package]] +name = "clipboard-win" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b" +dependencies = [ + "winapi", +] + [[package]] name = "clipboard-win" version = "4.4.1" @@ -386,9 +420,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -427,9 +461,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", ] @@ -554,6 +588,15 @@ version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", +] + [[package]] name = "fastrand" version = "1.7.0" @@ -858,6 +901,8 @@ dependencies = [ "chrono", "clap", "clap_complete", + "clipboard-ext", + "colored", "dirs 4.0.0", "log", "notify-rust", @@ -2084,6 +2129,16 @@ dependencies = [ "cc", ] +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "failure", + "libc", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2180,6 +2235,15 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "x11-clipboard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea" +dependencies = [ + "xcb", +] + [[package]] name = "x11rb" version = "0.8.1" @@ -2192,6 +2256,16 @@ dependencies = [ "winapi-wsapoll", ] +[[package]] +name = "xcb" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de" +dependencies = [ + "libc", + "log", +] + [[package]] name = "xml-rs" version = "0.8.4" diff --git a/Cargo.toml b/Cargo.toml index 4772c7e..9736597 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,12 @@ clap_complete = "3.1.0" anyhow = "1.0.55" better-panic = "0.3.0" validator = "0.14.0" +colored = "2.0.0" + +[target.'cfg(all(unix, not(any(target_os="macos", target_os="android", target_os="emscripten"))))'.dependencies] +clipboard-ext = "0.2.0" + +[target.'cfg(not(all(unix, not(any(target_os="macos", target_os="android", target_os="emscripten")))))'.dependencies] arboard = "2.0.1" [dependencies.clap] diff --git a/config.toml b/config.toml index cf97ee9..0afb591 100644 --- a/config.toml +++ b/config.toml @@ -3,3 +3,6 @@ id = '3e3ce0d7ac14d56' [notification] enabled = true + +[clipboard] +enabled = true diff --git a/src/api/image_type.rs b/src/api/image_type.rs index 15c3ebc..e3ea0f3 100644 --- a/src/api/image_type.rs +++ b/src/api/image_type.rs @@ -1,13 +1,13 @@ use serde_derive::{Deserialize, Serialize}; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct ImageInfo { pub data: ImageInfoData, pub success: bool, pub status: i32, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct ImageInfoData { pub id: String, pub title: Option, diff --git a/src/cli/clipboard.rs b/src/cli/clipboard.rs new file mode 100644 index 0000000..f756edc --- /dev/null +++ b/src/cli/clipboard.rs @@ -0,0 +1,34 @@ +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "android", target_os = "emscripten")) +))] +use clipboard_ext::prelude::*; +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "android", target_os = "emscripten")) +))] +use clipboard_ext::x11_fork::ClipboardContext; + +#[cfg(all( + unix, + not(any(target_os = "macos", target_os = "android", target_os = "emscripten")) +))] +pub fn set_clipboard(content: String) { + let mut ctx = ClipboardContext::new().expect("init clipboard"); + ctx.set_contents(content).expect("set clipboard"); +} + +#[cfg(not(all( + unix, + not(any(target_os = "macos", target_os = "android", target_os = "emscripten")) +)))] +use arboard::Clipboard; + +#[cfg(not(all( + unix, + not(any(target_os = "macos", target_os = "android", target_os = "emscripten")) +)))] +pub fn set_clipboard(content: String) { + let mut clipboard = Clipboard::new().unwrap(); + clipboard.set_text(content).unwrap(); +} diff --git a/src/cli/info_image.rs b/src/cli/info_image.rs index f2aaa16..94b7c3c 100644 --- a/src/cli/info_image.rs +++ b/src/cli/info_image.rs @@ -4,5 +4,5 @@ use super::print_image_info; pub async fn image_info(client: ImgurClient, id: &str) { let i = get_image(client, id).await.expect("send api request"); - print_image_info(i, false); + print_image_info(i); } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a8700e8..9fbca1d 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,62 +1,77 @@ +pub mod clipboard; pub mod credits; pub mod delete_image; pub mod info_image; pub mod parse; pub mod upload_image; -use crate::config::toml::parse; use imgurs::api::ImageInfo; -use arboard::Clipboard; use chrono::{prelude::DateTime, Utc}; -use log::info; -use notify_rust::Notification; +use colored::Colorize; use std::time::{Duration, UNIX_EPOCH}; -pub fn print_image_info(i: ImageInfo, notify: bool) { +pub fn print_image_info(i: ImageInfo) { let d = UNIX_EPOCH + Duration::from_secs(i.data.datetime.try_into().unwrap()); let datetime = DateTime::::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_else(|| "unknown".to_string()) + println!( + "{} {}", + "title".green(), + i.data + .title + .unwrap_or_else(|| "unknown".to_string()) + .magenta() ); } if i.data.description != None { - info!( - "Description {}", - i.data.description.unwrap_or_else(|| "unknown".to_string()) + println!( + "{} {}", + "description".green(), + i.data + .description + .unwrap_or_else(|| "unknown".to_string()) + .magenta() ); } if i.data.deletehash != None { - info!( - "Deletehash {}", - i.data.deletehash.unwrap_or_else(|| "unknown".to_string()) + println!( + "{} {}", + "deletehash".green(), + i.data + .deletehash + .unwrap_or_else(|| "unknown".to_string()) + .magenta() ); } - 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); - - let config = parse(); - - if notify && config.notification.enabled { - Notification::new() - .summary("Imgurs") - .body(&format!("Uploaded {}", i.data.link)) - .show() - .expect("send notification"); - - let mut clipboard = Clipboard::new().unwrap(); - clipboard.set_text(i.data.link.into()).unwrap(); - } + println!("{} {}", "id".green(), i.data.id.magenta()); + println!( + "{} {} {}", + "upload date".green(), + timestamp_str.magenta(), + "(UTC)".blue() + ); + println!("{} {}", "type".green(), i.data.img_type.magenta()); + println!("{} {}", "width".green(), i.data.width.to_string().magenta()); + println!( + "{} {}", + "height".green(), + i.data.height.to_string().magenta() + ); + println!( + "{} {} {}", + "size".green(), + (i.data.size / 1000).to_string().magenta(), + "KB".blue() + ); + println!("{} {}", "views".green(), i.data.views.to_string().magenta()); + println!( + "{} {}", + "bandwidth".green(), + i.data.bandwidth.to_string().magenta() + ); + println!("{} {}", "link".green(), i.data.link.magenta()); } diff --git a/src/cli/parse.rs b/src/cli/parse.rs index 5ee7b64..797f734 100644 --- a/src/cli/parse.rs +++ b/src/cli/parse.rs @@ -1,6 +1,6 @@ use imgurs::api::ImgurClient; -use clap::{App, AppSettings, IntoApp, Parser, Subcommand}; +use clap::{Command, IntoApp, Parser, Subcommand}; use clap_complete::{generate, Generator, Shell}; use log::error; use std::io::stdout; @@ -26,29 +26,20 @@ enum Commands { #[clap(about = "Print API Rate Limit")] Credits, - #[clap( - setting(AppSettings::ArgRequiredElseHelp), - about = "Upload image to Imgur" - )] + #[clap(about = "Upload image to Imgur")] Upload { path: String }, - #[clap( - setting(AppSettings::ArgRequiredElseHelp), - about = "Delete image from Imgur" - )] + #[clap(about = "Delete image from Imgur")] Delete { delete_hash: String }, - #[clap(setting(AppSettings::ArgRequiredElseHelp), about = "Print image info")] + #[clap(about = "Print image info")] Info { id: String }, - #[clap( - setting(AppSettings::ArgRequiredElseHelp), - about = "Print shell completions (bash, zsh, fish, powershell)" - )] + #[clap(about = "Print shell completions (bash, zsh, fish, powershell)")] Completions { shell: String }, } -fn print_completions(gen: G, app: &mut App) { +fn print_completions(gen: G, app: &mut Command) { generate(gen, app, app.get_name().to_string(), &mut stdout()) } @@ -73,7 +64,7 @@ pub async fn parse(client: ImgurClient) { } Commands::Completions { shell } => { - let mut app = Cli::into_app(); + let mut app = Cli::command(); match shell.as_str() { "bash" => print_completions(Shell::Bash, &mut app), diff --git a/src/cli/upload_image.rs b/src/cli/upload_image.rs index 3751ee2..3a168c1 100644 --- a/src/cli/upload_image.rs +++ b/src/cli/upload_image.rs @@ -1,10 +1,22 @@ +use super::clipboard::set_clipboard; use imgurs::api::{upload_image::upload_image as upload_img, ImgurClient}; +use notify_rust::Notification; + +use crate::config::toml::parse as parse_config; use super::print_image_info; use base64::encode as base64_encode; use std::{fs::read as fs_read, path::Path}; +macro_rules! notify ( + ($notification: expr) => ( + if parse_config().notification.enabled { + $notification.show().expect("send notification"); + } + ); +); + pub async fn upload_image(client: ImgurClient, path: &str) { let mut image: String = path.to_string(); @@ -18,5 +30,13 @@ pub async fn upload_image(client: ImgurClient, path: &str) { } let i = upload_img(client, &image).await.expect("send api request"); - print_image_info(i, true); + print_image_info(i.clone()); + + let body = format!("Uploaded {}", i.data.link); + + notify!(Notification::new().summary("Imgurs").body(&body)); + + if parse_config().clipboard.enabled { + set_clipboard(i.data.link) + } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 544585c..beb5a61 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -6,6 +6,7 @@ pub mod toml; pub struct Config { pub imgur: ConfigImgur, pub notification: ConfigNotification, + pub clipboard: ConfigClipboard, } #[derive(Debug, Deserialize)] @@ -17,3 +18,8 @@ pub struct ConfigImgur { pub struct ConfigNotification { pub enabled: bool, } + +#[derive(Debug, Deserialize)] +pub struct ConfigClipboard { + pub enabled: bool, +}