Generate thumbnails before API starts up
Clients can now request a thumbnail by specifying a size on the image request.
This commit is contained in:
69
src/main.rs
69
src/main.rs
@@ -1,5 +1,6 @@
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
extern crate rayon;
|
||||
|
||||
use actix_files::NamedFile;
|
||||
use actix_web::web::{HttpRequest, HttpResponse, Json};
|
||||
@@ -7,8 +8,9 @@ use actix_web::{get, post, web, App, HttpServer, Responder};
|
||||
use chrono::{Duration, Utc};
|
||||
use data::{LoginRequest, ThumbnailRequest};
|
||||
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||
use rayon::prelude::*;
|
||||
use serde::Serialize;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::data::{Claims, CreateAccountRequest, Token};
|
||||
use crate::database::{create_user, get_user, user_exists};
|
||||
@@ -105,16 +107,28 @@ fn is_valid_path(path: &str) -> Option<PathBuf> {
|
||||
}
|
||||
|
||||
#[get("/image")]
|
||||
async fn image(
|
||||
async fn get_image(
|
||||
_claims: Claims,
|
||||
request: HttpRequest,
|
||||
req: web::Query<ThumbnailRequest>,
|
||||
) -> impl Responder {
|
||||
if let Some(path) = is_valid_path(&req.path) {
|
||||
if let Ok(file) = NamedFile::open(path) {
|
||||
file.into_response(&request).unwrap()
|
||||
if let Some(_) = req.size {
|
||||
let thumbs = dotenv::var("THUMBNAILS").unwrap();
|
||||
let thumb_path = Path::new(&thumbs).join(path.file_name().unwrap());
|
||||
|
||||
println!("{:?}", thumb_path);
|
||||
if let Ok(file) = NamedFile::open(&thumb_path) {
|
||||
file.into_response(&request).unwrap()
|
||||
} else {
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
} else {
|
||||
HttpResponse::NotFound().finish()
|
||||
if let Ok(file) = NamedFile::open(path) {
|
||||
file.into_response(&request).unwrap()
|
||||
} else {
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
HttpResponse::BadRequest().finish()
|
||||
@@ -164,14 +178,57 @@ async fn get_video_part(request: HttpRequest, path: web::Path<ThumbnailRequest>)
|
||||
}
|
||||
}
|
||||
|
||||
async fn create_thumbnails() {
|
||||
let thumbs = &dotenv::var("THUMBNAILS").expect("THUMBNAILS not defined");
|
||||
let thumbnail_directory: &Path = Path::new(thumbs);
|
||||
|
||||
let t: Vec<_> = thumbnail_directory
|
||||
.read_dir()
|
||||
.expect("Error reading thumbnail directory")
|
||||
.collect();
|
||||
if t.len() > 0 {
|
||||
println!("Skipping thumbs");
|
||||
return;
|
||||
}
|
||||
|
||||
let images = PathBuf::from(dotenv::var("BASE_PATH").unwrap());
|
||||
|
||||
walkdir::WalkDir::new(images)
|
||||
.into_iter()
|
||||
.collect::<Vec<Result<_, _>>>()
|
||||
.into_par_iter()
|
||||
.filter_map(|entry| entry.ok())
|
||||
.filter(|entry| {
|
||||
println!("{:?}", entry.path());
|
||||
match entry.path().extension() {
|
||||
Some(ext) if ext == "jpg" || ext == "jpeg" || ext == "png" => true,
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.map(|entry| (image::open(entry.path()), entry.path().to_path_buf()))
|
||||
.filter(|(img, _)| img.is_ok())
|
||||
.map(|(img, path)| (img.unwrap(), path))
|
||||
.map(|(image, path)| (image.thumbnail(200, 200), path))
|
||||
.map(|(image, path)| {
|
||||
let thumb = Path::new(thumbnail_directory).join(path.file_name().unwrap());
|
||||
println!("{:?}", thumb);
|
||||
image.save(thumb).expect("Failure saving thumbnail");
|
||||
})
|
||||
.for_each(drop);
|
||||
|
||||
println!("Finished");
|
||||
}
|
||||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
create_thumbnails().await;
|
||||
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.service(register)
|
||||
.service(login)
|
||||
.service(list_photos)
|
||||
.service(image)
|
||||
.service(get_image)
|
||||
.service(generate_video)
|
||||
.service(stream_video)
|
||||
.service(get_video_part)
|
||||
|
||||
Reference in New Issue
Block a user