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