+ Rust docs where needed

There may be more changes that could be
added to improve documentation however
this is meant to be a good start.

!+ There is also a new redirect endpoint for /admin/dashboard
This just a convenience thing so that people
don't have to remember the '/dashboard'
part of the admin route.
This commit is contained in:
shockrah 2022-03-26 21:51:07 -07:00
parent 6c6d5f8f30
commit 86b9081354
6 changed files with 41 additions and 14 deletions

View File

@ -12,12 +12,18 @@ use std::path::{Path, PathBuf};
use rocket::data::{Data, ToByteUnit};
use rocket::serde::json::Json;
use rocket_dyn_templates::Template;
use rocket::response::Redirect;
use response::{bad_request, ok};
use apikey::ApiKey;
use response::ActionResponse;
use crate::common::get_clips_dir;
#[get("/")]
pub async fn login_dashboard_redirect() -> Redirect {
Redirect::to("/admin/dashboard")
}
#[get("/dashboard")]
pub async fn login_dashboard() -> Template {
// This page is basically just a login form
@ -37,9 +43,11 @@ pub async fn dashboard(_key: ApiKey) -> Json<ActionResponse> {
#[post("/upload-video/<category>/<filename>", data = "<data>")]
pub async fn updload_video(_key: ApiKey, category: PathBuf, filename: PathBuf, data: Data<'_>)
-> Result<Json<ActionResponse>> {
// filenames must have a basename .len of at least 1 + '.' + extension
// Valid file extensions are mkv|mp4|webm
/*
* Uploads must have BOTH a valid filename and a category
* Without the category the server will simply not find
* the correct endpoint to reach and thus will 404
*/
if util::valid_filename(&filename) == false {
return Ok(bad_request(Some("Invalid filename(s)")));
}
@ -47,8 +55,14 @@ pub async fn updload_video(_key: ApiKey, category: PathBuf, filename: PathBuf, d
let clips = get_clips_dir();
fs::create_dir_all(Path::new(&clips).join(&category))?;
/*
* We allow up to 200 Megaytes per upload as most short
* clips are not going to be very large anyway and this
* should be a reasonably high limit for those that want
* to upload "large" clips
* */
let filepath = Path::new(&clips).join(category).join(filename);
data.open(200.megabytes()).into_file(filepath).await?;
data.open(250.megabytes()).into_file(filepath).await?;
Ok(ok())
}

View File

@ -5,20 +5,19 @@ 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/<category>/.thumbnail.png
/// NOTE: this is simply a URI pathname
/// EXAMPLE: /thumbnail/<category>/.thumbnail.png
thumbnail: String
}
#[derive(Serialize)]
struct List {
categories: Vec<Category>
}
/// Returns a vector of category directories
pub fn get_category_dirs(path: &str) -> std::io::Result<Vec<DirEntry>> {
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);
@ -33,10 +32,12 @@ pub fn get_category_dirs(path: &str) -> std::io::Result<Vec<DirEntry>> {
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<String> {
let pathname = format!("{}/{}", thumbs_dir(), &category);
let path = Path::new(&pathname);
// Assume its a directory
// 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();
@ -55,10 +56,10 @@ pub fn get_category_thumbnail(category: &str) -> std::io::Result<String> {
})
}
/// WARN: misconfigured servers are just going to get shafted and serve up
/// a tonne of 500's
#[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 = get_clips_dir();
let mut cats: Vec<Category> = Vec::new();

View File

@ -1,5 +1,6 @@
use std::env;
/// Returns the absolute path to the videos directory
pub fn get_clips_dir() -> String {
match env::var("CLIPS_DIR") {
Ok(val) => val,
@ -7,6 +8,7 @@ pub fn get_clips_dir() -> String {
}
}
/// Returns the absolute path to the thumbnails directory
pub fn thumbs_dir() -> String {
match env::var("THUMBS_DIR") {
Ok(val) => val,

View File

@ -1,3 +1,7 @@
/// This module takes care of returning bare webpage templates
/// Most of the work done here is simply to fill the templates
/// with the appropriate meta data that is required
use rocket_dyn_templates::Template;
use rocket::fs::NamedFile;
use std::path::{Path, PathBuf};
@ -19,6 +23,7 @@ lazy_static! {
};
}
/// Default metadata that all web pages must be filled with
pub fn default_map() -> HashMap<&'static str, String> {
let mut h: HashMap<&'static str, String> = HashMap::new();
h.insert("sitetitle", SITENAME.clone());
@ -108,8 +113,9 @@ pub fn video(cat: PathBuf, file_base: PathBuf) -> Template {
Template::render("video", &h)
}
/// This route handler returns static files that are comprised
/// of JS, CSS, the favicon and other static items
#[get("/<file..>")]
pub async fn files(file: PathBuf) -> Option<NamedFile> {
// Used for things like javascript, css, and favicons
NamedFile::open(Path::new("static/").join(file)).await.ok()
}

View File

@ -2,6 +2,7 @@ use rocket::fs::NamedFile;
use std::path::{Path, PathBuf};
use crate::common::thumbs_dir;
/// Returns a thumbnail whose formatted name is <video-name>.<ext>.jpg
#[get("/<file..>")]
pub async fn get(file: PathBuf) -> Option<NamedFile> {
let clips_dir = thumbs_dir();

View File

@ -8,7 +8,9 @@ use crate::common::get_clips_dir;
#[derive(Serialize)]
pub struct VideoPreview {
/// Real filename on disk
name: String,
/// URI path to what the browser can reasonably expect
thumbnail: Option<String>
}
@ -60,6 +62,7 @@ pub fn list(cat: PathBuf) -> Option<Json<Vec<VideoPreview>>> {
}
/// Endpoint returns the video file itself that is saved on the server
#[get("/<cat>/<file>")]
pub async fn get_video(cat: PathBuf, file: PathBuf) -> Option<NamedFile> {
let clips_dir = get_clips_dir();