Added post social image

This commit is contained in:
Marcus Noble 2020-09-14 20:43:52 +01:00
parent 3bf8fc61c5
commit 6d1b7ff397
8 changed files with 210 additions and 1 deletions

View File

@ -1,3 +1,11 @@
FROM golang:1.14-alpine as go-builder
ENV GO111MODULE=on
WORKDIR /app
ADD social-image-gen .
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" -o social-image-gen main.go
FROM debian:buster AS builder
RUN apt-get -qq update \
@ -11,8 +19,13 @@ RUN curl -sL -o /tmp/hugo.deb \
dpkg -i /tmp/hugo.deb && \
rm /tmp/hugo.deb
COPY --from=go-builder /app/social-image-gen /social-image-gen
WORKDIR /app
ADD . .
ADD ./social-image-gen/fonts/ /fonts
RUN /social-image-gen --mode posts
RUN hugo -d /usr/share/nginx/html/
FROM nginx:latest

View File

@ -7,6 +7,8 @@ enableGitInfo = true
[permalinks]
posts = "/:title/"
[params]
gitUrl = "https://git.cluster.fun/AverageMarcus/til/commit/"
[taxonomies]
series = "series"

View File

@ -5,6 +5,8 @@ draft: false
tags:
- tekton
- docker
images:
- /images/tekton-multi-arch-builds.gif
---
Using Buildkit to build multi-arch compatible images without Docker daemon:

Binary file not shown.

Binary file not shown.

13
social-image-gen/go.mod Normal file
View File

@ -0,0 +1,13 @@
module social-image-gen
go 1.13
require (
github.com/ericaro/frontmatter v0.0.0-20200210094738-46863cd917e2
github.com/fogleman/gg v1.3.0
github.com/gofiber/fiber v1.14.6
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/pkg/errors v0.9.1
golang.org/x/image v0.0.0-20200801110659-972c09e46d76 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
)

42
social-image-gen/go.sum Normal file
View File

@ -0,0 +1,42 @@
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/ericaro/frontmatter v0.0.0-20200210094738-46863cd917e2 h1:+dzAHE3uQKGtPxobmh43c0n8V8A7X70zqUUDzL7ePVA=
github.com/ericaro/frontmatter v0.0.0-20200210094738-46863cd917e2/go.mod h1:Xy0DdToffIGb/ZMCwM5zFgIQOrVh0cKvNABpKRJYo1w=
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/gofiber/fiber v1.14.6 h1:QRUPvPmr8ijQuGo1MgupHBn8E+wW0IKqiOvIZPtV70o=
github.com/gofiber/fiber v1.14.6/go.mod h1:Yw2ekF1YDPreO9V6TMYjynu94xRxZBdaa8X5HhHsjCM=
github.com/gofiber/utils v0.0.10 h1:3Mr7X7JdCUo7CWf/i5sajSaDmArEDtti8bM1JUVso2U=
github.com/gofiber/utils v0.0.10/go.mod h1:9J5aHFUIjq0XfknT4+hdSMG6/jzfaAgCu4HEbWDeBlo=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ=
github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/image v0.0.0-20200801110659-972c09e46d76 h1:U7GPaoQyQmX+CBRWXKrvRzWTbd+slqeSh8uARsIyhAw=
golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 h1:OjiUf46hAmXblsZdnoSXsEUSKU8r1UEzcL5RVZ4gO9Y=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

137
social-image-gen/main.go Normal file
View File

@ -0,0 +1,137 @@
package main
import (
"bufio"
"bytes"
"fmt"
"image"
"image/color"
"image/color/palette"
"image/draw"
"image/gif"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/ericaro/frontmatter"
"github.com/fogleman/gg"
)
type Post struct {
Title string `yaml:"title"`
Tags []string `yaml:"tags"`
}
func main() {
if err := filepath.Walk("./content/posts/", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
body, err := ioutil.ReadFile(path)
if err != nil {
return err
}
var out Post
frontmatter.Unmarshal(body, &out)
img, err := run(out.Title)
if err != nil {
return err
}
filename := "./static/images/" + strings.ReplaceAll(info.Name(), ".md", ".gif")
fmt.Printf("Saving %s", filename)
ioutil.WriteFile(filename, img, 0755)
return nil
}); err != nil {
panic(err)
}
}
const (
width = 1200
height = 628
)
var (
monoFont = filepath.Join("/fonts", "Noto.ttf")
headerFont = filepath.Join("/fonts", "Inter-SemiBold.ttf")
fontColor = color.RGBA{169, 169, 179, 0xff}
)
func run(title string) ([]byte, error) {
dc := gg.NewContext(width, height)
// Background
dc.SetHexColor("#292a2d")
dc.DrawRectangle(0, 0, width, height)
dc.Fill()
// Header
dc.SetHexColor("#252627")
dc.DrawRectangle(0, 0, width, 100)
dc.Fill()
if err := dc.LoadFontFace(monoFont, 45); err != nil {
return nil, err
}
dc.SetColor(fontColor)
dc.DrawString("#til", 45, 60)
dc.LoadFontFace(monoFont, 20)
dc.SetColor(fontColor)
dc.DrawString("https://til.marcusnoble.co.uk", 895, 623)
dc.LoadFontFace(headerFont, 80)
textRightMargin := 50.0
textTopMargin := 130.0
x := textRightMargin
y := textTopMargin
maxWidth := float64(dc.Width()) - textRightMargin - textRightMargin
dc.SetColor(color.White)
dc.DrawStringWrapped(title, x+1, y+1, 0, 0, maxWidth, 1.5, gg.AlignLeft)
dc.SetColor(fontColor)
dc.DrawStringWrapped(title, x, y, 0, 0, maxWidth, 1.5, gg.AlignLeft)
frame1 := dc.Image()
dc = gg.NewContextForImage(frame1)
dc.LoadFontFace(headerFont, 80)
title += " |"
textRightMargin = 50.0
textTopMargin = 130.0
x = textRightMargin
y = textTopMargin
maxWidth = float64(dc.Width()) - textRightMargin - textRightMargin
dc.SetColor(color.White)
dc.DrawStringWrapped(title, x+1, y+1, 0, 0, maxWidth, 1.5, gg.AlignLeft)
dc.SetColor(fontColor)
dc.DrawStringWrapped(title, x, y, 0, 0, maxWidth, 1.5, gg.AlignLeft)
frame2 := dc.Image()
palettedImage1 := image.NewPaletted(frame1.Bounds(), palette.Plan9)
draw.Over.Draw(palettedImage1, frame1.Bounds(), frame1, image.ZP)
palettedImage2 := image.NewPaletted(frame2.Bounds(), palette.Plan9)
draw.Over.Draw(palettedImage2, frame2.Bounds(), frame2, image.ZP)
var output bytes.Buffer
gif.EncodeAll(bufio.NewWriter(&output), &gif.GIF{
Image: []*image.Paletted{
palettedImage1,
palettedImage2,
},
Delay: []int{50, 50},
})
return output.Bytes(), nil
}