Initial commit

pull/13/head
Anthony J. Martinez 3 years ago
commit a6e8d50730

1
.gitignore vendored

@ -0,0 +1 @@
/target

1575
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,20 @@
[package]
name = "caty_blog"
version = "0.1.0"
authors = ["Anthony Martinez", "Caty Christy"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = "2.33.3"
glob = "0.3.0"
tera = "1.7.0"
pulldown-cmark = { version = "0.8", default-features = false, features = ["simd"] }
tokio = { version = "1", features = ["full"] }
warp = "0.3"
[profile.release]
panic = "abort"
lto = true
opt-level = 'z'

@ -0,0 +1,25 @@
use caty_blog::*;
use warp::Filter;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// TODO: Load configuration file defining paths to stuff
// Load into memory as a Struct in an Arc(Mutex(something))
// This should also include the admin username/hash(password)
write_main(&render_main())?;
let static_files = warp::path("static")
.and(warp::fs::dir("webroot/static"));
let index = warp::get()
.and(warp::path::end())
.and(warp::fs::file("webroot/index.html"));
let routes = static_files.or(index);
warp::serve(routes).run(([127,0,0,1], 3030)).await;
Ok(())
}

@ -0,0 +1,86 @@
use std::fs::File;
use std::path::PathBuf;
use std::io::prelude::*;
use clap::{App, Arg};
use glob::glob;
use pulldown_cmark::{Parser, html};
use tera::{Tera, Context};
// Todo expand parsing to include a path for loading config
pub fn parse_args() -> String {
let mut pat_string = String::new();
let matches = App::new("Make Blog Posts")
.version("1.0")
.author("Anthony Martinez")
.about("I made it of course it rocks")
.arg(Arg::with_name("glob_pattern")
.short("p")
.long("--pattern")
.help("Provides the input file glob pattern")
.takes_value(true)
.required(true))
.get_matches();
if let Some(pattern) = matches.value_of("glob_pattern") {
pat_string = String::from(pattern);
}
pat_string
}
pub fn path_matches(pat: &str) -> Vec<PathBuf> {
let mut path_vec: Vec<PathBuf> = Vec::new();
for path in glob(pat).unwrap().filter_map(Result::ok) {
path_vec.push(path)
}
path_vec
}
pub fn read_to_html(paths: Vec<PathBuf>) -> Vec<String> {
let mut contents: Vec<String> = Vec::new();
for path in paths {
let buffer = std::fs::read_to_string(path).unwrap();
let parser = Parser::new(&buffer);
let mut html_output = String::new();
html::push_html(&mut html_output, parser);
contents.push(html_output);
}
contents
}
pub fn load_templates(dir: &str) -> Tera {
match Tera::new(dir) {
Ok(t) => t,
Err(e) => panic!("Failed with {}", e)
}
}
pub fn render_main() -> String {
let pattern = parse_args();
let path_vec = path_matches(&pattern);
let mut data = read_to_html(path_vec);
data.reverse();
let tera = load_templates("templates/*.tmpl");
let mut context = Context::new();
context.insert("posts", &data);
let output = tera.render("main.tmpl", &context);
if let Ok(output) = output {
output
} else {
String::new()
}
}
pub fn write_main(rendered: &str) -> Result<(), Box<dyn std::error::Error>> {
let buf = rendered.as_bytes();
let mut f = File::create("webroot/index.html")?;
f.write_all(buf)?;
Ok(())
}

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="static/caty.css">
<title>A Blog Example</title>
</head>
<body>
<header>
<center>
<h1>Quite Magical Really</h1>
<nav>
<a href="./">HOME</a>
</nav>
</center>
</header>
<main>
{%- for post in posts %}
{{ post }}
{%- endfor -%}
</main>
<footer>
<p>This brilliance was brought to you by.. ME</p>
</footer>
</body>
</html>

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="static/caty.css">
<title>A Blog Example</title>
</head>
<body>
<header>
<center>
<h1>Quite Magical Really</h1>
<nav>
<a href="./">HOME</a>
</nav>
</center>
</header>
<main>
<h3>WOWWWWWWWWWWWWWW</h3>
<p>Another one.</p>
<h3>Omfg Amazing</h3>
<p>This is some cool shit here. Like srsly wtf.</p>
</main>
<footer>
<p>This brilliance was brought to you by.. ME</p>
</footer>
</body>
</html>

