server, post: add about images for social media

Signed-off-by: Naman Sood <mail@nsood.in>
This commit is contained in:
Naman Sood 2021-12-17 03:09:04 -05:00
parent 4fd8925116
commit 4c39700474
36 changed files with 216 additions and 3 deletions

108
server.go
View file

@ -1,12 +1,22 @@
package main
import (
"bytes"
"io"
"log"
"math"
"net/http"
"strings"
"sync"
"github.com/aymerick/raymond"
"github.com/fogleman/gg"
)
const (
blogTitle = "Prose"
blogURL = "https://prose.nsood.in"
blogSummary = "Where I infodump in Markdown and nobody can stop me."
)
type server struct {
@ -15,7 +25,8 @@ type server struct {
mu sync.RWMutex
templates map[string]*raymond.Template
postList
styles map[string]string
styles map[string]string
homeImage bytes.Buffer
}
func newServer() (*server, error) {
@ -23,6 +34,11 @@ func newServer() (*server, error) {
staticHandler: http.FileServer(http.Dir("static/")),
}
err := createImage(blogTitle, blogSummary, blogURL, &s.homeImage)
if err != nil {
return nil, err
}
posts, err := newPostList()
if err != nil {
return nil, err
@ -92,11 +108,18 @@ func (s *server) router(res http.ResponseWriter, req *http.Request) {
s.homePage(res, req)
return
}
if slug == "about.png" {
s.renderImage(res, req, &s.homeImage)
return
}
for _, p := range s.postList {
if p.Slug == slug {
if slug == p.Slug {
s.postPage(p, res, req)
return
} else if slug == p.Slug+"/about.png" {
s.renderImage(res, req, &p.Image)
return
}
}
@ -152,7 +175,7 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
posts = posts + summary
}
page, err := s.createWebPage("Home", "Where I infodump in Markdown and nobody can stop me.", posts)
page, err := s.createWebPage("Home", blogSummary, posts)
if err != nil {
s.errorInRequest(res, req, err)
@ -161,6 +184,14 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
res.Write([]byte(page))
}
func (s *server) renderImage(res http.ResponseWriter, req *http.Request, img io.Reader) {
res.Header().Add("content-type", "image/png")
_, err := io.Copy(res, img)
if err != nil {
s.errorInRequest(res, req, err)
}
}
func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, filename string) (ok bool) {
contents, ok := s.styles[filename]
if !ok {
@ -170,3 +201,74 @@ func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, file
res.Write([]byte(contents))
return ok
}
func createImage(title, summary, url string, out io.Writer) error {
imgWidth, imgPaddingX, imgPaddingY := 800, 30, 60
titleSize, summarySize, urlSize := 42.0, 28.0, 18.0
lineHeight := 1.5
textWidth := float64(imgWidth - 2*imgPaddingX)
// temporarily set height = 0 for context only used to generate
// wrapped strings
draw := gg.NewContext(imgWidth, 0)
titleFont, err := gg.LoadFontFace("fonts/Nunito-Bold.ttf", titleSize)
if err != nil {
return err
}
summaryFont, err := gg.LoadFontFace("fonts/Nunito-LightItalic.ttf", summarySize)
if err != nil {
return err
}
urlFont, err := gg.LoadFontFace("fonts/JetBrainsMono-ExtraLight.ttf", urlSize)
if err != nil {
return err
}
draw.SetFontFace(titleFont)
wrappedTitle := draw.WordWrap(title, textWidth)
draw.SetFontFace(summaryFont)
wrappedSummary := draw.WordWrap(summary, textWidth)
imgHeight := 2 * imgPaddingY
for range wrappedTitle {
imgHeight += int(math.Ceil(lineHeight * titleSize))
}
for range wrappedSummary {
imgHeight += int(math.Ceil(lineHeight * summarySize))
}
imgHeight += int(math.Ceil(lineHeight * urlSize))
// actual context with actual height
draw = gg.NewContext(imgWidth, imgHeight)
draw.SetHexColor("#fff")
draw.DrawRectangle(0, 0, float64(imgWidth), float64(imgHeight))
draw.Fill()
draw.SetHexColor("#3498db")
accentHeight := 5.0
draw.DrawRectangle(0, float64(imgHeight)-accentHeight, float64(imgWidth), accentHeight)
draw.Fill()
offset := float64(imgPaddingY)
draw.SetFontFace(titleFont)
draw.SetHexColor("#333")
for _, line := range wrappedTitle {
draw.DrawString(line, float64(imgPaddingX), offset)
offset += lineHeight * titleSize
}
draw.SetFontFace(summaryFont)
draw.SetHexColor("#999")
for _, line := range wrappedSummary {
draw.DrawString(line, float64(imgPaddingX), offset)
offset += lineHeight * summarySize
}
draw.SetHexColor("#333")
draw.SetFontFace(urlFont)
urlY := float64(imgHeight - imgPaddingY)
draw.DrawStringWrapped(url, float64(imgPaddingX), urlY, 0, 0, textWidth, lineHeight, gg.AlignRight)
return draw.EncodePNG(out)
}