233 lines
8.4 KiB
Rust
233 lines
8.4 KiB
Rust
#!/usr/bin/env runrs
|
|
|
|
//! ```cargo
|
|
//! [dependencies]
|
|
//! base64 = "0.21.0"
|
|
//! clap = { version = "4.1.8", features = ["derive"] }
|
|
//! reqwest = { version = "0.11.14", features = ["blocking", "json"] }
|
|
//! rust_util = "0.6.41"
|
|
//! serde = { version = "1.0.152", features = ["derive"] }
|
|
//! serde_json = "1.0.93"
|
|
//! ```
|
|
|
|
use std::collections::HashMap;
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
|
|
use base64::Engine;
|
|
use clap::{arg, Parser};
|
|
use rust_util::{debugging, failure_and_exit, information, success};
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(author, version, about, long_about = None, bin_name = "post.rs")]
|
|
struct Args {
|
|
/// Access Token, or from environment: POST_RS_TOKEN
|
|
#[arg(short, long)]
|
|
token: Option<String>,
|
|
|
|
/// FileName
|
|
#[arg(short, long)]
|
|
file_name: Option<String>,
|
|
|
|
/// Content Type
|
|
#[arg(short, long)]
|
|
content_type: Option<String>,
|
|
|
|
/// Description
|
|
#[arg(short, long)]
|
|
description: Option<String>,
|
|
|
|
/// Available after create, default 7d, 10m(10 minutes), 1h(1 hour), 1d(1 day), 1M(1 month), 1y(1 year)
|
|
#[arg(long)]
|
|
available_after_create: Option<String>,
|
|
|
|
/// Available after decrypt, default 10m, 10m(10 minutes), 1h(1 hour), 1d(1 day), 1M(1 month), 1y(1 year)
|
|
#[arg(long)]
|
|
available_after_decrypt: Option<String>,
|
|
|
|
/// Password
|
|
#[arg(short, long)]
|
|
pass: Option<String>,
|
|
|
|
#[arg(required = true)]
|
|
file: PathBuf,
|
|
}
|
|
|
|
fn main() {
|
|
let args: Args = Args::parse();
|
|
let token = args.token.unwrap_or_else(
|
|
|| std::env::var("POST_RS_TOKEN").unwrap_or_else(
|
|
|_| failure_and_exit!("Token is required!")));
|
|
|
|
let file = args.file;
|
|
if !file.is_file() {
|
|
failure_and_exit!("File: {:?} not exists or it not a file.", file)
|
|
}
|
|
let file_name = args.file_name.unwrap_or_else(
|
|
|| file.file_name().map(
|
|
|f| f.to_str().map(ToString::to_string))
|
|
.flatten().unwrap_or_else(|| "unnamed".to_string()));
|
|
let content_type = args.content_type.unwrap_or_else(|| get_content_type(&file_name));
|
|
let description = args.description.unwrap_or_else(|| "n/a".to_string());
|
|
let available_after_create = args.available_after_create.unwrap_or_else(|| "7d".to_string());
|
|
let available_after_decrypt = args.available_after_decrypt.unwrap_or_else(|| "10m".to_string());
|
|
let password = args.pass;
|
|
|
|
let file_base64 = {
|
|
let file_bytes = fs::read(&file).unwrap_or_else(|e| {
|
|
failure_and_exit!("Read file: {:?} failed: {}", file, e)
|
|
});
|
|
base64::engine::general_purpose::STANDARD.encode(&file_bytes)
|
|
};
|
|
|
|
information!("Sending file: {}", file_name);
|
|
|
|
let mut params = HashMap::new();
|
|
params.insert("pretty", "true");
|
|
params.insert("token", &token);
|
|
params.insert("dataBase64", &file_base64);
|
|
params.insert("fileName", &file_name);
|
|
params.insert("contentType", &content_type);
|
|
params.insert("description", &description);
|
|
params.insert("availableAfterCreate", &available_after_create);
|
|
params.insert("availableAfterDecrypt", &available_after_decrypt);
|
|
debugging!("Params: {:?}", serde_json::to_string_pretty(¶ms));
|
|
|
|
if let Some(pass) = &password {
|
|
params.insert("pass", pass);
|
|
}
|
|
let client = reqwest::blocking::Client::new();
|
|
let post_result = client.post("https://hatter.ink/secfile/post.json")
|
|
.form(¶ms)
|
|
.send();
|
|
match post_result {
|
|
Err(e) => failure_and_exit!("Post file: {} failed: {}",file_name, e),
|
|
Ok(response) => match response.text() {
|
|
Err(e) => failure_and_exit!("Post file: {} response failed: {}", file_name, e),
|
|
Ok(text) => success!("Post file: {} succeed: {}", file_name, text),
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_content_type(file_name: &str) -> String {
|
|
let file_name = file_name.to_ascii_lowercase();
|
|
if file_name.ends_with(".txt") {
|
|
"text/plain".into()
|
|
} else if file_name.ends_with(".aac") {
|
|
"audio/aac".into()
|
|
} else if file_name.ends_with(".avi") {
|
|
"video/x-msvideo".into()
|
|
} else if file_name.ends_with(".css") {
|
|
"text/css".into()
|
|
} else if file_name.ends_with(".csv") {
|
|
"text/csv".into()
|
|
} else if file_name.ends_with(".doc") {
|
|
"application/msword".into()
|
|
} else if file_name.ends_with(".docx") {
|
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document".into()
|
|
} else if file_name.ends_with(".eot") {
|
|
"application/vnd.ms-fontobject".into()
|
|
} else if file_name.ends_with(".epub") {
|
|
"application/epub+zip".into()
|
|
} else if file_name.ends_with(".gz") {
|
|
"application/gzip".into()
|
|
} else if file_name.ends_with(".dif") {
|
|
"image/gif".into()
|
|
} else if file_name.ends_with(".htm")
|
|
|| file_name.ends_with(".html") {
|
|
"text/html".into()
|
|
} else if file_name.ends_with(".ico") {
|
|
"image/vnd.microsoft.icon".into()
|
|
} else if file_name.ends_with(".jar") {
|
|
"application/java-archive".into()
|
|
} else if file_name.ends_with(".jpe")
|
|
|| file_name.ends_with(".jpg")
|
|
|| file_name.ends_with(".jpeg") {
|
|
"image/jpeg".into()
|
|
} else if file_name.ends_with(".js") {
|
|
"text/javascript".into()
|
|
} else if file_name.ends_with(".json") {
|
|
"application/json".into()
|
|
} else if file_name.ends_with(".jsonld") {
|
|
"application/ld+json".into()
|
|
} else if file_name.ends_with(".mid")
|
|
|| file_name.ends_with(".midi") {
|
|
"audio/midi".into()
|
|
} else if file_name.ends_with(".mp3") {
|
|
"audio/mpeg".into()
|
|
} else if file_name.ends_with(".mp4") {
|
|
"video/mp4".into()
|
|
} else if file_name.ends_with(".mpeg") {
|
|
"video/mpeg".into()
|
|
} else if file_name.ends_with(".mpkg") {
|
|
"application/vnd.apple.installer+xml".into()
|
|
} else if file_name.ends_with(".odp") {
|
|
"application/vnd.oasis.opendocument.presentation".into()
|
|
} else if file_name.ends_with(".ods") {
|
|
"application/vnd.oasis.opendocument.spreadsheet".into()
|
|
} else if file_name.ends_with(".odt") {
|
|
"application/vnd.oasis.opendocument.text".into()
|
|
} else if file_name.ends_with(".oga") {
|
|
"audio/ogg".into()
|
|
} else if file_name.ends_with(".ogv") {
|
|
"video/ogg".into()
|
|
} else if file_name.ends_with(".ogg") {
|
|
"application/ogg".into()
|
|
} else if file_name.ends_with(".otf") {
|
|
"font/otf".into()
|
|
} else if file_name.ends_with(".png") {
|
|
"image/png".into()
|
|
} else if file_name.ends_with(".pdf") {
|
|
"application/pdf".into()
|
|
} else if file_name.ends_with(".ppt") {
|
|
"application/vnd.ms-powerpoint".into()
|
|
} else if file_name.ends_with(".pptx") {
|
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation".into()
|
|
} else if file_name.ends_with(".rar") {
|
|
"application/vnd.rar".into()
|
|
} else if file_name.ends_with(".rtf") {
|
|
"application/rtf".into()
|
|
} else if file_name.ends_with(".sh") {
|
|
"application/x-sh".into()
|
|
} else if file_name.ends_with(".svg") {
|
|
"image/svg+xml".into()
|
|
} else if file_name.ends_with(".tar") {
|
|
"application/x-tar".into()
|
|
} else if file_name.ends_with(".tif")
|
|
|| file_name.ends_with(".tiff") {
|
|
"image/tiff".into()
|
|
} else if file_name.ends_with(".ts") {
|
|
"video/mp2t".into()
|
|
} else if file_name.ends_with(".ttf") {
|
|
"font/ttf".into()
|
|
} else if file_name.ends_with(".wav") {
|
|
"audio/wav".into()
|
|
} else if file_name.ends_with(".weba") {
|
|
"audio/webm".into()
|
|
} else if file_name.ends_with(".webm") {
|
|
"video/webm".into()
|
|
} else if file_name.ends_with(".webp") {
|
|
"image/webp".into()
|
|
} else if file_name.ends_with(".woff") {
|
|
"font/woff".into()
|
|
} else if file_name.ends_with(".woff2") {
|
|
"font/woff2".into()
|
|
} else if file_name.ends_with(".xhtml") {
|
|
"application/xhtml+xml".into()
|
|
} else if file_name.ends_with(".xls") {
|
|
"application/vnd.ms-excel".into()
|
|
} else if file_name.ends_with(".xlsx") {
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".into()
|
|
} else if file_name.ends_with(".xml") {
|
|
"application/xml".into()
|
|
} else if file_name.ends_with(".zip") {
|
|
"application/zip".into()
|
|
} else if file_name.ends_with(".3gp") {
|
|
"video/3gpp".into()
|
|
} else if file_name.ends_with(".7z") {
|
|
"application/x-7z-compressed".into()
|
|
} else {
|
|
"application/octet-stream".into()
|
|
}
|
|
}
|