+ 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:
parent
6c6d5f8f30
commit
86b9081354
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user