Skip to content

Commit

Permalink
✨ feat: add Open Graph image generation for paste previews
Browse files Browse the repository at this point in the history
The commit adds functionality to generate preview images for pastes that can be used in Open Graph meta tags. This includes:

1. New endpoint for generating paste preview images
2. Image generation service using Go's graphics libraries
3. Syntax highlighting in generated images
4. Watermark support
5. Updated meta tags to use generated images for pastes
  • Loading branch information
watzon committed Nov 18, 2024
1 parent 386cbbe commit bb9a853
Show file tree
Hide file tree
Showing 10 changed files with 463 additions and 7 deletions.
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ require (

require github.com/watzon/hdur v1.0.0

require (
github.com/fogleman/gg v1.3.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
golang.org/x/image v0.22.0 // indirect
)

require (
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
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/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
Expand All @@ -79,6 +81,8 @@ github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
Expand Down Expand Up @@ -201,6 +205,8 @@ golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
Expand Down
17 changes: 17 additions & 0 deletions internal/server/handlers/paste.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,20 @@ func (h *PasteHandlers) HandleDeletePaste(c *fiber.Ctx) error {
func (h *PasteHandlers) HandleUpdateExpiration(c *fiber.Ctx) error {
return h.services.Paste.UpdateExpiration(c, getPasteID(c))
}

// HandleGetPasteImage returns an image of the paste suitable for Open Graph
func (h *PasteHandlers) HandleGetPasteImage(c *fiber.Ctx) error {
id := getPasteID(c)

// Get extension from locals if available
if ext := c.Locals("extension"); ext != nil {
id = id + "." + ext.(string)
}

paste, err := h.services.Paste.GetPaste(id)
if err != nil {
return err
}

return h.services.Paste.GetPasteImage(c, paste)
}
5 changes: 5 additions & 0 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,16 @@ func (s *Server) SetupRoutes() {
c.Locals("extension", c.Params("ext"))
return s.handlers.Paste.HandleDownload(c)
})
s.app.Get("/p/:id.:ext/image", func(c *fiber.Ctx) error {
c.Locals("extension", c.Params("ext"))
return s.handlers.Paste.HandleGetPasteImage(c)
})

// Handle paste routes without extensions
s.app.Get("/p/:id/raw", s.handlers.Paste.HandleRawView)
s.app.Get("/p/:id/download", s.handlers.Paste.HandleDownload)
s.app.Delete("/p/:id/:key", s.handlers.Paste.HandleDeleteWithKey)
s.app.Get("/p/:id/image", s.handlers.Paste.HandleGetPasteImage)

// Handle URL redirects
s.app.Get("/u/:id", s.handlers.URL.HandleRedirect)
Expand Down
Loading

0 comments on commit bb9a853

Please sign in to comment.