diff options
Diffstat (limited to 'roseh.moe.go')
| -rw-r--r-- | roseh.moe.go | 123 |
1 files changed, 113 insertions, 10 deletions
diff --git a/roseh.moe.go b/roseh.moe.go index 5ce4258..ad09cb5 100644 --- a/roseh.moe.go +++ b/roseh.moe.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "embed" "flag" "fmt" @@ -10,6 +11,7 @@ import ( "net/http" "net/http/httputil" "net/url" + "slices" "strings" "time" ) @@ -36,26 +38,126 @@ func notFound(w http.ResponseWriter, r *http.Request) { } } +//go:embed templates/outline.html.template +var outlineString string + +var outlineTemplate = template.Must(template.New("outline").Parse(outlineString)) + +var ( + //go:embed templates/blog/post.html.template + postString string + + //go:embed templates/blog/posts + blogPostFiles embed.FS +) + +func preloadBlogPosts() map[string][]byte { + base, err := outlineTemplate.Clone() + if err != nil { + log.Fatalf("outlineTemplate.Clone: %s", err) + } + base, err = base.New("body").Parse(postString) + if err != nil { + log.Fatalf("post.html.template: invalid template: %s", err) + } + postTemplates, err := blogPostFiles.ReadDir("templates/blog/posts") + if err != nil { + log.Fatalf("blog posts: %s", err) + } + posts := make(map[string][]byte, len(postTemplates)) + for _, post := range postTemplates { + base, err = base.Clone() + if err != nil { + log.Fatalf("base.Clone: %s", err) + } + postString, err := blogPostFiles.ReadFile("templates/blog/posts/" + post.Name()) + if err != nil { + log.Fatalf("somehow I fucked the paths up: %s", err) + } + postTemplate, err := base.New("post").Parse(string(postString)) + if err != nil { + log.Fatalf("%q: invalid template: %s", post.Name(), err) + } + buf := new(bytes.Buffer) + if err := postTemplate.ExecuteTemplate(buf, "outline", nil); err != nil { + log.Fatalf("%q: error: %s", post.Name(), err) + } + posts[strings.TrimSuffix(post.Name(), ".html.template")] = buf.Bytes() + } + return posts +} + +var blogPostsHTML = preloadBlogPosts() + +func blog(w http.ResponseWriter, r *http.Request) { + post, ok := blogPostsHTML[strings.TrimPrefix(r.URL.Path, "/blog/")] + if !ok { + notFound(w, r) + return + } + http.ServeContent(w, r, "post.html", serverStartTime, bytes.NewReader(post)) +} + //go:embed templates/index.html.template var indexString string -var indexTemplate = template.Must(template.New("index").Parse(indexString)) - -func index(w http.ResponseWriter, _ *http.Request) { - if err := indexTemplate.Execute(w, nil); err != nil { - log.Printf("Warning: index: %s", err) +func preloadIndex() []byte { + base, err := outlineTemplate.Clone() + if err != nil { + log.Fatalf("outlineTemplate.Clone: %s", err) + } + base.Funcs(template.FuncMap{ + "name": func(post string) string { + postBytes, err := blogPostFiles.ReadFile("templates/blog/posts/" + post + ".html.template") + if err != nil { + log.Fatalf("no such post %q: %s", post, err) + } + date := post[:strings.IndexByte(post, '_')] + firstLine := postBytes[:bytes.IndexByte(postBytes, '\n')] + return date + ": " + string(bytes.TrimSuffix(bytes.TrimPrefix(firstLine, []byte("<h1>")), []byte("</h1>"))) + }, + }) + indexTemplate, err := base.New("body").Parse(indexString) + if err != nil { + log.Fatalf("index.html.template: invalid template: %s", err) + } + posts := make([]string, 0, len(blogPostsHTML)) + for p := range blogPostsHTML { + posts = append(posts, p) } + slices.Sort(posts) + buf := new(bytes.Buffer) + if err := indexTemplate.ExecuteTemplate(buf, "outline", posts); err != nil { + log.Fatalf("index.html.template: error: %s", err) + } + return buf.Bytes() +} + +var indexHTML = preloadIndex() + +func index(w http.ResponseWriter, r *http.Request) { + http.ServeContent(w, r, "index.html", serverStartTime, bytes.NewReader(indexHTML)) } //go:embed templates/pong.html.template var pongString string -var pongTemplate = template.Must(template.New("pong").Parse(pongString)) - -func pong(w http.ResponseWriter, _ *http.Request) { - if err := pongTemplate.Execute(w, nil); err != nil { - log.Printf("Warning: pong: %s", err) +func preloadPong() []byte { + pongTemplate, err := template.New("pong").Parse(pongString) + if err != nil { + log.Fatalf("pong.html.template: invalid template: %s", err) + } + buf := new(bytes.Buffer) + if err := pongTemplate.Execute(buf, nil); err != nil { + log.Fatalf("pong.html.template: error: %s", err) } + return buf.Bytes() +} + +var pongHTML = preloadPong() + +func pong(w http.ResponseWriter, r *http.Request) { + http.ServeContent(w, r, "pong.html", serverStartTime, bytes.NewReader(pongHTML)) } //go:embed static @@ -76,6 +178,7 @@ func main() { flag.Parse() mux := http.NewServeMux() + mux.HandleFunc("/blog/", blog) mux.HandleFunc("/pong", pong) jellyfinURL, err := url.Parse("http://localhost:8096") if err != nil { |
