forked from C4TG1RL5_UN1T3D/dimgup-cli
118 lines
3 KiB
Rust
118 lines
3 KiB
Rust
#![allow(unused_macros)]
|
|
|
|
use anyhow::bail;
|
|
use clap::Parser;
|
|
use clipboard_ext::prelude::*;
|
|
use clipboard_ext::x11_bin::ClipboardContext;
|
|
use directories::ProjectDirs;
|
|
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::io::{Read, Seek, SeekFrom};
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
|
|
mod discord;
|
|
const MAXBUF: u64 = 8_380_416;
|
|
|
|
#[derive(Parser)]
|
|
#[clap(author, version, about, long_about = None)]
|
|
struct Args {
|
|
/// The file to upload to the API
|
|
#[arg(required = true)]
|
|
filename: PathBuf,
|
|
/// Sets the webhook to use and stores it for later uses.
|
|
#[arg(short, long)]
|
|
set_webhook: Option<String>,
|
|
|
|
#[arg(short, long)]
|
|
copy: bool,
|
|
}
|
|
|
|
macro_rules! loop_try {
|
|
($e:expr) => {
|
|
match $e {
|
|
Ok(v) => v,
|
|
Err(_) => continue,
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! try_or_return {
|
|
($e:expr) => {
|
|
match $e {
|
|
Ok(v) => v,
|
|
Err(_) => return,
|
|
}
|
|
};
|
|
}
|
|
|
|
fn get_config_file() -> PathBuf {
|
|
let proj_dirs = ProjectDirs::from("xyz", "karx", "dimgup-cli").unwrap();
|
|
let mut b = proj_dirs.config_dir().to_path_buf();
|
|
b.push("webhook");
|
|
b
|
|
}
|
|
|
|
fn get_webhook() -> anyhow::Result<String> {
|
|
let path = get_config_file();
|
|
Ok(std::fs::read_to_string(path)?)
|
|
}
|
|
|
|
fn set_webhook(webhook: &str) -> anyhow::Result<()> {
|
|
let path = get_config_file();
|
|
let parent = path.parent().unwrap();
|
|
std::fs::create_dir_all(&parent)?;
|
|
let mut file = File::create(&path)?;
|
|
file.write_all(webhook.as_bytes())?;
|
|
Ok(())
|
|
}
|
|
|
|
fn get_file_info(path: &Path) -> anyhow::Result<(File, u64, String)> {
|
|
let filename = path.file_name().unwrap().to_str().unwrap();
|
|
let mut handle = File::open(path)?;
|
|
let filesize = handle.seek(SeekFrom::End(0))?;
|
|
handle.seek(SeekFrom::Start(0))?;
|
|
if filesize > MAXBUF {
|
|
bail!("File is too big.")
|
|
} else {
|
|
Ok((handle, filesize, filename.to_string()))
|
|
}
|
|
}
|
|
|
|
fn do_upload(mut file: File, size: u64, name: &str, webhook: &str) -> anyhow::Result<String> {
|
|
let mut buffer = vec![0u8; size as usize];
|
|
file.read_exact(&mut *buffer)?;
|
|
let progress_update = |bytes: f64| {
|
|
let chars = ['\\', '|', '/', '-'];
|
|
print!("{} \r", chars[((bytes * 100.0) as usize) % chars.len()]);
|
|
try_or_return!(std::io::stdout().flush());
|
|
};
|
|
discord::upload(name, &buffer, webhook, progress_update)
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let args = Args::parse();
|
|
let filename = args.filename;
|
|
if let Some(ref webhook) = args.set_webhook {
|
|
set_webhook(&webhook)?;
|
|
println!("Webhook set successfully");
|
|
}
|
|
|
|
let webhook = match get_webhook() {
|
|
Ok(w) => w,
|
|
Err(_) => bail!("Please set your webhook. See `dimgup-cli --help` for more info."),
|
|
};
|
|
|
|
let (handle, size, name) = get_file_info(&filename)?;
|
|
|
|
let url = do_upload(handle, size, &name, &webhook)?;
|
|
|
|
println!("{}", url);
|
|
if args.copy {
|
|
let mut ctx = ClipboardContext::new().unwrap();
|
|
ctx.set_contents(url).unwrap();
|
|
println!("Copied!");
|
|
}
|
|
Ok(())
|
|
}
|