use serde::Serialize; use std::fs::DirEntry; use std::path::Path; use std::io; use rocket::serde::json::Json; use crate::common::{get_clips_dir, thumbs_dir}; /// Describes a category of videos as #[derive(Serialize)] pub struct Category { name: String, /// NOTE: this is simply a URI pathname /// EXAMPLE: /thumbnail//.thumbnail.png thumbnail: String } /// Returns a vector of category directories pub fn get_category_dirs(path: &str) -> std::io::Result> { let path = std::path::Path::new(path); // Trying to ignore non-directory entries if !path.is_dir() { let e = io::Error::new(io::ErrorKind::NotFound, "Unable to open"); return Err(e); } let mut ret: Vec = Vec::new(); for entry in (std::fs::read_dir(path)?).flatten() { if entry.path().is_dir() { ret.push(entry) } } Ok(ret) } /// Will return the path to a category's thumb nail assuming it exists. /// If nothing is found then it gives back the URI path to a not-found image pub fn get_category_thumbnail(category: &str) -> std::io::Result { let pathname = format!("{}/{}", thumbs_dir(), &category); let path = Path::new(&pathname); // Assume directory as we're only called from "safe" places let item = path.read_dir()?.find(|file| { if let Ok(file) = file { let name = file.file_name().into_string().unwrap(); name == "category-thumbnail.jpg" } else { false } }); return Ok(match item { Some(name) => { let name = name.unwrap().file_name().into_string().unwrap(); format!("/thumbnail/{}/{}", category, name) }, None => "/static/cantfindshit.jpg".to_string() }) } /// WARN: misconfigured servers are just going to get shafted and serve up /// a tonne of 500's #[get("/categories")] pub fn list() -> Json> { let dir = get_clips_dir(); let mut cats: Vec = Vec::new(); if let Ok(dirs) = get_category_dirs(&dir) { // Let's just assume that each item in this directory is a folder // That way we can do this blindly without 9999 allocs for d in dirs { let name = d.file_name().to_string_lossy().to_string(); let thumbnail = match get_category_thumbnail(&name) { Ok(s) => s, _ => "/static/cantfindshit.jpg".to_string() }; cats.push(Category {name, thumbnail}); } } Json(cats) }