Initial commit

This commit is contained in:
Technoduck 2024-08-29 11:04:04 -04:00
commit b8e56c87b4
29 changed files with 4131 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

1898
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

23
Cargo.toml Normal file
View file

@ -0,0 +1,23 @@
[package]
name = "rusty_duck"
version = "0.1.0"
edition = "2021"
[profile.release]
opt-level = 'z' # Optimize for size.
lto = true # Enable Link Time Optimisation
codegen-units = 1 # Reduced to increase optimisations.
panic = 'abort' # Abort on panic
strip = "symbols" # Strip symbols from binary
[dependencies]
askama = { version = "0.12.1", features = ["with-axum"] }
askama_axum = "0.4.0"
axum = "0.7.5"
comrak = "0.27.0"
markdown-parser = "0.1.2"
rand = "0.8.5"
serde = { version = "1.0.209", features = ["derive"] }
serde_yaml = "0.9.34"
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
tower-http = { version = "0.5.2", features = ["fs"] }

13
assets/duck.asc Normal file
View file

@ -0,0 +1,13 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZMNBMhYJKwYBBAHaRw8BAQdAmPlgCTcSG+IWCXqaE5muoTUnU5phhTx0r7Rb
/+KkBn20IFRlY2hubyBEdWNrIDxkdWNrQHRlY2hub2R1Y2subWU+iJkEExYKAEEW
IQSNINxoxA6qXTt7s4AEGKzIL/qdBAUCZMNBMgIbAwUJA8JnAAULCQgHAgIiAgYV
CgkICwIEFgIDAQIeBwIXgAAKCRAEGKzIL/qdBMi6APwNf+l6lEAe43VqFdX2JQBG
Ix0zhcpFIsbj8uuGJigEFgD9GuMFECAIdnjeYKJCAl5HgOgmR8TK+rY5bMeVa93v
wAS4OARkw0EyEgorBgEEAZdVAQUBAQdAl4PNh37rKOOd0bb47BhcaWMPhgBvWuz4
uUbXpZOilyQDAQgHiH4EGBYKACYWIQSNINxoxA6qXTt7s4AEGKzIL/qdBAUCZMNB
MgIbDAUJA8JnAAAKCRAEGKzIL/qdBP6iAQCJkWOreY5Kwz1JDwu0mICt3MobMJsX
IT+H2MdjE5uyDQD/TBgZjHRp6xILvSSzS8H5e0ClBkKNqUhJMVZ+hPdx/wU=
=dSiL
-----END PGP PUBLIC KEY BLOCK-----

BIN
assets/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
assets/gnu-linux.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

1614
assets/img/led_hoop/pcb.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

28
assets/old_style.css Normal file
View file

@ -0,0 +1,28 @@
:root {
font-size:1rem;
--rhythm: 1.5rem;
--line-length: 60vw;
}
header {
margin-bottom: 0px;
}
h1,
h2,
h3,
h4,
h5,
h6,
.\<h1\>,
.\<h2\>,
.\<h3\>,
.\<h4\>,
.\<h5\>,
.\<h6\> {
margin-block-start:var(--gap);
}
p {
font-size: 1.2em;
}

5
assets/robots.txt Normal file
View file

@ -0,0 +1,5 @@
User-agent: *
Disallow: /
User-agent: ChatGPT-User
Disallow: /

122
assets/style.css Normal file
View file

@ -0,0 +1,122 @@
html {
overflow-y: scroll;
}
body {
background-color: #fff;
color: #000;
font-family: sans-serif;
margin: 0;
padding: 1ex;
}
/* HTML5 semantic tags: some (older) browsers display this inline by default */
article, figcaption, figure, header, main, nav {
display: block;
}
/* center images */
img {
margin: 0 auto;
}
table, img {
border: 0;
}
hr {
border: 0;
border-bottom: 3px solid #aaa;
height: 3px;
}
h1 {
font-size: 140%;
}
h2 {
font-size: 120%;
}
h3 {
font-size: 120%;
}
h1,
h1 a,
h1 a:visited,
h2,
h2 a,
h2 a:visited,
h3,
h3 a,
h3 a:visited,
h1 a:hover,
h2 a:hover,
h3 a:hover {
color: inherit;
text-decoration: none;
}
table tr td {
padding: 2px 10px 2px 0px;
}
pre {
margin: 0;
}
pre code {
display: block;
border: 3px solid #aaa;
padding: 5px;
}
code {
background-color: #eee;
border: 1px solid #aaa;
font-family: monospace;
overflow-x: auto;
padding: 1px;
word-wrap: normal;
}
#menu td {
padding: 1ex 0;
}
#main {
border-top: 3px solid #aaa;
}
#menuwrap,
#menu,
#main {
margin: 0px auto;
max-width: 100ex;
}
.hidden {
display: none;
}
.logo {
display: flex;
}
img.logo {
width: 7em;
}
.footer {
margin-top: 4em;
}
.footer a img {
float: left;
margin-bottom: 3em;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #121210;
color: #bdbdbd;
}
pre code, code {
background-color: #333;
border-color: #444;
}
hr {
border-color: #444;
}
a {
color: #56c8ff;
}
#main {
border-top: 3px solid #444;
}
}

