Make basic version of creating new page, also make file_write

This commit is contained in:
Sofia 2018-04-16 20:03:33 +03:00
parent 9e84a2454d
commit 739e68c58f
6 changed files with 110 additions and 49 deletions

28
config.example.toml Normal file
View File

@ -0,0 +1,28 @@
[website]
website_name = "Test Website Name!"
built_pages = ["test_page/about.toml", "test_page/other.toml"]
use_default_css = true
javascript = []
css = []
#before_navbar_url = "/navbar.html"
#before_content_url = "/before_content.html"
#after_content_url = "/after_content.html"
#favicon = "favicon.png"
#twitter_author = "@teascade"
#google_robots = "all"
#google_site_verification = ""
[navbar]
items = ["about", "other", "google"]
[navbar.item.about]
title = "About"
link = "/"
[navbar.item.other]
title = "Other"
link = "/other"
[navbar.item.google]
title = "Google!"
link = "https://google.com"

View File

@ -1,13 +1,12 @@
use std::path::PathBuf;
use config::Config; use config::Config;
use template::Template; use template::Template;
use renderer; use renderer;
use logger::{LogLevel, Logger}; use logger::{LogLevel, Logger};
use error::Error; use error::Error;
use options::BuildOps; use options::BuildOps;
use file_writer;
use std::fs::{create_dir_all, File};
use std::io::prelude::*;
use std::path::{Path, PathBuf};
const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css"); const DEFAULT_CSS: &'static str = include_str!("templates/default-css.css");
const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html"); const PAGE_TEMPLATE: &'static str = include_str!("templates/page-template.html");
@ -21,49 +20,14 @@ fn fetch_config() -> Result<Config, Error> {
} }
} }
fn write_file<T: Into<String>, U: Into<String>>(
path_str: T,
content: U,
overwrite: bool,
) -> Result<(), Error> {
let path_str = path_str.into();
let content = content.into();
let mut path = PathBuf::from(&path_str);
if let (Some(parent), Some(file_name)) = (path.clone().parent(), path.clone().file_name()) {
let parent = Path::new("public").join(parent);
create_dir_all(parent.clone())?;
path = parent.join(file_name);
} else {
return Err(Error::new(
LogLevel::SEVERE,
format!("Could not find parent folder or file name for {}", path_str),
));
}
if path.exists() && !overwrite {
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, ops: &BuildOps) -> Result<(), Error> { pub fn build(logger: &Logger, ops: &BuildOps) -> Result<(), Error> {
logger.log(LogLevel::INFO, "Starting build"); logger.log(LogLevel::INFO, "Starting build");
let config = fetch_config()?; let config = fetch_config()?;
if config.global_config.website.use_default_css { if config.global_config.website.use_default_css {
let css_path = "css/default.css"; let css_path = file_writer::add_to_beginning(PathBuf::from("css/default.css"), "public")?;
logger.log(LogLevel::DETAIL, format!("Adding public/{}", css_path)); logger.log(LogLevel::DETAIL, format!("Adding {:?}", css_path));
write_file(css_path, DEFAULT_CSS, ops.overwrite)?; file_writer::write_file(css_path, DEFAULT_CSS, ops.overwrite)?;
} }
logger.log(LogLevel::INFO, "Generating page templates"); logger.log(LogLevel::INFO, "Generating page templates");
@ -95,13 +59,14 @@ pub fn build(logger: &Logger, ops: &BuildOps) -> Result<(), Error> {
logger.log(LogLevel::INFO, "Writing"); logger.log(LogLevel::INFO, "Writing");
for (idx, config) in configs.clone().iter().enumerate() { for (idx, config) in configs.clone().iter().enumerate() {
let html_path = config.clone().page_config.page.html_path; let html_path = config.clone().page_config.page.html_path;
logger.log(LogLevel::DETAILER, format!("Writing public/{}", html_path)); let html_path = file_writer::add_to_beginning(PathBuf::from(html_path), "public")?;
logger.log(LogLevel::DETAILER, format!("Writing {:?}", html_path));
if let Some(render) = renders.get(idx) { if let Some(render) = renders.get(idx) {
write_file(html_path, render.clone(), ops.overwrite)?; file_writer::write_file(html_path, render.clone(), ops.overwrite)?;
} else { } else {
return Err(Error::new( return Err(Error::new(
LogLevel::SEVERE, LogLevel::SEVERE,
format!("Internal error; Render not found for file: {}", html_path), format!("Internal error; Render not found for file: {:?}", html_path),
)); ));
} }
} }

41
src/file_writer.rs Normal file
View File

@ -0,0 +1,41 @@
use std::fs::{create_dir_all, File};
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use error::Error;
use logger::LogLevel;
pub fn add_to_beginning<T: Into<String>>(path: PathBuf, to_add: T) -> Result<PathBuf, Error> {
if let (Some(parent), Some(file_name)) = (path.clone().parent(), path.clone().file_name()) {
let parent = Path::new(&to_add.into()).join(parent);
create_dir_all(parent.clone())?;
Ok(parent.join(file_name))
} else {
return Err(Error::new(
LogLevel::SEVERE,
format!("Could not find parent folder or file name for {:?}", path),
));
}
}
pub fn write_file<T: Into<String>>(
path: PathBuf,
content: T,
overwrite: bool,
) -> Result<(), Error> {
let content = content.into();
if path.exists() && !overwrite {
Err(Error::new(
LogLevel::SEVERE,
format!(
"File already exists: {:?} -- Consider using overwrite-flag",
path
),
))
} else {
match File::create(path) {
Ok(mut file) => Ok(file.write_all(content.as_bytes()).unwrap()),
Err(err) => Err(Error::from(err)),
}
}
}

View File

@ -14,6 +14,7 @@ mod config;
mod template; mod template;
mod renderer; mod renderer;
mod builder; mod builder;
mod file_writer;
use structopt::StructOpt; use structopt::StructOpt;
@ -27,13 +28,23 @@ fn main() {
let logger = Logger::new(LogLevel::from(log_level as u8)); let logger = Logger::new(LogLevel::from(log_level as u8));
match opt.cmd { match opt.cmd {
Subcommands::Build(build) => match builder::build(&logger, &build) { Subcommands::Build(ops) => match builder::build(&logger, &ops) {
Ok(_) => logger.log(LogLevel::DETAILER, "Building finished successfully."), Ok(_) => logger.log(LogLevel::DETAILER, "Building finished successfully."),
Err(err) => { Err(err) => {
logger.log(err.severity(), err.description()); logger.log(err.severity(), err.description());
logger.log(LogLevel::SEVERE, "Aborting building due to error."); logger.log(LogLevel::SEVERE, "Aborting building due to error.");
} }
}, },
Subcommands::NewPage => println!("Unsupported!"), Subcommands::New(ops) => {
logger.log(
LogLevel::DETAIL,
format!("Creating a new .toml file at {:?}", ops.toml_path),
);
match file_writer::write_file(ops.toml_path, "Hello!", ops.overwrite) {
Ok(_) => logger.log(LogLevel::INFO, "Done."),
Err(err) => logger.log(err.severity(), err.description()),
}
}
} }
} }

View File

@ -1,3 +1,5 @@
use std::path::PathBuf;
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug)]
#[structopt(name = "Teasca.de Generator", #[structopt(name = "Teasca.de Generator",
about = "A website generator, used mainly for generating teasca.de")] about = "A website generator, used mainly for generating teasca.de")]
@ -20,8 +22,8 @@ pub enum Subcommands {
#[structopt(name = "build")] #[structopt(name = "build")]
Build(BuildOps), Build(BuildOps),
/// Create a new page /// Create a new page
#[structopt(name = "new-page")] #[structopt(name = "new")]
NewPage, New(NewOps),
} }
#[derive(StructOpt, Debug)] #[derive(StructOpt, Debug)]
@ -30,3 +32,16 @@ pub struct BuildOps {
#[structopt(short = "o", long = "overwrite")] #[structopt(short = "o", long = "overwrite")]
pub overwrite: bool, pub overwrite: bool,
} }
#[derive(StructOpt, Debug)]
pub struct NewOps {
/// File path for the .toml file created
#[structopt(parse(from_os_str))]
pub toml_path: PathBuf,
/// File path for the markdown file created
#[structopt(short = "m", long = "markdown", parse(from_os_str))]
pub markdown_path: Option<PathBuf>,
/// Overwrites existing .toml / .md files
#[structopt(short = "o", long = "overwrite")]
pub overwrite: bool,
}

1
test_page/hello.toml Normal file
View File

@ -0,0 +1 @@
Hello!