Added logger, error and builder
This commit is contained in:
parent
f40ee315f9
commit
a21e689a6f
@ -4,13 +4,13 @@ built_pages = ["test_page.toml"]
|
|||||||
use_default_css = true
|
use_default_css = true
|
||||||
javascript = []
|
javascript = []
|
||||||
css = []
|
css = []
|
||||||
#favicon = "path.png"
|
#favicon = "favicon.png"
|
||||||
#twitter_author = "@teascade"
|
#twitter_author = "@teascade"
|
||||||
#google_robots = "all"
|
#google_robots = "all"
|
||||||
#google_site_verification = ""
|
#google_site_verification = ""
|
||||||
|
|
||||||
[navbar]
|
[navbar]
|
||||||
items = ["home", "potato", "games"]
|
items = ["home", "games"]
|
||||||
|
|
||||||
[navbar.item.home]
|
[navbar.item.home]
|
||||||
title = "Home"
|
title = "Home"
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
:root {
|
|
||||||
--color-main-bg: rgb(38, 40, 43);
|
|
||||||
|
|
||||||
--color-navbar-bg: rgb(52, 52, 56);
|
|
||||||
--color-navbar-button: rgb(50, 50, 53);
|
|
||||||
--color-navbar-button-hover: rgb(43, 43, 46);
|
|
||||||
--color-navbar-button-focus: rgb(44, 44, 48);
|
|
||||||
--color-navbar-border-bottom: rgb(41, 41, 44);
|
|
||||||
|
|
||||||
--color-content-bg: rgb(44, 44, 48);
|
|
||||||
--color-content-fg: rgb(164, 161, 172);
|
|
||||||
|
|
||||||
--navbar-height: 3.5vw;
|
|
||||||
--navbar-width: 60%;
|
|
||||||
--navbar-padding-size: 0.5em;
|
|
||||||
--navbar-text-size: 24px;
|
|
||||||
|
|
||||||
--content-width: 50%;
|
|
||||||
--content-text-size: 1.2em;
|
|
||||||
--content-top-padding: 2em;
|
|
||||||
--content-side-padding: 2em;
|
|
||||||
|
|
||||||
--highlight-color: rgb(230, 134, 217);
|
|
||||||
}
|
|
||||||
|
|
||||||
body, html {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-family: Roboto, Helvetica, sans-serif;
|
|
||||||
background-color: var(--color-main-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#text {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navbar styles */
|
|
||||||
|
|
||||||
nav {
|
|
||||||
width: 100%;
|
|
||||||
height: var(--navbar-height);
|
|
||||||
background-color: var(--color-navbar-bg);
|
|
||||||
border-bottom: solid 4px var(--color-navbar-border-bottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul {
|
|
||||||
height: 100%;
|
|
||||||
font-size: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
width: var(--navbar-width);
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav li {
|
|
||||||
height: 100%;
|
|
||||||
font-size: var(--navbar-text-size);
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav li a {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
background-color: var(--color-navbar-button);
|
|
||||||
color: var(--highlight-color);
|
|
||||||
text-decoration: none;
|
|
||||||
padding-left: var(--navbar-padding-size);
|
|
||||||
padding-right: var(--navbar-padding-size);
|
|
||||||
transition: 0.15s;
|
|
||||||
border-left: solid 3px var(--color-navbar-button-hover);
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
nav li:not(.image) a {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav li:first-child a {
|
|
||||||
border-left: solid 5px var(--color-navbar-button-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav li:last-child a {
|
|
||||||
border-right: solid 5px var(--color-navbar-button-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul a:hover {
|
|
||||||
background-color: var(--color-navbar-button-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav ul a:focus {
|
|
||||||
outline: none;
|
|
||||||
background-color: var(--color-navbar-button-focus);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navbar images */
|
|
||||||
|
|
||||||
nav img {
|
|
||||||
height: var(--navbar-height);
|
|
||||||
vertical-align: top;
|
|
||||||
border: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav li.image {
|
|
||||||
position: relative;
|
|
||||||
bottom: calc(var(--navbar-height) / 4);
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav li.image a {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Article styles */
|
|
||||||
|
|
||||||
article {
|
|
||||||
width: var(--content-width);
|
|
||||||
min-height: calc(100% - var(--navbar-height) - var(--content-top-padding) - 4px);
|
|
||||||
margin: auto;
|
|
||||||
padding-top: var(--content-top-padding);
|
|
||||||
padding-left: var(--content-side-padding);
|
|
||||||
padding-right: var(--content-side-padding);
|
|
||||||
background-color: var(--color-content-bg);
|
|
||||||
color: var(--color-content-fg);
|
|
||||||
font-size: var(--content-text-size);
|
|
||||||
}
|
|
||||||
|
|
||||||
article > * {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
article a {
|
|
||||||
color: var(--highlight-color);
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 16 KiB |
@ -1,62 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<meta name="description" content="">
|
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<meta name="robots" content="">
|
|
||||||
<meta name="google-site-verification" content="" />
|
|
||||||
|
|
||||||
<meta name="title" content="Test Website Name!">
|
|
||||||
<meta property="og:title" content="Test Page">
|
|
||||||
<meta property="og:site_name" content="Test Website Name!">
|
|
||||||
<meta property="og:type" content="website">
|
|
||||||
<meta property="og:description" content="">
|
|
||||||
<meta property="og:image" content="">
|
|
||||||
<meta property="og:image:secure_url" content="">
|
|
||||||
<meta property="og:image:type" content="image/png">
|
|
||||||
<meta property="og:image:width" content="512">
|
|
||||||
<meta property="og:image:height" content="512">
|
|
||||||
|
|
||||||
<meta name="twitter:site" content="">
|
|
||||||
<meta name="twitter:creator" content="">
|
|
||||||
<meta name="twitter:title" content="Test Page">
|
|
||||||
<meta name="twitter:description" content="">
|
|
||||||
<meta name="twitter:image" content="">
|
|
||||||
<link rel="stylesheet" href="css/default.css">
|
|
||||||
|
|
||||||
<link rel="shortcut icon" href=""></link>
|
|
||||||
|
|
||||||
<title>Test Page</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<nav>
|
|
||||||
<ul>
|
|
||||||
<li class="image">
|
|
||||||
<a href="home">
|
|
||||||
<img src="img/teascade.png" alt="Home">
|
|
||||||
</img>
|
|
||||||
</a>
|
|
||||||
</li><li class="image">
|
|
||||||
<a href="home">
|
|
||||||
<img src="img/teascade.png" alt="Home">
|
|
||||||
</img>
|
|
||||||
</a>
|
|
||||||
</li><li>
|
|
||||||
<a href="games">Games</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<article>
|
|
||||||
<h1>Test Header!</h1>
|
|
||||||
<p>Some test content!</p>
|
|
||||||
|
|
||||||
</article>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
90
src/builder.rs
Normal file
90
src/builder.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use config::Config;
|
||||||
|
use template::Template;
|
||||||
|
use renderer;
|
||||||
|
use logger::{LogLevel, Logger};
|
||||||
|
use error::Error;
|
||||||
|
|
||||||
|
use std::fs::{create_dir_all, File};
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css");
|
||||||
|
const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html");
|
||||||
|
const NAVBAR_ITEM: &'static str = include_str!("templates/navbar/item-template.html");
|
||||||
|
const NAVBAR_IMAGE_ITEM: &'static str = include_str!("templates/navbar/image-item-template.html");
|
||||||
|
|
||||||
|
fn fetch_config() -> Result<Config, Error> {
|
||||||
|
match Config::new() {
|
||||||
|
Ok(config) => Ok(config),
|
||||||
|
Err(err) => Err(Error::from(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_file<T: Into<String>, U: Into<String>>(path_str: T, content: U) -> Result<(), Error> {
|
||||||
|
let path_str = path_str.into();
|
||||||
|
let content = content.into();
|
||||||
|
|
||||||
|
let path = Path::new(&path_str);
|
||||||
|
if let Some(parent) = path.parent() {
|
||||||
|
create_dir_all(parent)?;
|
||||||
|
} else {
|
||||||
|
return Err(Error::new(
|
||||||
|
LogLevel::SEVERE,
|
||||||
|
format!("Could not find parent folder for {}", path_str),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if path.exists() {
|
||||||
|
Err(Error::new(
|
||||||
|
LogLevel::SEVERE,
|
||||||
|
format!(
|
||||||
|
"File already exists: {} -- Consider using overwrite-flag",
|
||||||
|
path_str
|
||||||
|
),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
match File::create(path) {
|
||||||
|
Ok(mut file) => Ok(file.write_all(content.as_bytes()).unwrap()),
|
||||||
|
Err(err) => Err(Error::from(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(logger: &Logger) -> Result<(), Error> {
|
||||||
|
logger.log(LogLevel::INFO, "Starting build");
|
||||||
|
let config = fetch_config()?;
|
||||||
|
|
||||||
|
if config.global_config.website.use_default_css {
|
||||||
|
logger.log(LogLevel::DETAIL, "Adding public/css/default.css");
|
||||||
|
write_file("public/css/default.css", DEFAULT_CSS)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(LogLevel::INFO, "Generating page templates");
|
||||||
|
let page_template = Template::new(PAGE_TEMPLATE);
|
||||||
|
|
||||||
|
let mut navbar_content = String::new();
|
||||||
|
if config.global_config.navbar.is_some() {
|
||||||
|
let navbar_item_template = Template::new(NAVBAR_ITEM);
|
||||||
|
let navbar_image_item_template = Template::new(NAVBAR_IMAGE_ITEM);
|
||||||
|
logger.log(LogLevel::DETAIL, "Rendering Navbar");
|
||||||
|
navbar_content =
|
||||||
|
renderer::render_navbar(&config, navbar_item_template, navbar_image_item_template)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.log(LogLevel::INFO, "Rendering");
|
||||||
|
logger.log(LogLevel::DETAILER, "Rendering public/test.html");
|
||||||
|
let rendered = match config.get_configs_for(0) {
|
||||||
|
Ok(page_config) => page_template.render(&Template::page_data_from(
|
||||||
|
page_config.clone(),
|
||||||
|
navbar_content,
|
||||||
|
renderer::render_markdown_content(&page_config).unwrap(),
|
||||||
|
)),
|
||||||
|
Err(err) => panic!(err),
|
||||||
|
};
|
||||||
|
|
||||||
|
logger.log(LogLevel::INFO, "Writing");
|
||||||
|
logger.log(LogLevel::DETAILER, "Writing public/test.html");
|
||||||
|
write_file("public/test.html", rendered)?;
|
||||||
|
|
||||||
|
logger.log(LogLevel::INFO, "Done!");
|
||||||
|
Ok(())
|
||||||
|
}
|
36
src/error.rs
Normal file
36
src/error.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
use std::convert::From;
|
||||||
|
use std::io::Error as IOError;
|
||||||
|
use std::error::Error as STDError;
|
||||||
|
|
||||||
|
use logger::LogLevel;
|
||||||
|
|
||||||
|
pub struct Error {
|
||||||
|
description: String,
|
||||||
|
severity: LogLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn new<T: Into<String>>(severity: LogLevel, description: T) -> Error {
|
||||||
|
Error {
|
||||||
|
severity,
|
||||||
|
description: description.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> String {
|
||||||
|
self.description.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn severity(&self) -> LogLevel {
|
||||||
|
self.severity.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IOError> for Error {
|
||||||
|
fn from(err: IOError) -> Error {
|
||||||
|
Error {
|
||||||
|
description: err.description().to_owned(),
|
||||||
|
severity: LogLevel::SEVERE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
src/logger.rs
Normal file
31
src/logger.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
pub struct Logger {
|
||||||
|
log_level: LogLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Logger {
|
||||||
|
pub fn new(log_level: LogLevel) -> Logger {
|
||||||
|
Logger { log_level }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log<T: Into<String>>(&self, log_level: LogLevel, message: T) {
|
||||||
|
if self.log_level.clone() as i32 >= log_level.clone() as i32 {
|
||||||
|
match log_level {
|
||||||
|
LogLevel::SEVERE => eprintln!("[SEVERE]: {}", message.into()),
|
||||||
|
LogLevel::INFO => println!("[INFO]: {}", message.into()),
|
||||||
|
LogLevel::WARNING => eprintln!("[WARNING]: {}", message.into()),
|
||||||
|
LogLevel::DETAIL => println!("[DETAIL]: {}", message.into()),
|
||||||
|
LogLevel::DETAILER => println!("[DETAILER]: {}", message.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum LogLevel {
|
||||||
|
SEVERE = 0,
|
||||||
|
INFO = 1,
|
||||||
|
WARNING = 2, // Default
|
||||||
|
DETAIL = 3,
|
||||||
|
DETAILER = 4,
|
||||||
|
}
|
61
src/main.rs
61
src/main.rs
@ -4,65 +4,24 @@ extern crate regex;
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
extern crate toml;
|
extern crate toml;
|
||||||
|
|
||||||
|
mod logger;
|
||||||
|
mod error;
|
||||||
mod config_toml;
|
mod config_toml;
|
||||||
mod config;
|
mod config;
|
||||||
mod template;
|
mod template;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
mod builder;
|
||||||
|
|
||||||
use config::Config;
|
use logger::{LogLevel, Logger};
|
||||||
use template::Template;
|
|
||||||
|
|
||||||
use std::error::Error;
|
|
||||||
use std::fs::{create_dir_all, File};
|
|
||||||
use std::io::prelude::*;
|
|
||||||
|
|
||||||
const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css");
|
|
||||||
const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html");
|
|
||||||
const NAVBAR_ITEM: &'static str = include_str!("templates/navbar/item-template.html");
|
|
||||||
const NAVBAR_IMAGE_ITEM: &'static str = include_str!("templates/navbar/image-item-template.html");
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Fetching configs");
|
let logger = Logger::new(LogLevel::DETAILER);
|
||||||
let config = match Config::new() {
|
|
||||||
Ok(config) => config,
|
|
||||||
Err(err) => panic!(err.description().to_owned()),
|
|
||||||
};
|
|
||||||
|
|
||||||
if config.global_config.website.use_default_css {
|
match builder::build(&logger) {
|
||||||
println!("Adding public/css/default.css");
|
Ok(_) => logger.log(LogLevel::DETAILER, "Building finished successfully."),
|
||||||
create_dir_all("public/css").ok();
|
Err(err) => {
|
||||||
let mut file = File::create("public/css/default.css").unwrap();
|
logger.log(err.severity(), err.description());
|
||||||
file.write_all(DEFAULT_CSS.as_bytes()).ok();
|
logger.log(LogLevel::SEVERE, "Aborting building due to error.");
|
||||||
}
|
|
||||||
|
|
||||||
println!("Generating page templates");
|
|
||||||
let page_template = Template::new(PAGE_TEMPLATE);
|
|
||||||
|
|
||||||
let mut navbar_content = String::new();
|
|
||||||
if config.global_config.navbar.is_some() {
|
|
||||||
let navbar_item_template = Template::new(NAVBAR_ITEM);
|
|
||||||
let navbar_image_item_template = Template::new(NAVBAR_IMAGE_ITEM);
|
|
||||||
println!("Rendering navbar");
|
|
||||||
match renderer::render_navbar(&config, navbar_item_template, navbar_image_item_template) {
|
|
||||||
Ok(navbar) => navbar_content = navbar,
|
|
||||||
Err(err) => panic!(err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Rendering public/test.html");
|
|
||||||
let rendered = match config.get_configs_for(0) {
|
|
||||||
Ok(page_config) => page_template.render(&Template::page_data_from(
|
|
||||||
page_config.clone(),
|
|
||||||
navbar_content,
|
|
||||||
renderer::render_markdown_content(&page_config).unwrap(),
|
|
||||||
)),
|
|
||||||
Err(err) => panic!(err),
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("Writing public/test.html");
|
|
||||||
create_dir_all("public").ok();
|
|
||||||
let mut file = File::create("public/test.html").unwrap();
|
|
||||||
file.write_all(rendered.as_bytes()).ok();
|
|
||||||
|
|
||||||
println!("Done!");
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ use pulldown_cmark::{html, Parser};
|
|||||||
|
|
||||||
use config::{Config, SinglePageConfigs};
|
use config::{Config, SinglePageConfigs};
|
||||||
use template::Template;
|
use template::Template;
|
||||||
|
use error::Error;
|
||||||
|
use logger::LogLevel;
|
||||||
|
|
||||||
pub fn render_markdown_content(config: &SinglePageConfigs) -> Result<String, String> {
|
pub fn render_markdown_content(config: &SinglePageConfigs) -> Result<String, String> {
|
||||||
if let Some(parent) = config.page_config_path.parent() {
|
if let Some(parent) = config.page_config_path.parent() {
|
||||||
@ -33,7 +35,7 @@ pub fn render_navbar(
|
|||||||
config: &Config,
|
config: &Config,
|
||||||
item_template: Template,
|
item_template: Template,
|
||||||
image_item_template: Template,
|
image_item_template: Template,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, Error> {
|
||||||
let mut navbar_str = String::new();
|
let mut navbar_str = String::new();
|
||||||
|
|
||||||
if let Some(navbar) = config.global_config.navbar.clone() {
|
if let Some(navbar) = config.global_config.navbar.clone() {
|
||||||
@ -46,14 +48,17 @@ pub fn render_navbar(
|
|||||||
navbar_str += &*item_template.render(&data);
|
navbar_str += &*item_template.render(&data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(Error::new(
|
||||||
"Navbar item does not exist: navbar.item.{}",
|
LogLevel::SEVERE,
|
||||||
item_str
|
format!("Navbar item does not exist: navbar.item.{}", item_str),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(navbar_str)
|
Ok(navbar_str)
|
||||||
} else {
|
} else {
|
||||||
Err("Attempted to render navbar without navbar".to_owned())
|
Err(Error::new(
|
||||||
|
LogLevel::SEVERE,
|
||||||
|
"Attempted to render navbar without navbar".to_owned(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user