bobashare_admin/cli/
create.rsuse std::path::PathBuf;
use anyhow::{anyhow, Context};
use bobashare::{generate_randomized_id, storage::file::FileBackend};
use chrono::TimeDelta;
use clap::{Args, Subcommand};
use tokio::{
fs::File,
io::{self, AsyncWriteExt},
};
use tracing::{event, instrument, Level};
#[derive(Debug, Clone, Args)]
pub(crate) struct CreateUpload {
#[clap(short, long, value_parser)]
expiry: Option<u16>,
#[clap(short, long, value_parser)]
source_file: PathBuf,
#[clap(subcommand)]
name: NameOptions,
}
#[derive(Debug, Clone, Subcommand)]
pub(crate) enum NameOptions {
Random {
#[clap(short, long, default_value_t = 8)]
length: u16,
},
Name {
#[clap(short, long)]
name: String,
},
}
#[instrument(skip(backend))]
pub(crate) async fn create_upload(backend: FileBackend, args: CreateUpload) -> anyhow::Result<()> {
let expiry = args.expiry.map(|e| TimeDelta::try_days(e.into()).unwrap());
let name = match args.name {
NameOptions::Name { name } => name,
NameOptions::Random { length } => generate_randomized_id(length.into()),
};
let filename = args
.source_file
.file_name()
.ok_or_else(|| anyhow!("invalid filename for source file"))?
.to_string_lossy()
.to_string();
let mut file = File::open(&args.source_file)
.await
.with_context(|| format!("error opening file at {:?}", &args.source_file))?;
let mimetype = mime_guess::from_path(&args.source_file).first_or_octet_stream();
let mut upload = backend
.create_upload(name, filename, mimetype, expiry, None)
.await?;
println!("{:?}", upload.metadata);
let copied = io::copy(&mut file, &mut upload.file).await?;
event!(Level::DEBUG, "Wrote {} bytes to the upload file", copied);
upload.file.flush().await?;
upload.flush().await?;
Ok(())
}