Update to use opengraph-image-gen
This commit is contained in:
parent
e8c7513a4d
commit
c3202aa8c1
16
Dockerfile
16
Dockerfile
@ -1,31 +1,15 @@
|
||||
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 \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get -qq install -y --no-install-recommends libstdc++6 python-pygments git ca-certificates asciidoc curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV HUGO_VERSION 0.74.3
|
||||
ENV HUGO_BINARY hugo_extended_${HUGO_VERSION}_Linux-64bit.deb
|
||||
RUN curl -sL -o /tmp/hugo.deb \
|
||||
https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY} && \
|
||||
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
|
||||
|
@ -1,12 +1,12 @@
|
||||
---
|
||||
title: "Don't Reuse Keys"
|
||||
title: "Don't Reuse API Keys"
|
||||
date: 2020-10-03T12:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- cli
|
||||
- credentials
|
||||
images:
|
||||
- /images/dont-reuse-keys.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Don't%20Reuse%20API%20Keys&tags=cli%2Ccredentials&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
Not a technical post today, more of a reminder to myself not to reuse API keys for different purposes. In this instance I reset the credentials I had labelled "Terraform" which I just so happened to also be using In [Harbor](https://goharbor.io/) to connect to my S3 bucket. Que 2 hours of me later trying to figure out why I couldn't pull or push any images.
|
||||
|
@ -3,9 +3,9 @@ title: "How to get the favicon of any site"
|
||||
date: 2020-11-10T09:49:37+01:00
|
||||
draft: false
|
||||
tags:
|
||||
- favicon
|
||||
-
|
||||
images:
|
||||
- /images/favicons.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=How%20to%20get%20the%20favicon%20of%20any%20site&tags=favicon&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
If you ever find yourself needing to display a small icon for a 3rd party URL but don't want to have to crawl the site to pull out the favicon URL then you can make use of a Google CDN:
|
||||
|
@ -5,7 +5,7 @@ draft: false
|
||||
tags:
|
||||
- golang
|
||||
images:
|
||||
- /images/go-named-return-values.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Named%20returns%20in%20Go%20functions&tags=golang%2Cprogramming&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
While debugging some issues I was having with the AWS Golang SDK I discovered it was possible to name your function return values (pointers) and then set them within your function body without needing to explicitly return them at the end.
|
||||
|
@ -5,7 +5,7 @@ draft: false
|
||||
tags:
|
||||
- golang
|
||||
images:
|
||||
- /images/golang-append.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Golang's%20append%20mutates%20the%20provided%20array&tags=golang%2Cprogramming%2Carrays%2Cslices&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
A word of warning when using `append()` in Golang...
|
||||
|
@ -6,10 +6,10 @@ tags:
|
||||
- go
|
||||
- golang
|
||||
images:
|
||||
- /images/golang-split-by-space.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Split%20on%20spaces%20in%20Go&tags=golang%2Cprogramming%2Carrays&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
While looking to split a multiline and space separated string and not having any look with `strings.Split()` I came across this somewhat oddly names function:
|
||||
While looking to split a multiline and space separated string and not having any luck with `strings.Split()` I came across this somewhat oddly names function:
|
||||
|
||||
```go
|
||||
import (
|
||||
|
@ -6,7 +6,7 @@ tags:
|
||||
- kubernetes
|
||||
- kubectl
|
||||
images:
|
||||
- /images/kubectl-replace.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=kubectl%20replace&tags=kubernetes%2Ckubectl&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
After working with Kubernetes for a few years now I've only just today learnt about `kubectl replace` which, you guessed it, completely replaces a resource.
|
||||
|
@ -5,7 +5,7 @@ draft: false
|
||||
tags:
|
||||
- kubernetes
|
||||
images:
|
||||
- /images/kubernetes-label-length.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Kubernetes%20label%20length&tags=kubernetes%2Clabels&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
It turns out that label _values_ in Kubernetes have a limit of 63 characters!
|
||||
|
@ -6,7 +6,7 @@ tags:
|
||||
- tekton
|
||||
- docker
|
||||
images:
|
||||
- /images/tekton-multi-arch-builds.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=Tekton%20Multi-Arch%20Image%20Builds&tags=tekton%2Cdocker%2Cci%2Ccd&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
Using Buildkit to build multi-arch compatible images without Docker daemon:
|
||||
|
@ -5,7 +5,7 @@ draft: false
|
||||
tags:
|
||||
- yaml
|
||||
images:
|
||||
- /images/yaml-multiline.gif
|
||||
- https://opengraph.cluster.fun/opengraph/?siteTitle=Today%20I%20learnt...&title=YAML%20multiline%20values&tags=yaml&image=https%3A%2F%2Fmarcusnoble.co.uk%2Fimages%2Fmarcus.jpg&twitter=Marcus_Noble_&github=AverageMarcus&website=www.MarcusNoble.co.uk
|
||||
---
|
||||
|
||||
After using YAML for a long time, for many, many Kubernetes manifest files, I have today learnt that it contains two multiline value types (called scalars):
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,13 +0,0 @@
|
||||
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
|
||||
)
|
@ -1,42 +0,0 @@
|
||||
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=
|
@ -1,137 +0,0 @@
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user