initial commit
This commit is contained in:
commit
6c1c2fc043
11 changed files with 3112 additions and 0 deletions
102
src/main.rs
Normal file
102
src/main.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#[macro_use]
|
||||
extern crate rocket;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use rocket::fs::NamedFile;
|
||||
use rocket_dyn_templates::{context, Template};
|
||||
use scraper::{Html, Selector};
|
||||
use serde::Serialize;
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
#[get("/")]
|
||||
fn serve_main() -> Template {
|
||||
Template::render(
|
||||
"index",
|
||||
context! {
|
||||
content: std::fs::read_to_string("data/pages/about.html").unwrap_or_else(|_| "Error loading about page.".to_string())
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/posts/<post_name>")]
|
||||
async fn serve_post(post_name: &str) -> Template {
|
||||
let file_path = Path::new("data/posts").join(format!("{}.html", post_name));
|
||||
let file_maybe = std::fs::read_to_string(file_path);
|
||||
let file = match file_maybe.ok() {
|
||||
Some(s) => s,
|
||||
None => "404: File not found.".to_string(),
|
||||
};
|
||||
Template::render(
|
||||
"index",
|
||||
context! {
|
||||
content: file
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/style/<file>")]
|
||||
async fn serve_css(file: &str) -> Option<NamedFile> {
|
||||
let file_path = Path::new("data/style").join(format!("{}", file));
|
||||
NamedFile::open(file_path).await.ok()
|
||||
}
|
||||
|
||||
#[get("/recent_posts")]
|
||||
fn list_recent_posts() -> Template {
|
||||
#[derive(Serialize)]
|
||||
struct Post {
|
||||
title: String,
|
||||
path: String,
|
||||
date: String,
|
||||
date_utc: DateTime<Utc>,
|
||||
}
|
||||
|
||||
let posts_dir = Path::new("data/posts");
|
||||
|
||||
let mut posts = Vec::new();
|
||||
if let Ok(entries) = std::fs::read_dir(posts_dir) {
|
||||
for entry in entries {
|
||||
if let Ok(entry) = entry {
|
||||
if let Some(file_name) = entry.file_name().to_str() {
|
||||
if file_name.ends_with(".html") {
|
||||
let file = match std::fs::read_to_string(posts_dir.join(file_name)) {
|
||||
Ok(s) => s,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let document = Html::parse_document(file.as_str());
|
||||
let mut tags: HashMap<&str, &str> = HashMap::new();
|
||||
for meta_tag in document.select(&Selector::parse("meta").unwrap()) {
|
||||
let name = meta_tag.value().attr("name").unwrap_or("");
|
||||
let content = meta_tag.value().attr("content").unwrap_or("");
|
||||
tags.insert(name, content);
|
||||
}
|
||||
let title = tags.get("title").unwrap_or(&"Untitled Post").to_string();
|
||||
let date_utc = tags
|
||||
.get("date")
|
||||
.and_then(|s_date| DateTime::parse_from_rfc3339(s_date).ok())
|
||||
.map(|dt| dt.with_timezone(&Utc))
|
||||
.unwrap_or_else(|| DateTime::from_timestamp(0, 0).unwrap());
|
||||
let date = date_utc.format("%d-%m-%Y").to_string();
|
||||
posts.push(Post {
|
||||
title,
|
||||
date_utc,
|
||||
date,
|
||||
path: format!("/posts/{}", file_name.trim_end_matches(".html")),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
posts.sort_by_key(|post| std::cmp::Reverse(post.date_utc));
|
||||
|
||||
Template::render("posts_list", context! { posts: posts })
|
||||
}
|
||||
|
||||
#[launch]
|
||||
fn rocket() -> _ {
|
||||
rocket::build()
|
||||
.mount("/", routes![serve_post, serve_main, serve_css, list_recent_posts])
|
||||
.attach(Template::fairing())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue