* 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::fs::DirEntry;
use std::ffi::OsStr;
use serde::Serialize; use serde::Serialize;
use rocket::serde::json::Json; use rocket::serde::json::Json;
use crate::common::get_clips_dir;
#[derive(Serialize)] #[derive(Serialize)]
pub struct VideoPreview { pub struct VideoPreview {
@ -9,8 +11,11 @@ pub struct VideoPreview {
thumbnail: Option<String> thumbnail: Option<String>
} }
fn vid_file_entries(path: &str) -> std::io::Result<Vec<DirEntry>> { fn vid_file_entries(path: &OsStr) -> std::io::Result<Vec<DirEntry>> {
let path = std::path::Path::new(path); 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() { if !path.is_dir() {
panic!("<{:?}> is not a valid directory", path); 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); 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() { #[get("/category/<cat..>")]
println!("File {:?} not found", path); pub fn list(cat: PathBuf) -> Option<Json<Vec<VideoPreview>>> {
let e = std::io::Error::new(std::io::ErrorKind::NotFound, "Thumbnail file not found"); /*
return Err(e); * List out the videos to a given category
} */
// First we have to make sure this given category is even registered with us
// Read into a vec so that base64 can deal with it let file_path = cat.file_name().unwrap_or(OsStr::new(""));
let mut buf = Vec::new(); if let Ok(entries) = vid_file_entries(file_path) {
let mut file = std::fs::File::open(path)?; let mut previews: Vec<VideoPreview> = Vec::new();
file.read_to_end(&mut buf)?; // Autismo but at least its bare-able
for ent in entries {
let thumbnail = base64::encode(buf).to_string(); let name = ent.file_name();
let thumbnail = match thumbnail.len() { let name = name.to_string_lossy();
0 => None,
_ => Some(thumbnail) let cat = cat.to_string_lossy();
}; let thumbnail = format!("/thumbnail/{}/{}", cat, name);
let name = match path.file_name() {
Some(val) => val.to_string_lossy().to_string(), let item = VideoPreview {
None => String::new() name: name.to_string(),
}; thumbnail: Some(thumbnail)
Ok(VideoPreview { name, thumbnail }) };
} previews.push(item);
}
#[get("/category/<cat>")] return Some(Json(previews))
pub fn list(cat: String) -> Json<Vec<VideoPreview>> { }
// Strip out any and all '..' from the string return None;
// 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)
} }