* vid_file_entries now uses common::get_clips_dir

- get_video_preview
This is because of the old base64 requirement
* /api/category/<cat> handler now returns Option<Json<Vec<VideoPreview>>>
While more verbose we can more easily convey intentions
to any consumers of this endpoint.
Those intentions being that None values just mean nothing was found
This commit is contained in:
shockrah 2021-10-12 22:17:50 -07:00
parent e049512c03
commit 254da1ae90

View File

@ -1,7 +1,9 @@
use std::env;
use std::path::PathBuf;
use std::fs::DirEntry;
use std::ffi::OsStr;
use serde::Serialize;
use rocket::serde::json::Json;
use crate::common::get_clips_dir;
#[derive(Serialize)]
pub struct VideoPreview {
@ -9,8 +11,11 @@ pub struct VideoPreview {
thumbnail: Option<String>
}
fn vid_file_entries(path: &str) -> std::io::Result<Vec<DirEntry>> {
let path = std::path::Path::new(path);
fn vid_file_entries(path: &OsStr) -> std::io::Result<Vec<DirEntry>> {
let mut dir = get_clips_dir();
dir.push('/'); dir.push_str(&path.to_string_lossy());
let path = std::path::Path::new(&dir);
if !path.is_dir() {
panic!("<{:?}> is not a valid directory", path);
}
@ -26,68 +31,32 @@ fn vid_file_entries(path: &str) -> std::io::Result<Vec<DirEntry>> {
return Ok(entries);
}
pub fn get_video_preview(clips_dir: &str, vid_file: &str) -> std::io::Result<VideoPreview> {
use std::io::Read;
// Contruct the full path to the video file itself
// NOTE: thumbnail file names are basically file.mkv.jpg
let path = {
let mut s = clips_dir.to_string();
s.push_str("/thumbnails/");
s.push_str(vid_file);
s.push_str(".jpg");
s
};
let path = std::path::Path::new(&path);
if !path.is_file() {
println!("File {:?} not found", path);
let e = std::io::Error::new(std::io::ErrorKind::NotFound, "Thumbnail file not found");
return Err(e);
#[get("/category/<cat..>")]
pub fn list(cat: PathBuf) -> Option<Json<Vec<VideoPreview>>> {
/*
* List out the videos to a given category
*/
// First we have to make sure this given category is even registered with us
let file_path = cat.file_name().unwrap_or(OsStr::new(""));
if let Ok(entries) = vid_file_entries(file_path) {
let mut previews: Vec<VideoPreview> = Vec::new();
// Autismo but at least its bare-able
for ent in entries {
let name = ent.file_name();
let name = name.to_string_lossy();
let cat = cat.to_string_lossy();
let thumbnail = format!("/thumbnail/{}/{}", cat, name);
let item = VideoPreview {
name: name.to_string(),
thumbnail: Some(thumbnail)
};
previews.push(item);
}
return Some(Json(previews))
}
// Read into a vec so that base64 can deal with it
let mut buf = Vec::new();
let mut file = std::fs::File::open(path)?;
file.read_to_end(&mut buf)?;
let thumbnail = base64::encode(buf).to_string();
let thumbnail = match thumbnail.len() {
0 => None,
_ => Some(thumbnail)
};
let name = match path.file_name() {
Some(val) => val.to_string_lossy().to_string(),
None => String::new()
};
Ok(VideoPreview { name, thumbnail })
}
#[get("/category/<cat>")]
pub fn list(cat: String) -> Json<Vec<VideoPreview>> {
// Strip out any and all '..' from the string
// Doing this to avoid any directory traversal memes
let cat = cat.replace("..","");
// Target the directory of clips that we're looking for
let mut clips_dir = match env::var("CLIPS_DIR") {
Ok(val) => val,
Err(_) => "/media/clips/".to_string()
};
clips_dir.push('/'); clips_dir.push_str(&cat);
let thumbs_dir = clips_dir.clone();
let mut json: Vec<VideoPreview> = Vec::new();
// Grab direntires to all the target files
let vid_files = vid_file_entries(&clips_dir).unwrap();
for vf in vid_files {
// jfc this is rarted
let name = vf.file_name().to_string_lossy().to_string();
match get_video_preview(&thumbs_dir, &name) {
Ok(val) => json.push(val),
_ => continue
};
}
return Json(json)
return None;
}