From 813c16a00cb5f0766fad6bb7dbf00b965e14a5a3 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Mon, 26 Dec 2022 20:48:29 -0600 Subject: [PATCH] More refactoring + MD switch + Switched to Markdown + Removed RST module and tests + Converted RST pages to MD + Updated a few pages + Clippy + Fmt --- Cargo.lock | 142 ++++++++++++++++++ Cargo.toml | 2 + src/config.rs | 7 + src/error.rs | 2 + src/main.rs | 55 +++---- src/rst_parser/mod.rs | 113 -------------- src/rst_parser/rst_error.rs | 28 ---- src/tests/mod.rs | 28 ---- .../1resume.rst => raw_md/1resume.md} | 16 +- static/raw_md/projects/motion_detector.md | 21 +++ .../projects/website.md} | 50 ++++-- static/raw_rst/projects/motion_detector.rst | 33 ---- static/style.css | 4 +- templates/base.html.tera | 8 +- .../{rst_page.html.tera => md_page.html.tera} | 5 +- 15 files changed, 255 insertions(+), 259 deletions(-) create mode 100644 src/config.rs delete mode 100644 src/rst_parser/mod.rs delete mode 100644 src/rst_parser/rst_error.rs delete mode 100644 src/tests/mod.rs rename static/{raw_rst/1resume.rst => raw_md/1resume.md} (79%) create mode 100644 static/raw_md/projects/motion_detector.md rename static/{raw_rst/projects/website.rst => raw_md/projects/website.md} (55%) delete mode 100644 static/raw_rst/projects/motion_detector.rst rename templates/{rst_page.html.tera => md_page.html.tera} (67%) diff --git a/Cargo.lock b/Cargo.lock index 2b24d56..f1e26ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "async-compression" version = "0.3.15" @@ -66,6 +75,17 @@ dependencies = [ "syn", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -250,6 +270,21 @@ dependencies = [ "phf_codegen", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -440,6 +475,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -475,6 +519,15 @@ dependencies = [ "walkdir", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.15" @@ -622,9 +675,11 @@ version = "0.1.0" dependencies = [ "axum", "axum-extra", + "pulldown-cmark", "regex", "serde", "serde_json", + "structopt", "tera", "tokio", "tower", @@ -921,6 +976,30 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.49" @@ -930,6 +1009,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" +dependencies = [ + "bitflags", + "getopts", + "memchr", + "unicase", +] + [[package]] name = "quote" version = "1.0.7" @@ -1142,6 +1233,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "syn" version = "1.0.107" @@ -1190,6 +1311,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.38" @@ -1432,12 +1562,24 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +[[package]] +name = "unicode-segmentation" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" + [[package]] name = "unicode-width" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.2" diff --git a/Cargo.toml b/Cargo.toml index 337a0ac..dcc355c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,5 @@ tower-http = { version = "0.3.0", features = [ ] } tower-layer = "0.3.2" axum-extra = { version = "0.4.2", features = ["spa"]} +structopt = "0.3.26" +pulldown-cmark = "0.9.2" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..eae68a1 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,7 @@ +use std::net::SocketAddr; +use structopt::StructOpt; + +#[derive(StructOpt)] +pub struct SiteArgs { + pub serve_at: SocketAddr, +} diff --git a/src/error.rs b/src/error.rs index 352b64e..5a4fd68 100644 --- a/src/error.rs +++ b/src/error.rs @@ -44,3 +44,5 @@ impl Display for JSiteError { } } } + +pub type PageResult = Result; diff --git a/src/main.rs b/src/main.rs index bfb0bd0..2605ad5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ +mod config; mod error; -mod rst_parser; mod tests; -use crate::rst_parser::parse_images; use axum::error_handling::HandleErrorLayer; use axum::extract::{Path, State}; use axum::http::StatusCode; @@ -10,20 +9,21 @@ use axum::response::{Html, IntoResponse}; use axum::routing::get; use axum::{BoxError, Router}; use axum_extra::routing::SpaRouter; -use error::JSiteError; +use error::{JSiteError, PageResult}; +use pulldown_cmark::html::push_html; +use pulldown_cmark::{Options, Parser}; use regex::Regex; -use rst_parser::parse_links; use serde::Serialize; use std::borrow::Cow; -use std::net::SocketAddr; use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; +use structopt::StructOpt; use tera::{Context, Tera}; use tower::ServiceBuilder; use tower_http::trace::TraceLayer; -type PageResult = Result; +use crate::config::SiteArgs; #[derive(Serialize)] struct SiteFile { @@ -39,20 +39,20 @@ struct PageData { links: Vec, } -/// Returns the rendered template of the index page of the website. This includes links and rst -/// pages included in `static/raw_rst` +/// Returns the rendered template of the index page of the website. This includes links and md +/// pages included in `static/raw_md` async fn index(State(state): State>) -> PageResult { let mut ctx = Context::new(); let mut links: Vec = Vec::new(); // Get the links to display on the main page - get_pages("static/raw_rst", &mut links)?; + get_pages("static/raw_md", &mut links)?; ctx.insert("links", &links); Ok(Html(state.render("index.html.tera", &ctx)?)) } -/// Gets all the raw rst pages contained in a directory +/// Gets all the raw md pages contained in a directory /// /// The order of the vector is determined by OS. Ordering can be set by prepending the file name /// with a number. Files that start with lower numbers are placed earlier in the list. @@ -86,7 +86,7 @@ fn get_pages(path: &str, pages: &mut Vec) -> PageResult<()> { } else { match rank.parse() { Ok(r) => r, - Err(_) => std::u32::MAX, + Err(_) => u32::MAX, } }; @@ -149,12 +149,12 @@ fn get_page(path: &std::path::Path) -> PageResult { Err(JSiteError::PageNotFound(path.to_path_buf())) } -/// Returns a rendered template of a raw rst page if it exists +/// Returns a rendered template of a raw md page if it exists /// /// # Arguments /// * `page` - path to page -async fn rst_page(tera: State>, Path(page): Path) -> PageResult> { - let mut path = PathBuf::from("static/raw_rst"); +async fn md_page(tera: State>, Path(page): Path) -> PageResult> { + let mut path = PathBuf::from("static/raw_md"); path.push(page); // Try and get the page @@ -182,35 +182,35 @@ async fn rst_page(tera: State>, Path(page): Path) -> PageResu map.insert("page_data", &page_data); tera.render("listing.html.tera", &map)? } else { - // Else, render the RST page + // Else, render the MD page let mut map = Context::new(); let contents = match std::fs::read_to_string(site_page.path.clone()) { Ok(contents) => contents, Err(_) => return error_page(&tera, site_page.path.to_str().unwrap()).await, }; - // Render links - let mut contents = parse_links(&contents).unwrap(); - contents = parse_images(contents.as_str()).unwrap(); + let options = Options::all(); + let parser = Parser::new_ext(&contents, options); - // Ensure render will look good - contents = contents.replace('\n', "
"); - contents = contents.replace(" ", "  "); + let mut html_output = String::new(); + push_html(&mut html_output, parser); map.insert("page", &site_page.link_name); - map.insert("content", &contents); - tera.render("rst_page.html.tera", &map)? + map.insert("content", &html_output); + tera.render("md_page.html.tera", &map)? }; Ok(Html(page)) } +/// Build error page async fn error_page(tera: &Tera, page: &str) -> PageResult> { let mut map = Context::new(); map.insert("error_page", page); Ok(Html(tera.render("404.html.tera", &map)?)) } +/// Handle server errors async fn handle_error(error: BoxError) -> impl IntoResponse { if error.is::() { return (StatusCode::REQUEST_TIMEOUT, Cow::from("request timed out")); @@ -232,6 +232,8 @@ async fn handle_error(error: BoxError) -> impl IntoResponse { /// Launches website #[tokio::main] async fn main() { + let args = SiteArgs::from_args(); + // Use globbing let tera = match Tera::new("templates/*.tera") { Ok(t) => Arc::new(t), @@ -243,7 +245,7 @@ async fn main() { let app = Router::new() .route("/", get(index)) - .route("/about/*path", get(rst_page)) + .route("/about/*path", get(md_page)) .merge(SpaRouter::new("/static", "static")) .layer( ServiceBuilder::new() @@ -256,9 +258,8 @@ async fn main() { ) .with_state(tera); - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); - println!("listening on {}", addr); - axum::Server::bind(&addr) + println!("listening on {}", args.serve_at); + axum::Server::bind(&args.serve_at) .serve(app.into_make_service()) .await .unwrap(); diff --git a/src/rst_parser/mod.rs b/src/rst_parser/mod.rs deleted file mode 100644 index d41fed2..0000000 --- a/src/rst_parser/mod.rs +++ /dev/null @@ -1,113 +0,0 @@ -pub mod rst_error; - -use regex::{Captures, Regex}; -use rst_error::RSTError; -use std::collections::HashMap; -use std::convert::TryFrom; - -/// RST Image -struct RSTImage { - /// File location - image_file: String, - /// Height - height: Option, - /// Width - width: Option, - /// Alt Text - alt: Option, - /// Align (not implemented) - #[allow(dead_code)] - align: Option, -} - -impl RSTImage { - /// Convert to HTML img tag - fn to_html(&self) -> String { - let mut html = format!("\"{}\"",", html, style); - - html - } -} - -impl TryFrom<&Captures<'_>> for RSTImage { - type Error = RSTError; - /// Convert from a regex capture to a RSTImage - /// - /// # Arguments - /// - /// * cap - regex capture - fn try_from(cap: &Captures<'_>) -> Result { - let image = Self { - image_file: cap - .name("file_name") - .map(|m| m.as_str().to_string()) - .ok_or(RSTError::NotFound("file_name"))?, - height: cap.name("width").map(|m| m.as_str().to_string()), - width: cap.name("width").map(|m| m.as_str().to_string()), - alt: cap.name("alt").map(|m| m.as_str().to_string()), - align: cap.name("align").map(|m| m.as_str().to_string()), - }; - - Ok(image) - } -} - -/// Renders RST links as HTML links -/// -/// # Arguments -/// -/// * `string` - input RST string -pub fn parse_links(string: &str) -> Result { - let re_link_ref = Regex::new(r"\n?.. _(.*): (.*)\n")?; - let mut link_map: HashMap = HashMap::new(); - - for cap in re_link_ref.captures_iter(string) { - link_map.insert(String::from(&cap[1]), String::from(&cap[2])); - } - - let text: String = re_link_ref.replace_all(string, "").to_string(); - - let re_link = Regex::new(r"`(.*)`_")?; - - let output = re_link.replace_all(&text, |cap: &Captures| { - let link = match link_map.get(&cap[1]) { - None => String::from(""), - Some(link) => link.to_owned(), - }; - - format!("{}", link, &cap[1]) - }); - - Ok(output.to_string()) -} - -/// Renders RST images as HTML embedded images -/// -/// # Arguments -/// -/// * `string` - input rst string -pub fn parse_images(string: &str) -> Result { - let re_image = Regex::new( - r".. image:: (?P.*)\n( *((:height: (?P.*))|(:width: (?P.*))|(:scale: (?P.*%))|(:alt: (?P.*))|(:align: (?P.*)))\n)*", - )?; - - Ok(re_image - .replace_all(string, |cap: &Captures| { - RSTImage::try_from(cap).unwrap().to_html() - }) - .to_string()) -} diff --git a/src/rst_parser/rst_error.rs b/src/rst_parser/rst_error.rs deleted file mode 100644 index ff23ebc..0000000 --- a/src/rst_parser/rst_error.rs +++ /dev/null @@ -1,28 +0,0 @@ -use regex::Error; - -#[derive(Debug)] -pub enum RSTError { - /// Regex compile error - RegexError(regex::Error), - /// Required element not found - NotFound(&'static str), -} - -impl std::error::Error for RSTError {} - -impl From for RSTError { - /// From regex error - fn from(e: Error) -> Self { - Self::RegexError(e) - } -} - -impl std::fmt::Display for RSTError { - /// fmt error - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - RSTError::NotFound(s) => write!(f, "required element missing: `{}`", s), - RSTError::RegexError(e) => write!(f, "regex compile error: `{:?}`", e), - } - } -} diff --git a/src/tests/mod.rs b/src/tests/mod.rs deleted file mode 100644 index d94a64f..0000000 --- a/src/tests/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -#[cfg(test)] -use super::rst_parser::{parse_images, parse_links}; - -#[test] -fn test_link_parser() { - let mut input = String::from( - "This is a paragraph that contains `a link`_. - - .. _a link: https://domain.invalida\n", - ); - - let output = parse_links(&mut input).unwrap(); - - assert_eq!(output.trim_end(), "This is a paragraph that contains a link.") -} - -#[test] -fn test_image_parser() { - let input = ".. image:: cool/image/123.png - :width: 60% - :height: auto - :alt: this is the alt text - "; - - let output = parse_images(input).unwrap(); - - assert_eq!(output.trim_end(), "\"this") -} diff --git a/static/raw_rst/1resume.rst b/static/raw_md/1resume.md similarity index 79% rename from static/raw_rst/1resume.rst rename to static/raw_md/1resume.md index 0b5d752..74fb7c8 100644 --- a/static/raw_rst/1resume.rst +++ b/static/raw_md/1resume.md @@ -1,24 +1,22 @@ -Joey Hines - joey@ahines.net - Westminster, CO -============================================== +# Joey Hines - joey@ahines.net - Westminster, CO -Education ---------- +## Education * Masters of Science in Electrical and Computer Engineering * Auburn University, Auburn, AL. GPA: 3.9. May 2021 * Bachelors of Science in Computer Engineering * The University of Texas at Dallas, Richardson, TX. GPA: 3.59. May 2019 -Technical Skills ----------------- +## Technical Skills * Programing Languages: C, Python, Rust, Java * Operating Systems: Linux, Windows * Version Control: Git, SVN -Work Experience ---------------- +## Work Experience Blue Canyon Technologies - Flight Software Engineer - May 2021 to Present -* Developed flight software for small satellite missions +* Developed flight software for multiple small satellite missions across the BCT product line range * Collaborated with mission operations to improve ground station capabilities +* Improved test infrastructure and scripting +* Supported the summer internship program as a mentor Auburn University - Graduate Research and Teaching Assistant - August 2019 to May 2021 * Command and Data Handling (CDHS) team lead for a cube satellite project diff --git a/static/raw_md/projects/motion_detector.md b/static/raw_md/projects/motion_detector.md new file mode 100644 index 0000000..ba2863c --- /dev/null +++ b/static/raw_md/projects/motion_detector.md @@ -0,0 +1,21 @@ +# Motion Detector +A project made for Auburn ELEC 7450: Digtal Image Processing. The source code can be found on my +[GitHub](https://github.com/joeyahines/motion_detector) + +## Goal +The goal of this project was to detect motion on a video stream from a [VideoForLinux](https://en.wikipedia.org/wiki/Video4Linux) source. +The algorithm can also be tested by loading in individual frames. + +## Implementation +The project was written in C and VideoForLinux for grabbing image data and [SDL](https://www.libsdl.org/) +for rendering the video output. A background model is built by implementing a moving average of the image. +In addition to this, a motion mask is implemented to desensitise the algorithm from background motion objects. + +Webcam output w/ motion highlighted: + +![motion capture](https://github.com/joeyahines/motion_detector/blob/master/docs/final_report/motion.png?&raw=true) + +Motion detection layer: + +![motion detection layer](https://github.com/joeyahines/motion_detector/blob/master/docs/final_report/motion_image.png?raw=true) + diff --git a/static/raw_rst/projects/website.rst b/static/raw_md/projects/website.md similarity index 55% rename from static/raw_rst/projects/website.rst rename to static/raw_md/projects/website.md index 80758a2..a17c960 100644 --- a/static/raw_rst/projects/website.rst +++ b/static/raw_md/projects/website.md @@ -1,5 +1,34 @@ -This Website -============ +# This Website (V3) + +This is the 3rd iteration of this website. The 1st iteration was a simple HTML page built with bootstrap +that looked similar to the current design. The 2nd iteration moved to Rust and the Rocket framework and +was more dynamic allowing for RST pages to be rendered to html. This latest iteration uses Axum and Markdown +rendered to HTML for the dynamic content. + +## Moving away from Rocket +Rocket is a great framework and will probably be the Rust goto. However, it is very complex and comes +with a lot of bells and whistles I don't need. Its also in active development which meant it became very +hard to update the site. Everytime I wanted to add a new feature I would go to update Rocket and have something +break. + +I originally tried Warp, which I have used for some other projects. While I like it mostly, I find it very +hard to move past the basic examples. And when you run into issues with it, the compiler loves to spit out +very esoteric errors that are a pain to debug. + +I'm also a low level developer. I like working at lower levels of interfaces. Axum is pretty high level +in the grand scheme of things, but it doesn't seem overly opinionated in its design. Axum has its own issues +and I doubt this will be the last time I switch the framework... + +## Moving away from RST +I lied, in the last updated for this site I said how much I loved RST. After using more Markdown for note-taking +and for some documentation, I realized I like it more. I always decided to not write my own parse for it. +Rust has some good libraries that render MD to HTML. + +# This Website (V2) +> NOTE: This is the old version of this page for the second version of this site. It's here for archival purposes. +This was originally written in RST and has been converted to MD for v3. + +## This Website This is the 2nd version of my personal website, the first version was very similar to this but written in plain HTML using Bootstrap. I was never very happy with how it looked and it being raw HTML limited what I could do with it. To improve it, I set out with a few goals: @@ -10,19 +39,15 @@ improve it, I set out with a few goals: * Improve aesthetics * Ensure mobile version also looks good -Picking Rust and Rocket ------------------------ -As I am not much of a UI person, the website update was put on the back burner for sometime. The old site was "good +### Picking Rust and Rocket +As I am not much of a UI person, the website update was put on the back burner for sometime. The old site was "good enough." I originally considered doing it in Python and using Django. But that fails the criteria of being easily -deployable. In early 2020, I began learning Rust out of curiosity and the need to use it for research. -I decided to tackle the website backend in Rust as a learning exercise. I went with the `Rocket`_ framework. It +deployable. In early 2020, I began learning Rust out of curiosity and the need to use it for research. +I decided to tackle the website backend in Rust as a learning exercise. I went with the Rocket framework. It seemed to suit my needs and supported Tera templates. Tera templates are very similar to Django's templates that I had already had experience in. -.. _Rocket: https://rocket.rs/ - -Easily Editable ---------------- +### Easily Editable As the style of the site is a simplistic linux terminal, I decided it would be nice to have the longer pages be in raw reStructuredText. This fits the aesthetic of the site well and unlike HTML files, they are raw text and are easy to write and read while editing them. RST files can also easily be built into PDFs, which is great for generating a resume. @@ -32,8 +57,7 @@ the Rust backend looks for all pages and lists them. To control ordering, I impl character of a file name is its rank. For example, my resume is in a file called 1resume.rst. This gives it rank of 1 so it shows up on the main page before other links. -Improving Aesthetics --------------------- +### Improving Aesthetics Like stated earlier, I am no UI designer. The terminal style meant I could put very little effort into the design of the actual website. Somehow in version one, I still managed to mess that up. This was mainly due to hacking together bootstrap to give me something that looked like a terminal. This time, I dumped Bootstrap and wrote my own CSS. I should diff --git a/static/raw_rst/projects/motion_detector.rst b/static/raw_rst/projects/motion_detector.rst deleted file mode 100644 index 84f5eeb..0000000 --- a/static/raw_rst/projects/motion_detector.rst +++ /dev/null @@ -1,33 +0,0 @@ -Motion Detector -=============== -A project made for Auburn ELEC 7450: Digtal Image Processing. The source code can be found on my `Github`_ - -.. _GitHub: https://github.com/joeyahines/motion_detector - -Goal -++++ -The goal of this project was to detect motion on a video stream from a `VideoForLinux`_ source. The algorithm -can also be tested by loading in individual frames. - -.. _VideoForLinux: https://en.wikipedia.org/wiki/Video4Linux - -Implementation -++++++++++++++ -The project was written in C and VideoForLinux for grabbing image data and `SDL`_ for rendering the video -output. A background model is built by implementing a moving average of the image. In addition to this, -a motion mask is implemented to desensitise the algorithm from background motion objects. - -.. _SDL: https://www.libsdl.org/ - -Webcam output w/ motion highlighted: - -.. image:: https://github.com/joeyahines/motion_detector/blob/master/docs/final_report/motion.png?&raw=true - :width: 60% - :height: auto - -Motion detection layer: - -.. image:: https://github.com/joeyahines/motion_detector/blob/master/docs/final_report/motion_image.png?raw=true - :width: 60% - :height: auto - diff --git a/static/style.css b/static/style.css index b9fb929..75e38cd 100644 --- a/static/style.css +++ b/static/style.css @@ -6,7 +6,7 @@ } .text { - font-family: "Ubuntu Mono", monospace; + font-family: "Hack", monospace; color: whitesmoke; } @@ -15,7 +15,7 @@ } .heading { - font-family: "Ubuntu Mono", monospace; + font-family: "Hack", monospace; color: limegreen; } diff --git a/templates/base.html.tera b/templates/base.html.tera index 259fc6d..772bfe3 100644 --- a/templates/base.html.tera +++ b/templates/base.html.tera @@ -5,7 +5,7 @@ Joey Hines. - + @@ -14,12 +14,12 @@

Joey Hines.

-

+

joey@ahines:~$ {% block command %}{% endblock command %}
{% block content %}{% endblock content %}
- joey@ahines:~$ -

+
+ joey@ahines:~$
© Joey Hines
diff --git a/templates/rst_page.html.tera b/templates/md_page.html.tera similarity index 67% rename from templates/rst_page.html.tera rename to templates/md_page.html.tera index 41df8b3..08204a2 100644 --- a/templates/rst_page.html.tera +++ b/templates/md_page.html.tera @@ -1,11 +1,12 @@ {% extends "base.html.tera" %} {% block command %} -cat {{ page }}.rst +cat {{ page }}.md {% endblock command %} +
{% block content %}
{{ content | safe }} -{% endblock content %} \ No newline at end of file +{% endblock content %}