clippable/api/src/category.rs
shockrah d5b8fba7f6 * Opting to return a URI pathname to thumbnails now
Because of this the backend now only has to serve data that browsers req
Also helps out api clients since responses are generally smaller
And helps out servers since responses are faster
2021-10-12 11:18:32 -07:00

56 lines
1.5 KiB
Rust

use serde::Serialize;
use std::fs::DirEntry;
use std::{io, env};
use rocket::serde::json::Json;
#[derive(Serialize)]
pub struct Category {
name: String,
// NOTE: this is simply a URI pathname
// EXAMPLE: /thumbnail/<category>/.thumbnail.png
thumbnail: String
}
#[derive(Serialize)]
struct List {
categories: Vec<Category>
}
fn get_category_dirs(path: &str) -> std::io::Result<Vec<DirEntry>> {
let path = std::path::Path::new(path);
if !path.is_dir() {
let e = io::Error::new(io::ErrorKind::NotFound, "Unable to open");
return Err(e);
}
let mut ret: Vec<DirEntry> = Vec::new();
for entry in std::fs::read_dir(path)? {
if let Ok(entry) = entry {
ret.push(entry)
}
}
return Ok(ret);
}
#[get("/categories")]
pub fn list() -> Json<Vec<Category>> {
// WARN: misconfigured servers are just going to get shafted and serve up
// a tonne of 500's
let dir = match env::var("CLIPS_DIR") {
Ok(val) => val,
Err(_) => "/media/clips/".to_string()
};
let mut cats: Vec<Category> = 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 = format!("/thumbnail/{}/category-thumbnail.jpg", name);
cats.push(Category {name, thumbnail});
}
}
Json(cats)
}