diff options
| -rw-r--r-- | content/projects/index.md | 46 | ||||
| -rw-r--r-- | src/assets.rs | 11 | ||||
| -rw-r--r-- | src/bin/actix.rs | 12 | ||||
| -rw-r--r-- | src/bin/hyper.rs | 36 | ||||
| -rw-r--r-- | src/blog.rs | 21 | ||||
| -rw-r--r-- | src/router.rs | 9 | ||||
| -rw-r--r-- | templates/header.html | 1 | ||||
| -rw-r--r-- | templates/projects.html | 12 | ||||
| -rw-r--r-- | tests/test_router.rs | 15 | ||||
| -rwxr-xr-x | watch | 5 | 
10 files changed, 149 insertions, 19 deletions
| diff --git a/content/projects/index.md b/content/projects/index.md new file mode 100644 index 0000000..2ae7015 --- /dev/null +++ b/content/projects/index.md @@ -0,0 +1,46 @@ +Just a list of some projects I have done and find useful on my day-to-day life. + +-   [Hub Watcher](https://hub-watcher.gabrielgio.me/) +    [[gitlab](https://gitlab.com/gabrielgio/hub-watcher)] + +    A small project to monitor changes in a docker image from [docker +    hub](https://hub.docker.com/). By default every 5 minutes it will fetch the +    digest of image and compare with the previous returned digest, if they are +    different it will make a post request to a given url. + +    I created it so I can automatically trigger my gitlab pipeline to build my +    custom nextcloud image everytime Nextcloud GmbH updates their image. + +-   [Reddit to Nextcloud +    importer](https://gabrielgio.gitlab.io/reddit-nextcloud-importer/) +    [[github](https://gitlab.com/gabrielgio/reddit-nextcloud-importer)] + +    A small project that monitors user\'s saved posts on reddit, downloads its +    media and uploads to a nextcloud instance. + +    It combines 3 projects: [praw](https://github.com/praw-dev/praw) to read and +    motitor user's saved feed, [gallery-dl](https://github.com/mikf/gallery-dl) +    to download media from several sources, and +    [nextcloud-api-wrapper](https://github.com/luffah/nextcloud-API) to manage +    folder and upload files to nexcloud instance. + +-   [Filter for Nerdcast +    (pt-BR)](https://gabrielgio.gitlab.io/jn_filter/) +    [[gitlab](https://gitlab.com/gabrielgio/jn_filter)] + +    Just a small podcast filter to remove and/or split a feed from +    [Nerdcast](https://www.jovemnerd.com.br/nerdcast/) into different segments. +    The current feed its quite clustered with many programs/segments and this +    project just helps to clean up so only the segment you want shows up on you +    podcast client. + +-   [Password generator](https://genpass.gabrielgio.me/) +    [[gitlab](https://gitlab.com/gabrielgio/genpass)] + +    It started with me having fun with clojure script ([last +    commit](https://gitlab.com/gabrielgio/genpass/-/tree/2db3d88503fbe219e99c464c4cc8e768613e1359)). +    Now I have been using it as a playground to play a bit with rust/wasm and it +    is a quite interesting comparacion to make. The cljs implementation could +    not handle more than 1k chars, while the wasm can easly handle >100k. Is it +    useful for a password generator? Probabally not, but if it is your use case +    now I got you covered. diff --git a/src/assets.rs b/src/assets.rs index 2c39d1b..32d26e9 100644 --- a/src/assets.rs +++ b/src/assets.rs @@ -11,12 +11,23 @@ pub const BLOG_REGEX: &str = r"(?P<date>[\d]{4}-[\d]{2}-[\d]{2})(?P<title>[a-zA-  #[folder = "content/posts/"]  pub struct PostAsset; +#[derive(RustEmbed)] +#[folder = "content/projects/"] +pub struct ProjectsAsset; +  #[derive(TemplateOnce)]  #[template(path = "index.html")]  pub struct IndexTemplate {      pub posts: Vec<BlogEntry>,  } + +#[derive(TemplateOnce)] +#[template(path = "projects.html")] +pub struct ProjectsTemplate { +    pub content: String, +} +  #[derive(TemplateOnce)]  #[template(path = "post.html")]  pub struct PostTemplate { diff --git a/src/bin/actix.rs b/src/bin/actix.rs index 101fe2e..978e8ed 100644 --- a/src/bin/actix.rs +++ b/src/bin/actix.rs @@ -1,5 +1,5 @@  use actix_web::{get, web, middleware, App, HttpResponse, HttpServer, Responder, http::header::ContentType}; -use macroblog::blog::{render_index_page, render_post_page}; +use macroblog::blog::{render_index_page, render_post_page, render_projects};  use macroblog::router::blog_post_exists;  use std::env; @@ -12,6 +12,15 @@ async fn index() -> impl Responder {          .body(body)  } +#[get("/projects")] +async fn projects() -> impl Responder { +    let body = render_projects(); + +    HttpResponse::Ok() +        .content_type(ContentType::html()) +        .body(body) +} +  #[get("/posts/{name}")]  async fn posts(name: web::Path<String>) -> impl Responder { @@ -36,6 +45,7 @@ async fn main() -> std::io::Result<()> {          App::new()              .wrap(middleware::Compress::default())              .service(index) +            .service(projects)              .service(posts)      })      .bind(("0.0.0.0", port))? diff --git a/src/bin/hyper.rs b/src/bin/hyper.rs index 3f23f18..f24cbe4 100644 --- a/src/bin/hyper.rs +++ b/src/bin/hyper.rs @@ -1,11 +1,10 @@ -use std::convert::Infallible; -use std::{env}; -use std::net::SocketAddr; -use hyper::{Body, Request, Response, Server};  use hyper::service::{make_service_fn, service_fn}; +use hyper::{Body, Request, Response, Server}; +use macroblog::blog::{render_index_page, render_post_page, render_projects};  use macroblog::router::Router; -use macroblog::blog::{render_index_page, render_post_page}; - +use std::convert::Infallible; +use std::env; +use std::net::SocketAddr;  async fn not_found() -> Result<Response<Body>, Infallible> {      let resp: Response<Body> = Response::builder() @@ -15,7 +14,6 @@ async fn not_found() -> Result<Response<Body>, Infallible> {      Ok(resp)  } -  async fn index() -> Result<Response<Body>, Infallible> {      let body = render_index_page(); @@ -28,6 +26,17 @@ async fn index() -> Result<Response<Body>, Infallible> {      Ok(resp)  } +async fn projects() -> Result<Response<Body>, Infallible> { +    let body = render_projects(); + +    let resp: Response<Body> = Response::builder() +        .status(200) +        .header("posts-type", "text/html") +        .body(body.into()) +        .unwrap(); + +    Ok(resp) +}  async fn post(path: &String) -> Result<Response<Body>, Infallible> {      let body = render_post_page(path); @@ -46,20 +55,21 @@ async fn request(req: Request<Body>) -> Result<Response<Body>, Infallible> {      match Router::new(path) {          Router::Index => index().await, +        Router::Projects => projects().await,          Router::Post { page } => post(&page).await, -        Router::NotFound => not_found().await +        Router::NotFound => not_found().await,      }  } -  #[tokio::main]  async fn main() { -    let port = env::var("PORT").unwrap_or("3000".into()).parse::<u16>().unwrap_or(3000); +    let port = env::var("PORT") +        .unwrap_or("3000".into()) +        .parse::<u16>() +        .unwrap_or(3000);      let addr = SocketAddr::from(([0, 0, 0, 0], port)); -    let make_svc = make_service_fn(|_conn| async { -        Ok::<_, Infallible>(service_fn(request)) -    }); +    let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(request)) });      let server = Server::bind(&addr).serve(make_svc); diff --git a/src/blog.rs b/src/blog.rs index a1586f8..8c3af52 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -1,8 +1,7 @@ +use crate::assets::{BlogEntry, IndexTemplate, PostAsset, PostTemplate, ProjectsAsset, ProjectsTemplate};  use pulldown_cmark::{html, Options, Parser};  use sailfish::TemplateOnce;  use std::str; -use crate::assets::{BlogEntry, PostAsset, IndexTemplate, PostTemplate}; -  pub fn read_assets() -> Vec<BlogEntry> {      let mut entries: Vec<BlogEntry> = PostAsset::iter() @@ -26,6 +25,24 @@ fn get_file_content(path: &str) -> String {      return html_output.to_string();  } +fn get_projects_content() -> String { +    let buffer = ProjectsAsset::get("index.md").unwrap().data.into_owned(); +    let md = String::from_utf8(buffer).unwrap(); +    let mut options = Options::empty(); +    options.insert(Options::ENABLE_FOOTNOTES); +    let parser = Parser::new_ext(&md, options); +    let mut html_output = &mut String::new(); +    html::push_html(&mut html_output, parser); +    return html_output.to_string(); +} + +pub fn render_projects() -> String { +    ProjectsTemplate { +        content: get_projects_content(), +    } +    .render_once() +    .unwrap() +}  pub fn render_post_page(path: &String) -> String {      let blog = BlogEntry::new(path); diff --git a/src/router.rs b/src/router.rs index 3227d66..c5efd9c 100644 --- a/src/router.rs +++ b/src/router.rs @@ -1,11 +1,12 @@  use crate::assets::PostAsset;  use regex::Regex; -const ACTION_REGEX: &str = r"/{0,1}(?P<action>\w*)/(?P<id>.+)"; +const ACTION_REGEX: &str = r"/{0,1}(?P<action>\w*)/{0,1}(?P<id>.*)";  pub enum Router {      NotFound,      Index, +    Projects,      Post { page: String },  } @@ -17,11 +18,14 @@ impl Router {      pub fn new(path: &str) -> Router {          let re = Regex::new(ACTION_REGEX).unwrap();          let caps = re.captures(path); -        let action = match caps { +        let mut action = match caps {              Some(ref value) => &value["action"],              None => "index",          }; +        if action == "" { +            action = "index" +        }          // this 7 means the "/posts/" from the full path          let trimmed_path: String = path.chars().skip(7).collect(); @@ -33,6 +37,7 @@ impl Router {              "posts" => Router::Post {                  page: caps.unwrap()["id"].to_string(),              }, +            "projects" => Router::Projects,              "index" => Router::Index,              _ => Router::NotFound,          } diff --git a/templates/header.html b/templates/header.html index c830273..b81a09e 100644 --- a/templates/header.html +++ b/templates/header.html @@ -5,6 +5,7 @@          </a>          <nav class="container-fluid">              <ul> +                <li><a href="/projects" class="secondary">Projects</a></li>                  <li><a href="https://gitlab.com/gabrielgio/cv/-/raw/main/cv.pdf?inline=false" class="secondary">Resume</a></li>              </ul>          </nav> diff --git a/templates/projects.html b/templates/projects.html new file mode 100644 index 0000000..9aff1a6 --- /dev/null +++ b/templates/projects.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html data-theme="light" lang="en"> +    <head> +        <% include!("head.html"); %> +    </head> +    <body> +        <div class="layout"> +            <% include!("header.html"); %> +            <%- content %> +        </div> +    </body> +</html> diff --git a/tests/test_router.rs b/tests/test_router.rs index cfd4c32..97f344c 100644 --- a/tests/test_router.rs +++ b/tests/test_router.rs @@ -5,15 +5,28 @@ fn test_router_new_posts() {      match Router::new("/posts/2021-12-26Enable_NFS_on_K3S.md") {          Router::NotFound => assert!(false, "Wrong type parse"),          Router::Index => assert!(false, "Wrong type parse"), +        Router::Projects => assert!(false, "Wrong type parse"),          Router::Post { page } => assert_eq!(page, "2021-12-26Enable_NFS_on_K3S.md".to_string()),      };  } + +#[test] +fn test_router_projects() { +    match Router::new("/projects") { +        Router::NotFound => assert!(false, "Wrong type parse"), +        Router::Index => assert!(false, "Wrong type parse"), +        Router::Projects => assert!(true), +        Router::Post { page: _ } => assert!(false, "Wrong type parse"), +    }; +} +  #[test]  fn test_router_new_index() {      match Router::new("/") {          Router::Index => assert!(true),          Router::NotFound => assert!(false, "Wrong type parse"), +        Router::Projects => assert!(false, "Wrong type parse"),          Router::Post { page: _ } => assert!(false, "Wrong type parse"),      };  } @@ -23,6 +36,7 @@ fn test_router_new_not_found() {      match Router::new("/not_found") {          Router::NotFound => assert!(true),          Router::Index => assert!(false, "Wrong type parse"), +        Router::Projects => assert!(false, "Wrong type parse"),          Router::Post { page: _ } => assert!(false, "Wrong type parse"),      };  } @@ -32,6 +46,7 @@ fn test_router_new_not_found_matching_regex() {      match Router::new("/posts/2021-12-03Enable_NFS_on_K3S.html") {          Router::NotFound => assert!(true),          Router::Index => assert!(false, "Wrong type parse"), +        Router::Projects => assert!(false, "Wrong type parse"),          Router::Post { page: _ } => assert!(false, "Wrong type parse"),      };  } @@ -4,7 +4,10 @@ case $1 in    actix)      cargo watch -x "run --bin actix"      ;; -  *) +  hyper)      cargo watch -x "run --bin hyper"      ;; +  *) +    cargo watch -x "test" +    ;;  esac | 
