[web] Implement dumping of the static assets

This commit is contained in:
Emi Simpson 2021-10-30 15:17:19 -04:00
parent 26da64922d
commit e1aca0497e
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847
3 changed files with 70 additions and 4 deletions

View file

@ -33,11 +33,11 @@ pub enum SubCommand {
/// If serving static files, all files should be available under the /static/filename.ext
/// route.
pub struct DumpStatics {
#[argh(option, default = "String::from(\"./static/\")")]
#[argh(positional, default = "PathBuf::from(\"./static/\")")]
/// the directory to write the static files to
///
/// Defaults to ./static/
pub destination: String,
pub destination: PathBuf,
}
#[derive(FromArgs, PartialEq, Debug)]

View file

@ -5,6 +5,7 @@ pub mod configuration;
use configuration::ConfigError;
use std::io::ErrorKind;
use std::net::SocketAddr;
use std::process::exit;
use std::collections::HashMap;
@ -150,8 +151,38 @@ async fn main() -> std::io::Result<()> {
let args: configuration::PronounsTodayArgs = argh::from_env();
match args.command {
configuration::SubCommand::DumpStatics(_subargs) => {
println!("Support for dumping statics not yet implemented");
configuration::SubCommand::DumpStatics(subargs) => {
match statics::dump_statics(
subargs.destination.as_ref(),
statics::STATIC_ASSETS
) {
Ok(()) => {
println!("Successfully dumped all static assets to {}. Serve this \
directory under /static/ in order to speed up delivery of \
static assets", subargs.destination.display());
}
Err((e, path)) => {
match e.kind() {
ErrorKind::PermissionDenied => {
eprintln!(
"Permission denied for {}",
path.display(),
);
},
ErrorKind::AlreadyExists => {
eprintln!(
"Refusing to overwrite existing file {}",
path.display(),
);
},
_ => {
eprintln!("An unexpected IO error occurred while trying to \
interact with {}", path.display());
return Err(e);
}
};
}
};
Ok(())
}
configuration::SubCommand::Run(subargs) => {

View file

@ -1,3 +1,10 @@
use std::path::PathBuf;
use std::fs::OpenOptions;
use std::fs::File;
use std::fs::create_dir_all;
use std::io;
use std::io::Write;
use std::path::Path;
use actix_web::http::StatusCode;
use actix_web::HttpResponse;
use actix_web::HttpRequest;
@ -49,6 +56,34 @@ impl StaticAsset {
}
}
/// Attempt to dump several static assets to a directory
///
/// Creates the destination directory and all of the necessary parent directories, if
/// necessary. Will refuse to overwrite existing files.
pub fn dump_statics(destination: &Path, assets: &[StaticAsset]) -> Result<(), (io::Error, PathBuf)> {
create_dir_all(destination)
.map_err(|e| (e, destination.into()))?;
let files = assets.iter()
.map(|asset| {
let path = destination.join(asset.filename);
OpenOptions::new()
.write(true)
.create_new(true)
.open(&path)
.map_err(|e| (e, path.clone()))
.map(|file| (file, asset.bytes, path))
})
.collect::<Result<Vec<(File, &'static [u8], PathBuf)>, (io::Error, PathBuf)>>()?;
files.into_iter()
.map(|(mut file, bytes, path)|
file.write_all(bytes)
.map_err(|e| (e, path))
)
.collect::<Result<(), (io::Error, PathBuf)>>()
}
/// Generate a [`StaticAsset`] at compiletime from a filename.
#[cfg(any(feature = "embed_static_assets", feature = "ogp_images"))]