@ -0,0 +1,3 @@
### Omfg Amazing
This is some cool shit here. Like srsly wtf.

@ -0,0 +1,3 @@
### WOWWWWWWWWWWWWWW
Another one.

@ -0,0 +1,384 @@
:root {
--sans-font:-apple-system,BlinkMacSystemFont,"Avenir Next",Avenir,"Nimbus Sans L",Roboto,Noto,"Segoe UI",Arial,Helvetica,"Helvetica Neue",sans-serif;
--mono-font:Consolas,Menlo,Monaco,"Andale Mono","Ubuntu Mono",monospace;
--base-fontsize:1.15rem;
--header-scale:1.25;
--line-height:1.618;
--bg: #135F4Cff;
--accent-bg:#136044ff;
--text: #B2BABBff;
--text-light: #AFB8B9ff;
--border:#829191;
--accent:#79989B;
--accent-light:#90CAF9;
--code: #BABFBFff;
--preformatted: #A4B2B3ff;
--marked: #A0A6BE;
--disabled:#EFEFEF
}
@media (prefers-color-scheme:dark) {
:root {
--bg:#212121;
--accent-bg:#2B2B2B;
--text:#DCDCDC;
--text-light:#ABABAB;
--border:#666;
--accent:#FFB300;
--accent-light:#FFECB3;
--code:#F06292;
--preformatted:#CCC;
--disabled:#111
}
img,
video {
opacity:.6
}
}
html {
font-family:var(--sans-font);
font-size:16px
}
body {
color:var(--text);
background:var(--bg);
font-size:var(--base-fontsize);
line-height:var(--line-height);
display:flex;
min-height:100vh;
flex-direction:column;
flex:1;
margin:0 auto;
max-width:45rem;
padding:0 .5rem;
overflow-x:hidden;
word-break:break-word;
overflow-wrap:break-word
}
header {
background:var(--accent-bg);
border-bottom:1px solid var(--border);
text-align:center;
padding:2rem .5rem;
width:100vw;
position:relative;
left:50%;
right:50%;
margin-left:-50vw;
margin-right:-50vw
}
header h1,
header p {
margin:0
}
header h1 {
line-height:1.1
}
nav {
font-size:1rem;
line-height:2;
padding:1rem 0
}
nav a {
margin:1rem 1rem 0 0;
border:1px solid var(--border);
border-radius:5px;
color:var(--text)!important;
display:inline-block;
padding:.1rem 1rem;
text-decoration:none;
transition:.4s
}
nav a:hover {
color:var(--accent)!important;
border-color:var(--accent)
}
nav a.current:hover {
text-decoration:none
}
footer {
margin-top:4rem;
padding:2rem 1rem 1.5rem 1rem;
color:var(--text-light);
font-size:.9rem;
text-align:center;
border-top:1px solid var(--border)
}
h1 {
font-size:calc(var(--base-fontsize) * var(--header-scale) * var(--header-scale) * var(--header-scale) * var(--header-scale));
margin-top:calc(var(--line-height) * 1.5rem)
}
h2 {
font-size:calc(var(--base-fontsize) * var(--header-scale) * var(--header-scale) * var(--header-scale));
margin-top:calc(var(--line-height) * 1.5rem)
}
h3 {
font-size:calc(var(--base-fontsize) * var(--header-scale) * var(--header-scale));
margin-top:calc(var(--line-height) * 1.5rem)
}
h4 {
font-size:calc(var(--base-fontsize) * var(--header-scale));
margin-top:calc(var(--line-height) * 1.5rem)
}
h5 {
font-size:var(--base-fontsize);
margin-top:calc(var(--line-height) * 1.5rem)
}
h6 {
font-size:calc(var(--base-fontsize)/ var(--header-scale));
margin-top:calc(var(--line-height) * 1.5rem)
}
a,
a:visited {
color:var(--accent)
}
a:hover {
text-decoration:none
}
a button,
button,
input[type=button],
input[type=reset],
input[type=submit] {
border:none;
border-radius:5px;
background:var(--accent);
font-size:1rem;
color:var(--bg);
padding:.7rem .9rem;
margin:.5rem 0;
transition:.4s
}
a button[disabled],
button[disabled],
input[type=button][disabled],
input[type=checkbox][disabled],
input[type=radio][disabled],
input[type=reset][disabled],
input[type=submit][disabled],
select[disabled] {
cursor:default;
opacity:.5;
cursor:not-allowed
}
input:disabled,
select:disabled,
textarea:disabled {
cursor:not-allowed;
background-color:var(--disabled)
}
input[type=range] {
padding:0
}
abbr {
cursor:help
}
button:enabled:hover,
button:focus,
input[type=button]:enabled:hover,
input[type=button]:focus,
input[type=checkbox]:enabled:hover,
input[type=checkbox]:focus,
input[type=radio]:enabled:hover,
input[type=radio]:focus,
input[type=reset]:enabled:hover,
input[type=reset]:focus,
input[type=submit]:enabled:hover,
input[type=submit]:focus {
opacity:.8
}
details {
padding:.6rem 1rem;
background:var(--accent-bg);
border:1px solid var(--border);
border-radius:5px;
margin-bottom:1rem
}
summary {
cursor:pointer;
font-weight:700
}
details[open] {
padding-bottom:.75rem
}
details[open] summary {
margin-bottom:.5rem
}
details[open]>:last-child {
margin-bottom:0
}
table {
border-collapse:collapse;
width:100% margin: 1.5rem 0
}
td,
th {
border:1px solid var(--border);
text-align:left;
padding:.5rem
}
th {
background:var(--accent-bg);
font-weight:700
}
tr:nth-child(even) {
background:var(--accent-bg)
}
table caption {
font-weight:700;
margin-bottom:.5rem
}
ol,
ul {
padding-left:3rem
}
input,
select,
textarea {
font-size:inherit;
font-family:inherit;
padding:.5rem;
margin-bottom:.5rem;
color:var(--text);
background:var(--bg);
border:1px solid var(--border);
border-radius:5px;
box-shadow:none;
box-sizing:border-box;
width:60%;
appearance:none;
-moz-appearance:none;
-webkit-appearance:none
}
select {
background-image:linear-gradient(45deg,transparent 49%,var(--text) 51%),linear-gradient(135deg,var(--text) 51%,transparent 49%);
background-position:calc(100% - 20px),calc(100% - 15px);
background-size:5px 5px,5px 5px;
background-repeat:no-repeat
}
input[type=checkbox],
input[type=radio] {
vertical-align:bottom;
position:relative
}
input[type=radio] {
border-radius:100%
}
input[type=checkbox]:checked,
input[type=radio]:checked {
background:var(--accent)
}
input[type=checkbox]:checked::after {
content:' ';
width:.1em;
height:.25em;
border-radius:0;
position:absolute;
top:.05em;
left:.18em;
background:0 0;
border-right:solid var(--bg) .08em;
border-bottom:solid var(--bg) .08em;
font-size:1.8em;
transform:rotate(45deg)
}
input[type=radio]:checked::after {
content:' ';
width:.25em;
height:.25em;
border-radius:100%;
position:absolute;
top:.125em;
background:var(--bg);
left:.125em;
font-size:32px
}
textarea {
width:80%
}
@media only screen and (max-width:720px) {
input,
select,
textarea {
width:100%
}
}
input[type=checkbox],
input[type=radio] {
width:auto
}
input[type=file] {
border:0
}
fieldset {
border:0;
padding:0;
margin:0
}
hr {
color:var(--border);
border-top:1px;
margin:1rem auto
}
mark {
padding:2px 5px;
border-radius:4px;
background:var(--marked)
}
main img,
main video {
max-width:100%;
border-radius:5px
}
figure {
margin:0
}
figcaption {
font-size:.9rem;
color:var(--text-light);
text-align:center;
margin-bottom:1rem
}
blockquote {
margin:2rem 0 2rem 2rem;
padding:.4rem .8rem;
border-left:.35rem solid var(--accent);
opacity:.8;
font-style:italic
}
cite {
font-size:.9rem;
color:var(--text-light);
font-style:normal
}
code,
kbd,
pre,
pre span,
samp {
font-size:1.075rem;
font-family:var(--mono-font);
color:var(--code)
}
kbd {
color:var(--preformatted);
border:1px solid var(--preformatted);
border-bottom:3px solid var(--preformatted);
border-radius:5px;
padding:.1rem
}
pre {
padding:1rem 1.4rem;
max-width:100%;
overflow:auto;
overflow-x:auto;
color:var(--preformatted);
background:var(--accent-bg);
border:1px solid var(--border);
border-radius:5px
}
pre code {
color:var(--preformatted);
background:0 0;
margin:0;
padding:0
}
Loading…
Cancel
Save