Add all basic code

This commit is contained in:
~erin 2022-01-23 13:40:13 -05:00
commit b098b6f708
No known key found for this signature in database
GPG Key ID: DA70E064A8C70F44
9 changed files with 431 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

181
Cargo.lock generated Normal file
View File

@ -0,0 +1,181 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "build_html"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e121f1569e70b069135a0768a6b62a16c9c0eeaba92815a4baa6fdb93a97ec79"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"serde",
"time",
"winapi",
]
[[package]]
name = "cooking"
version = "0.1.0"
dependencies = [
"build_html",
"chrono",
"uuid",
]
[[package]]
name = "getrandom"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "ppv-lite86"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "serde"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b"
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "uuid"
version = "1.0.0-alpha.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb3ab47baa004111b323696c6eaa2752e7356f7f77cf6b6dc7a2087368ce1ca4"
dependencies = [
"getrandom",
"rand",
"serde",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

21
Cargo.toml Normal file
View File

@ -0,0 +1,21 @@
[package]
name = "cooking"
description = "simple cooking/recipe site"
authors = ["Erin Nova <contact@the-system.eu.org>"]
license = "CNPLv7+"
homepage = "https://catgirl.cooking"
repository = "https://git.lavender.software/erin/tinymark"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[profile.release]
lto = true # Enable linktime optimization
codegen-units = 1
panic = "abort"
[dependencies]
build_html = "2.0.0"
uuid = { version = "1.0.0-alpha.1", features = ["v4", "serde", "fast-rng"] }
chrono = { version = "0.4", features = ["serde"] }

1
index.html Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html><head><link href="favicon.ico" rel="icon"><link href="style.css" rel="stylesheet"><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="description" content="The cutest cooking site on the net :3"><title>Catgirl Cooking</title></head><body><h1>🥘 Catgirl Cooking</h1><hr><p>The cutest cooking site on the net :3</p><p>Absolutely no ads, tracking, or nazis, ever.</p><i><p>Tags:</p><p><a href='breakfast'>breakfast</a>,<a href='apples'>apples</a>,<a href='cheese'>cheese</a>,<a href='vegan'>vegan</a>,<a href='vegetarian'>vegetarian</a>,</p></i><h2>Recipes:</h2><ul><li><a href="Macaroni & Cheese">Macaroni & Cheese</a></li><li><a href="Soup">Soup</a></li><li><a href="Apple Pie">Apple Pie</a></li><li><a href="More Soup">More Soup</a></li><li><a href="idk">idk</a></li><li><a href="cum">cum</a></li></ul><footer><hr><a href="/">home</a><a href="/atom.xml">atom</a><p>Software licensed under the CNPLv7+</p><p>Recipes under Public Domain</p></footer></body></html>

19
src/io.rs Normal file
View File

@ -0,0 +1,19 @@
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
pub fn write_html(html: String) {
let path = Path::new("index.html");
// Open file in write-only mode
let mut file = match File::create(&path) {
Err(why) => panic!("couldn't create file: {}", why),
Ok(file) => file,
};
// Write the HTML to fil
match file.write_all(html.as_bytes()) {
Err(why) => panic!("couldn't write to file: {}", why),
Ok(_) => println!("successfully wrote to file"),
}
}

59
src/main.rs Normal file
View File

@ -0,0 +1,59 @@
use build_html::{self, Html, HtmlContainer, ContainerType, Container};
mod structures;
mod io;
mod tests;
fn main() {
// Specify info to go onto the base page
let base_page = build_html::HtmlPage::new()
.with_head_link("favicon.ico", "icon") // Favicon
.with_stylesheet("style.css") // Link stylesheet
.with_meta(vec![("charset", "UTF-8")])
.with_meta(vec![("name", "viewport"), ("content", "width=device-width, initial-scale=1")]) // Display stuff
.with_meta(vec![("name", "description"), ("content", structures::DESCRIPTION)]) // Add the description
.with_title(structures::TITLE);
// Create the footer
let footer = Container::new(ContainerType::Footer)
.with_raw(r#"<hr>"#) // Line seperator
.with_link("/", "home") // Link to the root page
.with_link("/atom.xml", "atom") // Link the the Atom feed
// License info
.with_paragraph("Software licensed under the CNPLv7+")
.with_paragraph("Recipes under Public Domain");
// Create the home page
let mut home_page = base_page
.with_header(1, structures::HEADER)
.with_raw(r#"<hr>"#)
.with_paragraph(structures::DESCRIPTION)
.with_paragraph(structures::DETAILS);
// Create (test) lists of tags & recipes
let tags: Vec<&str> = vec!["breakfast", "apples", "cheese", "vegan", "vegetarian"];
let recipes: Vec<&str> = vec!["Macaroni & Cheese", "Soup", "Apple Pie", "More Soup", "idk", "cum"];
home_page.add_raw(r#"<i>"#); // Tags in italics
home_page.add_paragraph("Tags:");
let mut tags_html = String::new(); // Create custom html string for tags
tags_html.push_str(r#"<p>"#); // Begin paragraph element
for x in tags { // Go through the list of tags
tags_html.push_str(format!("<a href='{}'>{}</a>,", x, x).as_str()); // Append the tags as a link
}
tags_html.push_str(r#"</p>"#); // End the paragraph
home_page.add_raw(tags_html); // Add the string as html to the page
home_page.add_raw(r#"</i>"#); // End the italics
// Append recipes
home_page.add_header(2, "Recipes:");
let mut recipes_container = Container::new(ContainerType::UnorderedList);
for i in recipes {
recipes_container.add_link(i, i);
}
home_page.add_container(recipes_container);
home_page.add_container(footer);
io::write_html(home_page.to_html_string());
}

70
src/structures.rs Normal file
View File

@ -0,0 +1,70 @@
use uuid::Uuid;
use chrono::prelude::*;
// Content strings to add to html
pub const TITLE: &str = r#"Catgirl Cooking"#;
pub const HEADER: &str = r#"🥘 Catgirl Cooking"#;
pub const DESCRIPTION: &str = r#"The cutest cooking site on the net :3"#;
pub const DETAILS: &str = r#"Absolutely no ads, tracking, or nazis, ever."#;
pub enum TimeUnits {
Hours,
Min,
Sec,
}
pub enum MeasurementUnits {
Grams,
Kilograms,
Pounds,
Litres,
Millilitres,
Gallons,
Ounces,
Pinch,
Drop,
Tablespoon,
Teaspoon,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Tag(pub char, pub String);
impl Tag {
pub fn new(s: String) -> Tag {
Tag('#', s)
}
pub fn to_string(&self) -> String {
let mut tag = String::new();
tag.push_str(&self.0.to_string());
tag.push_str(&self.1);
return tag;
}
pub fn from_string(s: String) -> Tag {
let hash = s.chars().nth(0).unwrap();
let mut text = s;
text.remove(0);
text.make_ascii_lowercase();
return Tag(hash, text);
}
pub fn display(&self) {
println!("{}{}", self.0, self.1);
}
}
pub struct Recipe {
id: Uuid, // Unique recipe ID
name: String, // Full recipe name
prep_time: (i32, TimeUnits), // Preparation time: (value, units)
cooking_time: (i32, TimeUnits), // Cooking time: (value, units)
servings: u8, // How many servinge the recipe makes
ingredients: Vec<(i32, MeasurementUnits, String)>, // Vector of ingredients: (value, units, name)
directions: Vec<(u16, String)>, // List of instructions: (step #, details)
attribution: String, // Author name
posted_date: DateTime<Utc>, // Date the recipe was first posted
edited_date: DateTime<Utc>, // Date the recipe was last edited
tags: Vec<Tag>, // List of tags
}

20
src/tests.rs Normal file
View File

@ -0,0 +1,20 @@
#[cfg(test)]
mod tests {
// Note this useful idiom: importing names from outer (for mod tests) scope.
use crate::structures::*;
#[test]
fn test_tag_new() {
assert_eq!(Tag::new("test".to_string()), Tag('#', "test".to_string()));
}
#[test]
fn test_tag_from_string() {
assert_eq!(Tag::from_string("#test".to_string()), Tag('#', "test".to_string()));
}
#[test]
fn test_tag_to_string() {
assert_eq!(Tag('#', "test".to_string()).to_string(), "#test".to_string());
}
}

59
style.css Normal file
View File

@ -0,0 +1,59 @@
/* Light Theme */
@media (prefers-color-scheme: light) {
:root {
--background: #fffee6;
--foreground: #0f0f0e;
--accent: #26A269;
--link: #E7044C;
--link-visited: #A43737;
}
}
/* Dark Theme */
@media (prefers-color-scheme: dark) {
:root {
--background: #241F31;
--foreground: #F6F5F4;
--accent: #50C878;
--link: #FD8BAF;
--link-visited: #FB0452;
}
}
body {
background: var(--background);
color: var(--foreground);
max-width: 800px;
margin: auto;
padding: 0 16px;
margin-bottom: 500px;
font-family: 'Atkinson Hyperlegible', sans-serif;
}
a {
color: var(--link);
padding: 5px;
}
a:visited {
color: var(--link-visited);
}
h1 {
text-align: center;
}
footer {
text-align: center ;
}
img {
max-width: 600px ;
width: 100% ;
margin: auto ;
display: block ;
}
ul {
column-count: 3;
}