268 lines
6.6 KiB
Rust
268 lines
6.6 KiB
Rust
use std::fs;
|
|
use std::fs::File;
|
|
use std::path::Path;
|
|
|
|
extern crate tera;
|
|
use tera::{
|
|
Context,
|
|
Tera,
|
|
};
|
|
|
|
use serde::{
|
|
Deserialize,
|
|
Serialize,
|
|
};
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
struct SVGConfig {
|
|
svgs: Vec<SVGMetadata>,
|
|
}
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
struct SVGMetadata {
|
|
template: String,
|
|
title: String,
|
|
description: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
struct Post {
|
|
full_url: Option<String>,
|
|
url: String,
|
|
title: String,
|
|
summary: String,
|
|
date_published: String,
|
|
date_modified: Option<String>,
|
|
template_name: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
struct Project {
|
|
full_url: Option<String>,
|
|
url: String,
|
|
title: String,
|
|
image: String,
|
|
summary: String,
|
|
template_name: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
struct Config {
|
|
posts: Vec<Post>,
|
|
tech_demos: Vec<Project>,
|
|
projects: Vec<Project>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
struct MyContext {
|
|
title: String,
|
|
description: String,
|
|
canonical_url: String,
|
|
favicon_image: String,
|
|
page_image: String,
|
|
|
|
og_type: String,
|
|
og_locale: String,
|
|
og_site_name: String,
|
|
|
|
twitter_card: String,
|
|
|
|
posts: Vec<Post>,
|
|
tech_demos: Vec<Project>,
|
|
projects: Vec<Project>,
|
|
}
|
|
impl Default for MyContext {
|
|
fn default() -> Self {
|
|
Self {
|
|
title: "chmod777's homepage".to_owned(),
|
|
description: "A place where chmod777 puts their blog posts, project updates, and tech demos.".to_owned(),
|
|
canonical_url: "http://tilde.club/~chmod777".to_owned(),
|
|
favicon_image: "http://tilde.club/~chmod777/favicon.svg".to_owned(),
|
|
page_image: "http://tilde.club/~chmod777/favicon.svg".to_owned(),
|
|
og_type: "website".to_owned(),
|
|
og_locale: "en-US".to_owned(),
|
|
og_site_name: "tilde.club".to_owned(),
|
|
twitter_card: "summary".to_owned(),
|
|
posts: Vec::new(),
|
|
tech_demos: Vec::new(),
|
|
projects: Vec::new(),
|
|
}
|
|
}
|
|
}
|
|
fn get_file(path: &str) -> File {
|
|
let path = Path::new(path);
|
|
let display = path.display();
|
|
match File::create(path) {
|
|
Ok(file) => file,
|
|
Err(error) => panic!("Couldn't create file {}: {}", &display, &error),
|
|
}
|
|
}
|
|
fn read_file(path: &str) -> String {
|
|
fs::read_to_string(path).expect(&format!("Failed to read file: {}", path))
|
|
}
|
|
fn append_str(base: &str, extend: &str) -> String {
|
|
let mut s = base.to_owned();
|
|
s.push_str(extend);
|
|
s
|
|
}
|
|
fn main() {
|
|
{
|
|
fs::copy("ts/src/base.ts", "public/ts/base.ts").unwrap();
|
|
fs::copy("ts/src/pong.ts", "public/ts/pong.ts").unwrap();
|
|
}
|
|
|
|
{
|
|
let svg_tera = match Tera::new("svg_templates/**/*") {
|
|
Ok(tera) => tera,
|
|
Err(error_s) => panic!("Parsing error(s): {}", error_s),
|
|
};
|
|
|
|
let svg_config_json_string = read_file("svg_config.json");
|
|
let svg_config: SVGConfig =
|
|
serde_json::from_str(&svg_config_json_string).unwrap();
|
|
|
|
for metadata in svg_config.svgs.iter() {
|
|
let temp_path = append_str("templates/svg/", &metadata.template);
|
|
let path = append_str("public/assets/svg/", &metadata.template);
|
|
|
|
svg_tera
|
|
.render_to(
|
|
&metadata.template,
|
|
&Context::from_serialize(&metadata).unwrap(),
|
|
get_file(&temp_path),
|
|
)
|
|
.unwrap();
|
|
|
|
fs::copy(temp_path, path).unwrap();
|
|
}
|
|
}
|
|
|
|
let tera = match Tera::new("templates/**/*") {
|
|
Ok(tera) => tera,
|
|
Err(error_s) => panic!("Parsing error(s): {}", error_s),
|
|
};
|
|
|
|
let config_json_string = read_file("config.json");
|
|
let config: Config = serde_json::from_str(&config_json_string).unwrap();
|
|
|
|
let mut context = MyContext::default();
|
|
|
|
let base_url = "http://tilde.club/~chmod777";
|
|
for mut post in config.posts.iter().cloned() {
|
|
post.full_url = Some(append_str(base_url, &post.url));
|
|
context.posts.push(post);
|
|
}
|
|
for mut demo in config.tech_demos.iter().cloned() {
|
|
demo.full_url = Some(append_str(base_url, &demo.url));
|
|
context.tech_demos.push(demo)
|
|
}
|
|
for mut project in config.projects.iter().cloned() {
|
|
project.full_url = Some(append_str(base_url, &project.url));
|
|
context.projects.push(project);
|
|
}
|
|
|
|
tera.render_to(
|
|
"index.html",
|
|
&Context::from_serialize(&context).unwrap(),
|
|
get_file("public/index.html"),
|
|
)
|
|
.unwrap();
|
|
|
|
{
|
|
context.title = "About JavaScript".to_owned();
|
|
context.canonical_url =
|
|
"http://tilde.club/~chmod777/about/javascript.html".to_owned();
|
|
let blog_context = Context::from_serialize(&context).unwrap();
|
|
tera.render_to(
|
|
"javascript.html",
|
|
&blog_context,
|
|
get_file("public/about/javascript.html"),
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
{
|
|
context.title = "chmod777's blog".to_owned();
|
|
context.canonical_url =
|
|
"http://tilde.club/~chmod777/blog/blog.html".to_owned();
|
|
let blog_context = Context::from_serialize(&context).unwrap();
|
|
tera.render_to(
|
|
"blog/blog.html",
|
|
&blog_context,
|
|
get_file("public/blog/blog.html"),
|
|
)
|
|
.unwrap();
|
|
|
|
tera.render_to("feed.rss", &blog_context, get_file("public/feed.rss"))
|
|
.unwrap();
|
|
|
|
context.og_type = "article".to_owned();
|
|
for post in context.posts.iter() {
|
|
context.canonical_url = post.full_url.clone().unwrap();
|
|
context.description = post.summary.clone();
|
|
|
|
let path = append_str("public", &post.url);
|
|
tera.render_to(
|
|
&post.template_name,
|
|
&Context::from_serialize(&context).unwrap(),
|
|
get_file(&path),
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|
|
|
|
{
|
|
context.title = "chmod777's projects".to_owned();
|
|
context.og_type = "website".to_owned();
|
|
context.canonical_url =
|
|
"http://tilde.club/~chmod777/projects/projects.html".to_owned();
|
|
context.description = "".to_owned();
|
|
|
|
tera.render_to(
|
|
"projects/projects.html",
|
|
&Context::from_serialize(&context).unwrap(),
|
|
get_file("public/projects/projects.html"),
|
|
)
|
|
.unwrap();
|
|
|
|
for project in context.projects.iter() {
|
|
context.canonical_url = project.full_url.clone().unwrap();
|
|
context.description = project.summary.clone();
|
|
|
|
let path = append_str("public", &project.url);
|
|
tera.render_to(
|
|
&project.template_name,
|
|
&Context::from_serialize(&context).unwrap(),
|
|
get_file(&path),
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|
|
|
|
{
|
|
context.title = "chmod777's tech demos".to_owned();
|
|
context.canonical_url =
|
|
"http://tilde.club/~chmod777/tech_demos/tech_demos.html".to_owned();
|
|
context.description = "".to_owned();
|
|
|
|
tera.render_to(
|
|
"tech_demos/tech_demos.html",
|
|
&Context::from_serialize(&context).unwrap(),
|
|
get_file("public/tech_demos/tech_demos.html"),
|
|
)
|
|
.unwrap();
|
|
|
|
for demo in context.tech_demos.iter() {
|
|
context.canonical_url = demo.full_url.clone().unwrap();
|
|
context.description = demo.summary.clone();
|
|
|
|
let path = append_str("public", &demo.url);
|
|
|
|
tera.render_to(
|
|
&demo.template_name,
|
|
&Context::from_serialize(&context).unwrap(),
|
|
get_file(&path),
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|
|
}
|