BIN
assets/technoduck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

14
posts/000-genesis.md Normal file
View file

@ -0,0 +1,14 @@
---
title: Full website Update
date: 2023-01-12
---
## New Website
### Saait
I got a little bit tired of the old site, so changed it to something more ~websit-y~
Now its made using [Saait](https://git.codemadness.org/saait/) and what a treat it is.
More Updates coming.

11
posts/001-bash_blogger.md Normal file
View file

@ -0,0 +1,11 @@
---
title: Creating posts with bash and git from terminal
date: 2023-01-13
---
Since updating this website with Saait, I have decided to create a tool to streamline page creation from the terminal.
Inspired by [bash_blog](https://github.com/j0m/bash_blog) and [bashblog](https://github.com/cfenollosa/bashblog) especially bash was chosen.
It is goofy, not as practical as I would think, but neat nevertheless.
Source at my [git](https://git.technoduck.me) repo.

32
posts/002-services.md Normal file
View file

@ -0,0 +1,32 @@
---
title: List of Services running on the server
date: 2023-01-13
---
### This blog
Self explanatory. This is my [website](/), my little corner of the internet.
### Email
Self hosted email server using Dovecot + Posfix.
### Git
[forgejo](https://git.technoduck.me) instance for my personal projects.
### Etebase
An [Etebase](https://etebase.technoduck.me) instance for syncing my tasks, to-do's and contacts between devices.
### Grocy
[Grocy](https://grocy.technoduck.me) instance for keeping track of food and grocery lists ( and literally anything else in your house including batteris in devices? ) it's really cool give it a check.
### Wiki
A [wikimedia](https://wiki.cold-metal.technoduck.me) instance running for a friend for categorizing all the lore of the world that is being created for a soft fiction story.
### WIP
Work in progress of a [website](https://wip.technoduck.me) I am making for a photographer/photography business.

41
posts/003-led_hoop.md Normal file
View file

@ -0,0 +1,41 @@
---
title: PCB LED hoop earring project
date: 2024-01-02
---
## LED Hoops
### What?
First, a blog post by [mitxela](https://mitxela.com) came upon my eyes, and piqued my interest.
Inspired by the [industrial piercing](https://mitxela.com/projects/scaffold) and the electronics that went into it, I though if other pieces of jewelry can be made with electronics (they can, it was specifically a question if my measly hands could craft them).
Since for the first time, I didn't want to experiment with absolute microscopic sizes, I decided that a 4 cm hoop was an adequate project to attempt.
![schematic_kicad_image](img/led_hoop/schematic.png =800x)
An Attiny 24/44/84A can be used, I went with a -M variant, since it is slightly larger then the -MM variant, by a whole mm, which I assume will be easier to solder.
Placing them all in a nice hoop looking pcb, we obtain this:
![pcb_kicad_image](/assets/img/led_hoop/pcb.svg)
The test version comes with ISP pins for debugging and programming the chip when it's already installed.
0603 LED's were chosen for the same reason, they are small enough to be not that noticeable, but large enough to be not an incredible pain to work with.
### Why??
It looked and sounded fun, my only previous projects related to PCB production before this was edition a split [Sweep](https://github.com/davidphilipbarr/Sweep) keyboard.
And so I did.
### Cool. What now?
You can take your chance and go to [the git repository](https://git.technoduck.me/technoduck/led_hoop) for the project, `git pull`, and try your own luck.
Batteries not included.

16
posts/004-pantheon.md Normal file
View file

@ -0,0 +1,16 @@
---
title: Pantheon
date: 2024-03-03
---
# WATCH PANTHEON
## I DO NOT CARE WHAT DAY IT IS
### HERE'S YOUR PLAN
1. Wake up.
2. Open whatever device you watch things on.
3. Obtain, legally or illegaly, by any means necessary, 2 (two) seasons of Pantheon, created by Craig Silverstein based on short stories by Ken Liu.
4. Binge the 2 sesons in a single night (it is feasable I checked)
Thank you for coming to my Ted Talk.

36
posts/005-regenesis.md Normal file
View file

@ -0,0 +1,36 @@
---
title: Full website Re-Update
date: 2024-08-29
---
## New Website?
### Rust
The time has come and another re-write is upon us.
This time inspied by [this article](https://blog.transrights.art/blogs/2024_Screw-Frameworks-New-Site-2),
[theprimeagen](https://www.youtube.com/watch?v=rcZSOLAI1lM), and everpresent desire to rewrite everything in Rust,
the new website is a complete rewrite using rust and adjacent techniques.
Using only
```
[dependencies]
askama = { version = "0.12.1", features = ["with-axum"] }
askama_axum = "0.4.0"
axum = "0.7.5"
comrak = "0.27.0"
markdown-parser = "0.1.2"
rand = "0.8.5"
serde = { version = "1.0.209", features = ["derive"] }
serde_yaml = "0.9.34"
tokio = { version = "1.39.3", features = ["macros", "rt-multi-thread"] }
tower-http = { version = "0.5.2", features = ["fs"] }
```
as dependancies in the end we get a clean~ish, 2.8MB executable.
All markdown compilation gets done every time page is loaded, which is sub-optimal,
But reading time for all posts is non-significant compared to other loading times.
And voila, there is the new post.

40
src/blog_entries.rs Normal file
View file

@ -0,0 +1,40 @@
use std::{fs::read_dir, path::Path};
use markdown_parser::*;
use crate::structs::{BlogInfo, IndexPostEntry};
pub fn get_blog_entry_markdown(path:&String) -> Result<Markdown,Error> {
let location = format!("posts/{path}.md").to_string();
read_file(Path::new(&location))
}
pub fn get_all_markdowns() -> Vec<IndexPostEntry> {
let mut post_vec:Vec<IndexPostEntry> = Vec::new();
let mr_dir_iter = match read_dir("posts/") {
Ok(iter) => iter,
Err(err) => panic!("could ls files, err {err}")
};
for entry in mr_dir_iter {
if let Ok(entry) = entry {
let filename = entry.file_name().into_string().unwrap().split(".").collect::<Vec<_>>()[0].to_string();
let front_matter_string = get_blog_entry_markdown(&filename).unwrap();
let front_matter:BlogInfo = serde_yaml::from_str(&front_matter_string.front_matter()).unwrap();
post_vec.push(IndexPostEntry{
title: front_matter.title,
date: front_matter.date,
path: format!("/blog/{filename}"),
});
}
}
post_vec.sort_by_key(|e| e.path.clone() );
post_vec.reverse();
post_vec
}

36
src/handlers.rs Normal file
View file

@ -0,0 +1,36 @@
use axum::{extract::Path,response::Html};
use crate::structs::*;
use crate::rand_quote::get_quote;
use crate::blog_entries::{get_all_markdowns, get_blog_entry_markdown};
pub async fn index() -> Html<String> {
let all_entries = get_all_markdowns();
let quote = get_quote();
let new_page = IndexTemplate { random_quote: quote, index_post_entries:&all_entries};
Html(new_page.to_string())
}
pub async fn about() -> Html<String> {
let about_content = comrak::markdown_to_html("about", &comrak::Options::default());
let page_content = AboutTemplate{about_content: &about_content};
Html(page_content.to_string())
}
pub async fn blog(Path(blog_path):Path<String>) -> Html<String> {
match get_blog_entry_markdown(&blog_path){
Ok(markdown) => Html(
BlogTemplate{
blog_content: &comrak::markdown_to_html(markdown.content(), &comrak::Options::default()),
front_matter:&serde_yaml::from_str(markdown.front_matter()).unwrap()}.to_string()
),
Err(..) => not_found().await,
}
}
pub async fn not_found() -> Html<String> {
Html(NotFoundTemplate{}.to_string())
}

27
src/main.rs Normal file
View file

@ -0,0 +1,27 @@
use axum::{routing::get, Router};
use tower_http::services::{ServeDir, ServeFile};
mod handlers;
mod structs;
pub mod blog_entries;
pub mod rand_quote;
#[tokio::main]
async fn main() {
let app: axum::Router = Router::new()
.route("/", get(handlers::index))
.route("/about", get(handlers::about))
.route("/blog",get(handlers::index))
.route("/blog/:blog_path",get(handlers::blog))
.route_service("/robots.txt", ServeFile::new("assets/robots.txt"))
.fallback(get(handlers::not_found))
.nest_service("/assets", ServeDir::new("assets"));
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}

19
src/rand_quote.rs Normal file
View file

@ -0,0 +1,19 @@
use rand::Rng;
pub fn get_quote() -> &'static str {
let vs = vec![
"Silliness and tomfooler are afoot, and who am I to stop it.",
"Low entropy self replicating phenomenon that generates a binding force called compassion.",
"I was born in the late Holocene and I've seen some shit.",
"If there's a deal meant for you, any wild place on earth will do.",
"Live long and prosper.",
"Prometheus they say brought gods fire down to man and we've caught it tamed it trained it since our history began.",
"Oh, so, wenn PETER PARKER eine Reizüberflutung hat, dann sind es \"Spidey-Sinne\", aber wenn ich es tue, ICH HABE AUTISM.",
"Guess we are doing Rust now",
];
let mut rng = rand::thread_rng();
match vs.get(rng.gen_range(0..vs.len())) {
Some(quote) => quote,
None => "You have caught me off guard.",
}
}

40
src/structs.rs Normal file
View file

@ -0,0 +1,40 @@
use askama::Template;
use serde::{Serialize,Deserialize};
#[derive(Template)]
#[template(path="index.html")]
pub struct IndexTemplate<'a> {
pub random_quote: &'a str,
pub index_post_entries: &'a Vec<IndexPostEntry>
}
#[derive(Template)]
#[template(path="about.html")]
pub struct AboutTemplate<'a> {
pub about_content: &'a String,
}
#[derive(Template)]
#[template(path="404.html")]
pub struct NotFoundTemplate {
}
#[derive(Template)]
#[template(path="blog_entry.html")]
pub struct BlogTemplate<'a> {
pub front_matter: &'a BlogInfo,
pub blog_content: &'a String,
}
#[derive(Debug,Serialize,Deserialize)]
pub struct BlogInfo {
pub title: String,
pub date: String,
}
#[derive(Debug,Serialize,Deserialize,PartialEq, Eq, PartialOrd, Ord)]
pub struct IndexPostEntry {
pub title: String,
pub date: String,
pub path: String,
}

7
templates/404.html Normal file
View file

@ -0,0 +1,7 @@
{% extends "layout.html" %}
{% block content %}
<p>Sadly this page doesnt seem to exist</p>
{% endblock %}

15
templates/about.html Normal file
View file

@ -0,0 +1,15 @@
{% extends "layout.html" %}
{% block title %}
About -
{% endblock %}
{% block content %}
<h2> yepper yapper yapper</h2>
<p> this is an about page </p>
{{ about_content|safe }}
{% endblock %}

15
templates/blog_entry.html Normal file
View file

@ -0,0 +1,15 @@
{% extends "layout.html" %}
{% block title %}
{{front_matter.title}} -
{% endblock %}
{% block content %}
<h1> {{front_matter.title}} </h1>
{{ blog_content|safe }}
{% endblock %}

24
templates/index.html Normal file
View file

@ -0,0 +1,24 @@
{% extends "layout.html" %}
{% block quote %}
{{ random_quote }}
{% endblock %}
{% block content %}
<h1 style="margin-top:0.5em"> Posts </h1>
<div class="table">
{% for entry in index_post_entries %}
<div>
<time> {{ entry.date }} </time>
<a href="{{ entry.path }}"> {{ entry.title }}</a>
</div>
{% endfor %}
</div>
{% endblock %}

54
templates/layout.html Normal file
View file

@ -0,0 +1,54 @@
<!doctype html>
<html lang="en">
<head>
<title>{% block title %}{% endblock %} Technoduck</title>
<link rel="stylesheet" href="/assets/style.css">
<link rel="stylesheet" href="https://unpkg.com/missing.css@1.1.2">
<link rel="stylesheet" href="/assets/old_style.css">
<link rel="icon" href="/assets/favicon.png" type="image/png" />
</head>
<body>
<main>
<header>
<a href="/">
<img style="display: flex; width: 7em;" align="left" alt="technoduck" src="/assets/technoduck.png">
</a>
<div class="table">
<div class="float:left">
<a href="/">Blog</a> |
<a href="https://git.technoduck.me" title="Git repository with some of my projects">Git</a> |
<a href="https://cv.technoduck.me">Files</a> |
<a href="https://wip.technoduck.me">[WIP]</a> |
</div>
<div class="float:right">
<a href="/about">About</a> |
<a href="assets/duck.asc">PGP</a> |
<a href="mailto:duck@technoduck.me">Mail</a>
</div>
</div>
<p>
{% block quote %}{% endblock %}
</p>
</header>
{% block content%}{% endblock %}
<footer>
<h4>
Copyleft (c) 2022-2024 technoduck
</h4>
<a href="https://yesterweb.org/no-to-web3/" target="_blank">
<img alt="a button that says 'keep the web free, say no to web3', linking to a page about web3" src="https://auzziejay.com/images/noweb32.gif">
</a>
<a href="https://voidlinux.org" target="_blank">
<img alt="A button indicating this site was made with Gnu+Linux, linking to Voidlinux website" src="/assets/gnu-linux.gif">
</a>
<a href="https://joinfediverse.wiki/Main_Page/Fancy" target="_blank">
<img alt="Button with Mastodon on it, linking to joinfediverse wiki" src="/assets/mastodon_button_2.gif">
</a>
</footer>
</main>
</body>
</html>