basic command line interface

This commit is contained in:
Jörn-Michael Miehe 2025-05-27 14:01:09 +00:00
parent 28039fd286
commit 155487fa83
4 changed files with 120 additions and 21 deletions

64
Cargo.lock generated
View file

@ -81,9 +81,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.23"
version = "1.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766"
checksum = "16595d3be041c03b09d08d0858631facccee9221e579704070e6e9e4915d3bc7"
dependencies = [
"shlex",
]
@ -94,6 +94,46 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed93b9805f8ba930df42c2590f05453d5ec36cbb85d018868a5b24d31f6ac000"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "379026ff283facf611b0ea629334361c4211d1b12ee01024eec1591133b04120"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]]
name = "colorchoice"
version = "1.0.3"
@ -238,6 +278,12 @@ version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "http"
version = "1.3.1"
@ -461,12 +507,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.0"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2611b99ab098a31bdc8be48b4f1a285ca0ced28bd5b4f23e45efa8c63b09efa5"
dependencies = [
"once_cell",
]
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "percent-encoding"
@ -657,6 +700,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
name = "shrupl"
version = "0.1.0"
dependencies = [
"clap",
"env_logger",
"log",
"serde",
@ -675,6 +719,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"

View file

@ -2,9 +2,15 @@
name = "shrupl"
version = "0.1.0"
edition = "2024"
description = "ShrUpl is a tool to upload files to a Sharry Instance through a public Alias, leveraging the tus protocol"
[dependencies]
clap = { version = "4.5.38", features = ["derive"] }
env_logger = "0.11.8"
log = "0.4.27"
serde = { version = "1.0.219", features = ["derive"] }
ureq = { version = "3.0.11", features = ["json"] }
[profile.release]
lto = true
panic = "abort"

View file

@ -1,10 +1,54 @@
mod sharry;
use std::{path::PathBuf, time::Duration};
use clap::Parser;
use log::{error, info};
use sharry::{Alias, File, NewShareRequest, Share};
use std::time::Duration;
use ureq::Agent;
use sharry::{Alias, File, NewShareRequest, Share, Uri};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Cli {
/// Protocol for Sharry instance
#[arg(
short, long,
default_value_t = String::from("https"),
value_parser = clap::builder::PossibleValuesParser::new(["http", "https"]),
)]
proto: String,
/// Name of the new share
#[arg(
short, long,
default_value_t = String::from("shrupl upload"),
)]
name: String,
/// Description of the new share
#[arg(short, long)]
desc: Option<String>,
/// Maximum number of views for the new share
#[arg(short, long, default_value_t = 10)]
views: u32,
/// Chunk size for uploading, in MiB
#[arg(short, long, default_value_t = 10)]
chunk: usize,
/// Base URL for Sharry Instance
url: String,
/// ID of a public alias to use
alias: String,
/// Files to upload to the new share
#[arg(value_name = "FILE")]
files: Vec<PathBuf>,
}
fn main() {
env_logger::init();
@ -13,12 +57,11 @@ fn main() {
.build()
.into();
let alias = Alias::new(
"sharry.yavook.de".into(),
"G7RYoWME1W7-pcgipemJcr8-39FcMd92gBu-RgufeHc51z6",
);
let args = Cli::parse();
let share = NewShareRequest::new(Some("foo"), "", 10);
let alias = Alias::new(Uri::with_protocol(args.proto, args.url), args.alias);
let share = NewShareRequest::new(args.name, args.desc, 10);
let share = Share::create(&agent, &alias, share).unwrap();
info!("share: {share:?}");
@ -28,7 +71,7 @@ fn main() {
.unwrap();
info!("file: {file:?}");
for chunk in file.chunked(10 * 1024 * 1024) {
for chunk in file.chunked(args.chunk * 1024 * 1024) {
println!("chunk len: {}", chunk.bytes.len());
file.upload_chunk(&agent, &alias, &chunk)
.inspect_err(|e| error!("error: {e}"))

View file

@ -29,23 +29,23 @@ impl From<Uri> for String {
#[derive(Serialize)]
#[allow(non_snake_case)]
pub struct NewShareRequest {
name: Option<String>,
name: String,
validity: u32,
description: String,
description: Option<String>,
maxViews: u32,
password: Option<String>,
}
impl NewShareRequest {
pub fn new(
name: Option<impl Into<String>>,
description: impl Into<String>,
name: impl Into<String>,
description: Option<impl Into<String>>,
max_views: u32,
) -> Self {
Self {
name: name.map(Into::into),
name: name.into(),
validity: 0,
description: description.into(),
description: description.map(Into::into),
maxViews: max_views,
password: None,
}