feat: add post-rs
This commit is contained in:
1264
post-rs/Cargo.lock
generated
Normal file
1264
post-rs/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
post-rs/Cargo.toml
Normal file
14
post-rs/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "post-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[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"
|
||||||
114
post-rs/src/main.rs
Normal file
114
post-rs/src/main.rs
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#!/usr/bin/env runrs
|
||||||
|
|
||||||
|
//! ```cargo
|
||||||
|
//! [dependencies]
|
||||||
|
//! clap = "4.1.8"
|
||||||
|
//! 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)]
|
||||||
|
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_bytes = fs::read(&file).unwrap_or_else(|e| {
|
||||||
|
failure_and_exit!("Read file: {:?} failed: {}", file, e)
|
||||||
|
});
|
||||||
|
let file_base64 = 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(respone) => match respone.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 {
|
||||||
|
if file_name.ends_with(".txt") {
|
||||||
|
"text/plain".into()
|
||||||
|
} else {
|
||||||
|
"application/octet-stream".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user