Add comments

This commit is contained in:
SeanOMik 2022-11-13 19:58:51 -05:00
parent 024e51e60d
commit 55b6cc1a10
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
1 changed files with 35 additions and 16 deletions

View File

@ -6,21 +6,24 @@ use std::path::{PathBuf, Path};
use std::{io, fs};
use rand::seq::SliceRandom;
/// Simple program to greet a person
/// Struct representing CLI arguments
#[derive(Parser, Debug)]
#[command(author, version, about)]
struct CliArgs {
/// Name of the person to greet
//#[arg(short, long)]
/// Paths to search for images in.
paths: Vec<PathBuf>,
/// Port to serve the http server on.
#[arg(short, long, default_value_t = 8080)]
port: u16,
/// Wether or not to recursively search for images in supplied paths
#[arg(short, long, default_value_t = true)]
recursive: bool
}
/// A Struct representing an image that was indexed.
/// Currently this just stores a path, but it might be expanded on later.
#[derive(Clone)]
struct IndexedImage {
path: PathBuf
@ -34,6 +37,7 @@ impl IndexedImage {
}
}
/// Actix-web AppState. This is used to share the indexed pictures to routes.
struct AppState {
pub pictures: Vec<IndexedImage>,
}
@ -53,26 +57,36 @@ async fn chose_picture(data: web::Data<AppState>, path: web::Path<String>) -> im
if tail.is_empty() {
let pictures = &data.pictures;
// Randomly chose a image
if let Some(chosen) = pictures.choose(&mut rand::thread_rng()) {
// Convert the image's path to a &str and handle the option.
let path = match chosen.path.to_str() {
Some(s) => s,
None => {
return HttpResponse::InternalServerError().body("Failed to convert path PathBuf to &str (The path is not valid unicode)!");
return HttpResponse::InternalServerError()
.body("Failed to convert path PathBuf to &str (The path is not valid unicode)!");
}
};
HttpResponse::TemporaryRedirect().insert_header((actix_web::http::header::LOCATION, format!("/{}", path))).finish()
// Redirect client
HttpResponse::TemporaryRedirect()
.insert_header((actix_web::http::header::LOCATION, format!("/{}", path)))
.finish()
} else {
HttpResponse::NotFound().body("No images were discovered")
}
} else {
println!("Chose \"{}\"", tail);
// Find the dimensions of the image.
let (width, height) = match imagesize::size(tail.clone()) {
Ok(dim) => (dim.width, dim.height),
Err(err) => panic!("Error: {}", err),
Err(err) => {
return HttpResponse::InternalServerError().body(format!("Failure to get dimensions of image ({})!", err));
}
};
// Construct the html body
let body = format!("
<html lang=\"en\">
<head>
@ -88,12 +102,13 @@ async fn chose_picture(data: web::Data<AppState>, path: web::Path<String>) -> im
<img src=\"/img/{}\" width=\"{0}\" height=\"{1}\" alt=\"Roulette selected: {}\">
</a>
</body>
</html>", width, height, tail.clone(), tail);
</html>", width, height, tail.clone(), tail); // TODO: Give filename instead of path
HttpResponse::Ok().body(body)
}
}
/// Get the image mime for responding
fn get_image_mime(path: &String) -> std::io::Result<Option<String>> {
if let Some(kind) = infer::get_from_path(path)? {
if kind.matcher_type() == MatcherType::Image {
@ -111,19 +126,22 @@ async fn serve_picture(path: web::Path<String>) -> impl Responder {
if !tail.is_empty() {
println!("Serving file \"{}\"", tail);
// Read byes of image
let mut file = tokio::fs::File::open(&tail).await.unwrap(); // TODO: Don't unwrap
let mut contents = vec![];
file.read_to_end(&mut contents).await.unwrap(); // TODO: Don't unwrap
let content_type = get_image_mime(&tail).unwrap(); // TODO: Don't unwrap
HttpResponse::Ok().content_type(content_type.unwrap_or_default()).body(contents)
HttpResponse::Ok()
.content_type(content_type.unwrap_or_default())
.body(contents)
} else {
HttpResponse::NotFound().body("No path given")
}
}
/// Search for images in `dir`
fn image_discovery(dir: &Path, recursive: bool) -> io::Result<Vec<IndexedImage>> {
let mut files = vec![];
@ -132,6 +150,7 @@ fn image_discovery(dir: &Path, recursive: bool) -> io::Result<Vec<IndexedImage>>
let entry = entry?;
let path = entry.path();
if path.is_dir() {
// If we're discovering recursively, append the indexed images.
if recursive {
let mut explored = image_discovery(&path, recursive)?;
files.append(&mut explored);
@ -147,9 +166,9 @@ fn image_discovery(dir: &Path, recursive: bool) -> io::Result<Vec<IndexedImage>>
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let args: CliArgs = CliArgs::parse();
let args: CliArgs = CliArgs::parse(); // Parse CLI arguments
// Read all the images from the supplied paths
// Index all the images from the supplied paths
let mut images = vec![];
for path in args.paths {
println!("Exploring path: {:?}", path);
@ -159,13 +178,13 @@ async fn main() -> std::io::Result<()> {
println!("Discovered {} images!", images.len());
// Construct HTTP Actix server
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(AppState::new(images.clone())))
.service(serve_picture)
.service(chose_picture)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}).bind(("127.0.0.1", 8080))?
.run()
.await
}