From 067ee4d66d0174be408d4051148f33b9a428ac3b Mon Sep 17 00:00:00 2001
From: thinkpadmaster
Date: Wed, 28 Jun 2023 21:05:01 -0500
Subject: first commit
---
TODO.md | 15 +
data/blog/FirstPost.html | 24 ++
data/projects/CCSEntryPortfolio.html | 21 ++
data/projects/CCSSophomoreInterior.html | 14 +
data/static/favicon.ico | Bin 0 -> 2238 bytes
data/static/media/DTR-232-D-Final_Board-Scerba.jpg | Bin 0 -> 3604922 bytes
data/static/media/MKE_Skyline_Art_Museum.jpg | Bin 0 -> 1661741 bytes
.../Arai_Helmet_720p.jpg | Bin 0 -> 62151 bytes
.../Sketch Portfolio early 2021/Bernie_720p.jpg | Bin 0 -> 45277 bytes
.../Dorm_Setup_720p.jpg | Bin 0 -> 68019 bytes
.../Sketch Portfolio early 2021/Flamingo_720p.jpg | Bin 0 -> 33120 bytes
.../Harley_Sportbike_Concept_720p.jpg | Bin 0 -> 75277 bytes
.../Peacock_Portrait2_Zoom_720p.jpg | Bin 0 -> 50559 bytes
.../Peacock_Portrait_720p.jpg | Bin 0 -> 29568 bytes
.../SL350_Bobber_720p.jpg | Bin 0 -> 43971 bytes
data/static/oldStyle.css | 348 +++++++++++++++++++++
data/static/script.js | 49 +++
data/static/sitemap.xml | 42 +++
data/static/style.css | 91 ++++++
go.mod | 3 +
site | Bin 0 -> 9126585 bytes
site.go | 268 ++++++++++++++++
templates/about.html | 12 +
templates/blog.html | 15 +
templates/index.html | 19 ++
templates/master.html | 38 +++
templates/postHelp.tmpl | 6 +
templates/projects.html | 15 +
28 files changed, 980 insertions(+)
create mode 100644 TODO.md
create mode 100644 data/blog/FirstPost.html
create mode 100644 data/projects/CCSEntryPortfolio.html
create mode 100644 data/projects/CCSSophomoreInterior.html
create mode 100644 data/static/favicon.ico
create mode 100644 data/static/media/DTR-232-D-Final_Board-Scerba.jpg
create mode 100644 data/static/media/MKE_Skyline_Art_Museum.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Arai_Helmet_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Bernie_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Dorm_Setup_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Flamingo_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Harley_Sportbike_Concept_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Peacock_Portrait2_Zoom_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/Peacock_Portrait_720p.jpg
create mode 100644 data/static/media/Sketch Portfolio early 2021/SL350_Bobber_720p.jpg
create mode 100644 data/static/oldStyle.css
create mode 100644 data/static/script.js
create mode 100644 data/static/sitemap.xml
create mode 100644 data/static/style.css
create mode 100644 go.mod
create mode 100755 site
create mode 100644 site.go
create mode 100644 templates/about.html
create mode 100644 templates/blog.html
create mode 100644 templates/index.html
create mode 100644 templates/master.html
create mode 100644 templates/postHelp.tmpl
create mode 100644 templates/projects.html
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..819f64c
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,15 @@
+# TODO File
+
+## site.go
+* Re-implement filesystem.Walk() to sort tree by 'date created'
+* Chop trailing '/' from URL path
+* Simplify loadPosts() / loadPost() functions (lots of shared code)
+
+## about.html
+* Write an 'about'
+
+## Overall
+* Change misleading and false *.html extension to something custom
+* Add tag system
+* Move over some old site content
+* Add year and month header for appropriate sections in the blog
\ No newline at end of file
diff --git a/data/blog/FirstPost.html b/data/blog/FirstPost.html
new file mode 100644
index 0000000..75496b2
--- /dev/null
+++ b/data/blog/FirstPost.html
@@ -0,0 +1,24 @@
+ First Post
+
+!@#
+
+!@#
+ First Post
+
+ This is my first post on the new site! I am very excited to have the new system set up and mostly functional. There is still plenty of work to be done, but this is a great start.
+ I have moved to Golang for all server side scripting web serving, and it's been a fun language to learn so far. I have had a lot of encouragement from my friend over at www.angel-castaneda.com so go check out his page to see what he is working on.
+
+ The new site structure should be as follows:
+
+ - / - Home page with featured projects and short about section.
+ - /projects - Page with all posted industrial and automotive design projects.
+ - /projects/name - Project with title "name".
+ - /blog - Page with all blog posts (content that does not fit under "/projects".)
+ - /blog/name - Blog entry with title "name".
+ - /about - About me and this website
+
+
+ I am very excited to start posting again! This site refresh has been long overdue. Feel free to send any errors, typos, or strange behavior to my listed email; there are bound to be some problems at first.
+
diff --git a/data/projects/CCSEntryPortfolio.html b/data/projects/CCSEntryPortfolio.html
new file mode 100644
index 0000000..f3a98f1
--- /dev/null
+++ b/data/projects/CCSEntryPortfolio.html
@@ -0,0 +1,21 @@
+ elements with href starting with #
+document.addEventListener('click', 'a[href^="#"]', function(event) {
+ // Click events are captured before hashchanges. Timeout
+ // causes offsetAnchor to be called after the page jump.
+ window.setTimeout(function() {
+ offsetAnchor();
+ }, 0);
+});
+
+// Set the offset when entering page with hash present in the url
+window.setTimeout(offsetAnchor, 0);*/
\ No newline at end of file
diff --git a/data/static/sitemap.xml b/data/static/sitemap.xml
new file mode 100644
index 0000000..1f568c3
--- /dev/null
+++ b/data/static/sitemap.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ https://alexscerba.com/
+ 2023-06-15T04:44:23+00:00
+ 1.00
+
+
+ https://alexscerba.com/projects/
+ 2023-06-15T04:44:23+00:00
+ 0.80
+
+
+ https://alexscerba.com/blog/
+ 2023-06-15T04:44:23+00:00
+ 0.80
+
+
+ https://alexscerba.com/about/
+ 2023-06-15T04:44:23+00:00
+ 0.80
+
+
+ https://alexscerba.com/projects/CCSEntryPortfolio
+ 2023-06-15T04:44:23+00:00
+ 0.80
+
+
+ https://alexscerba.com/blog/FirstPost
+ 2023-06-15T04:44:23+00:00
+ 0.64
+
+
+
+
\ No newline at end of file
diff --git a/data/static/style.css b/data/static/style.css
new file mode 100644
index 0000000..28eda95
--- /dev/null
+++ b/data/static/style.css
@@ -0,0 +1,91 @@
+* {
+ box-sizing: border-box;
+}
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: Arial, Helvetica, sans-serif;
+ max-width: 500px;
+ margin: 0 auto;
+ padding: 0;
+}
+
+nav {
+ margin-top: 8px;
+ text-align: center;
+ border-radius: 6px;
+ background-color: rgb(228, 228, 228);
+}
+
+nav ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+nav li {
+ display: inline-block;
+ margin: 10px;
+}
+
+a {
+ font-weight: bold;
+ color: black;
+ text-decoration: none;
+ border-bottom: 1px dotted black;
+}
+
+h1 {
+ margin: 60px 0 0 0;
+}
+
+.subtitle {
+ margin: 8px 0 60px 12px;
+}
+
+figure {
+ margin: 20px 0;
+}
+
+img {
+ max-width: 100%;
+}
+
+.imgGrid {
+ margin: 20px auto;
+ line-height: 0;
+ column-count: 2;
+ column-gap: 0px;
+}
+
+.imgGrid img {
+ width: 100% !important;
+ height: auto !important;
+}
+
+footer {
+ text-align: center;
+ background-color: rgb(228, 228, 228);
+ border-radius: 6px;
+}
+
+footer p {
+ padding: 8px 0;
+}
+
+@media only screen
+and (max-width: 520px) {
+ body {
+ max-width: 400px;
+ }
+}
+
+@media only screen
+and (max-width: 410px) {
+ body {
+ max-width: 375px;
+ }
+}
\ No newline at end of file
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..1891586
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module alexscerba.com/website
+
+go 1.20
diff --git a/site b/site
new file mode 100755
index 0000000..c802f64
Binary files /dev/null and b/site differ
diff --git a/site.go b/site.go
new file mode 100644
index 0000000..ab1d850
--- /dev/null
+++ b/site.go
@@ -0,0 +1,268 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "log"
+ "net/http"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+ "text/template"
+)
+
+type Post struct {
+ Meta []byte
+ Thumbnail []byte
+ Content []byte
+}
+
+type Posts struct {
+ Contents []*Post
+}
+
+func trimLeftChars(s string, n int) string {
+ m := 0
+ for i := range s {
+ if m >= n {
+ return s[i:]
+ }
+ m++
+ }
+ return s[:0]
+}
+
+func loadPost(path string) (p *Posts, err error) {
+
+ var section = 0
+ var tmp *Post = new(Post)
+
+ file, err := os.Open(path + ".html")
+ if err != nil {
+ file.Close()
+ var tmpPosts []*Post
+ tmpPosts = append(tmpPosts, tmp)
+ return &Posts{Contents: tmpPosts}, err
+ }
+
+ scanner := bufio.NewScanner(file)
+
+LineLoop:
+ for scanner.Scan() {
+ var line = scanner.Text()
+ var lineByte = []byte(line + "\n")
+
+ if line == "!@#" {
+ section++
+ goto LineLoop
+ }
+
+ switch section {
+ case 0:
+ tmp.Meta = append(tmp.Meta, lineByte...)
+ case 1:
+ tmp.Thumbnail = append(tmp.Thumbnail, lineByte...)
+ case 2:
+ tmp.Content = append(tmp.Content, lineByte...)
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ log.Fatal(err)
+ }
+
+ file.Close()
+
+ if err != nil {
+ return nil, err
+ }
+
+ var tmpPosts []*Post
+ tmpPosts = append(tmpPosts, tmp)
+
+ return &Posts{Contents: tmpPosts}, nil
+}
+
+func loadPosts(location string, postCount int) (p *Posts, err error) {
+ if postCount == 0 || postCount < -1 {
+ return nil, os.ErrInvalid
+ }
+
+ var tmpPosts []*Post
+ var depthCount = 0
+
+ // TODO - Use less computationally heavy opperation for scalability
+ err = filepath.Walk(location, func(path string, _ os.FileInfo, _ error) error {
+ var directory, err = regexp.MatchString("^data/(projects|blog)$", path)
+ if err != nil {
+ return err
+ }
+
+ if directory {
+ depthCount++
+ } else if postCount == -1 || depthCount < postCount+1 {
+ file, err := os.Open(path)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ scanner := bufio.NewScanner(file)
+
+ var section = 0
+ var tmp *Post = new(Post)
+
+ LineLoop:
+ for scanner.Scan() {
+ var line = scanner.Text()
+ var lineByte = []byte(line + "\n")
+
+ if line == "!@#" {
+ section++
+ goto LineLoop
+ }
+
+ switch section {
+ case 0:
+ tmp.Meta = append(tmp.Meta, lineByte...)
+ case 1:
+ tmp.Thumbnail = append(tmp.Thumbnail, lineByte...)
+ case 2:
+ tmp.Content = append(tmp.Content, lineByte...)
+ }
+ }
+
+ if err := scanner.Err(); err != nil {
+ log.Fatal(err)
+ }
+
+ file.Close()
+
+ tmpPosts = append(tmpPosts, tmp)
+ depthCount++
+
+ } else {
+ depthCount++
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &Posts{Contents: tmpPosts}, nil
+}
+
+func renderTemplate(w http.ResponseWriter, tmpl string, p *Posts) {
+ if tmpl == "post" {
+ t, err := template.ParseFiles("templates/master.html", "templates/postHelp.tmpl")
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ err = t.Execute(w, p.Contents[0])
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+ } else {
+ t, err := template.ParseFiles("templates/master.html", "templates/"+tmpl+".html")
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ err = t.Execute(w, p)
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ }
+ }
+}
+
+func rootHandler(w http.ResponseWriter, r *http.Request) {
+ path := strings.Split(r.URL.Path, "/")
+ if path[1] != "" {
+ http.NotFound(w, r)
+ } else {
+ p, err := loadPosts("data/projects", 3)
+ if err != nil {
+ http.NotFound(w, r)
+ }
+
+ renderTemplate(w, "index", p)
+ }
+}
+
+func aboutHandler(w http.ResponseWriter, r *http.Request) {
+ renderTemplate(w, "about", nil)
+}
+
+func agHandler(w http.ResponseWriter, r *http.Request) {
+ p, err := loadPosts("data"+strings.TrimSuffix(r.URL.Path, "/"), -1)
+ if err != nil {
+ http.NotFound(w, r)
+ }
+
+ renderTemplate(w, trimLeftChars(strings.TrimSuffix(r.URL.Path, "/"), 1), p)
+}
+
+func postHandler(w http.ResponseWriter, r *http.Request) {
+ path := strings.Split(r.URL.Path, "/")
+ if path[2] == "" {
+ agHandler(w, r)
+ } else {
+ p, err := loadPost("data/" + path[1] + "/" + path[2])
+ if p == nil || err != nil {
+ http.NotFound(w, r)
+ } else {
+ renderTemplate(w, "post", p)
+ }
+ }
+}
+
+func fileHandler(w http.ResponseWriter, r *http.Request) {
+ body, _ := os.ReadFile("data/www/" + r.URL.Path)
+
+ w.Header().Set("Content-Type", "text/css; charset=utf-8")
+ fmt.Fprintf(w, "%s", body)
+}
+
+func makeHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ fn(w, r)
+ }
+}
+
+func httpsRedirect(w http.ResponseWriter, req *http.Request) {
+ // remove/add not default ports from req.Host
+ target := "https://" + req.Host + req.URL.Path
+ if len(req.URL.RawQuery) > 0 {
+ target += "?" + req.URL.RawQuery
+ }
+ log.Printf("redirect to: %s", target)
+ http.Redirect(w, req, target,
+ // see comments below and consider the codes 308, 302, or 301
+ http.StatusMovedPermanently)
+}
+
+func main() {
+ /* hostValid, _ := regexp.MatchString("^alexscerba.com$", r.URL.Path)
+ if !hostValid {
+ req, _ := http.NewRequest(r.Method, "alexscerba.com"+r.URL.Path, r.Body)
+ redirect(w, req)
+ } */
+
+ fs := http.FileServer(http.Dir("./data/static"))
+ http.Handle("/static/", http.StripPrefix("/static/", fs))
+
+ http.HandleFunc("/projects/", postHandler)
+ http.HandleFunc("/blog/", postHandler)
+ http.HandleFunc("/about/", aboutHandler)
+ http.HandleFunc("/", rootHandler)
+
+ go http.ListenAndServe(":80", http.HandlerFunc(httpsRedirect))
+ log.Fatal(http.ListenAndServe(":443", nil))
+
+ //http.Handle("/", http.FileServer(http.Dir("/data/www")))
+ //log.Fatal(http.ListenAndServe(":8080", nil))
+}
diff --git a/templates/about.html b/templates/about.html
new file mode 100644
index 0000000..265e626
--- /dev/null
+++ b/templates/about.html
@@ -0,0 +1,12 @@
+{{ define "meta" }}
+ About
+
+{{ end }}
+{{ define "main" }}
+ About
+ Me and my site.
+
+ My name is Alex Scerba. For as long as I remember, I've been surrounded by people who tinkered and had a knack for repair and fixing. When the washing machine would go out, or the car started making a noise, we wouldn't call a repair man or go to the dealer. "It's just a machine, open it up and see what wrong" has been a part of my vocabulary for a long time and has been a major influence on how I lead my life.
+ In late elementary school, I was put into astronomy and tech camps at our local observatory. I attended them until highschool, at which point I started helping with the same camps and working on projects under another program they offered. The instructors were NASA engineers, astronomers, and science educators. This was my intro to the land of computers and engineering. Already surrounded by people that liked to fix stuff around the house, observing the kinds of things possible and being encouraged to build and program new things that would further our knowlegde of the universe lead me on my path to enrolling in the Milwaukee School of Engineering for a degree in computer science. It was at this time I built my website. It was out of jealousy actually... ; ). Another student posted his website in the "introduce yourself to the class" section. The site was fine enough. I sure didn't have one, but I had already written a webpage for a highschool presentation (That's another story) and felt I could do it bigger and better. With my vision in mind, I learned the basics of local web hosting and multipage development and eventually got a site deployed before the school year (I didn't end up posting it on the intro board). My time at MSOE was pretty good, but it was less than a year after the start of Covid, so it was far from the standard college experience. I enjoyed my courses well enough and was learning a lot, but I started to feel that it wasn't for me. I took sketching and drawing back up as a hobby early in the year, and by the time the third trimester came around, I decided that I was done. I wasn't really sure what to do, though. I knew that I liked drawing but knew I needed to get better and I liked working on motorcycles and had hopes for a while of starting up a small business making aftermarket parts or doing builds (This was definitely a pipe dream at the time, but I needed something to go on). Someone had to be behind the design of cars and motorcycles, so I did a search for schools that taught automotive design. Two schools showed up. CCS in Michigan and Art Center in California. CCS was cheaper, closer, and still looked like a great school, so I scrambled to put together a sketch portfolio to apply with, and I was accepted for the upcoming year.
+ CCS was an eye opener and intimidating. No longer did I have a leg up in the curriculum. Most of my classmates had been drawing for a decent portion of their lives or had been thinking about automotive design and cars, so they had a lot of interesting ideas. I had no clue what I was doing, other than I knew I liked motorcycles, computers, and building stuff.
+{{ end }}
\ No newline at end of file
diff --git a/templates/blog.html b/templates/blog.html
new file mode 100644
index 0000000..d90c19e
--- /dev/null
+++ b/templates/blog.html
@@ -0,0 +1,15 @@
+{{ define "meta"}}
+ Blog
+
+{{ end }}
+{{ define "main" }}
+ Blog
+ Personal and site updates.
+
+
+{{ range .Contents }}
+{{ printf "%s" .Thumbnail }}
+{{ end }}
+
+ Designer. Maker.
+ Student at College for Creative Studies in Detroit, MI. Love for tinkering, making, and building.
+
+ Current posted industrial and automotive design projects.
+