Files
scriptbase/post-rs/src/main.rs
2023-03-05 17:40:19 +08:00

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(&params));
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(&params)
.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()
}
}