forked from tangled.org/core
this repo has no description

appview: pages/markup: rewrite links links to camo url

Changed files
+57 -16
appview
+2
appview/config.go
···
Dev bool `env:"TANGLED_DEV, default=false"`
JetstreamEndpoint string `env:"TANGLED_JETSTREAM_ENDPOINT, default=wss://jetstream1.us-east.bsky.network/subscribe"`
ResendApiKey string `env:"TANGLED_RESEND_API_KEY"`
+
CamoHost string `env:"TANGLED_CAMO_HOST, default=https://camo.tangled.sh"`
+
CamoSharedSecret string `env:"TANGLED_CAMO_SHARED_SECRET"`
}
func LoadConfig(ctx context.Context) (*Config, error) {
+1 -1
appview/pages/funcmap.go
···
return v.Slice(start, end).Interface()
},
"markdown": func(text string) template.HTML {
-
rctx := &markup.RenderContext{}
+
rctx := &markup.RenderContext{RendererType: markup.RendererTypeDefault}
return template.HTML(rctx.RenderMarkdown(text))
},
"isNil": func(t any) bool {
+31
appview/pages/markup/camo.go
···
+
package markup
+
+
import (
+
"crypto/hmac"
+
"crypto/sha256"
+
"encoding/hex"
+
"fmt"
+
+
"github.com/yuin/goldmark/ast"
+
)
+
+
func generateCamoURL(baseURL, secret, imageURL string) string {
+
h := hmac.New(sha256.New, []byte(secret))
+
h.Write([]byte(imageURL))
+
signature := hex.EncodeToString(h.Sum(nil))
+
hexURL := hex.EncodeToString([]byte(imageURL))
+
return fmt.Sprintf("%s/%s/%s", baseURL, signature, hexURL)
+
}
+
+
func (rctx *RenderContext) camoImageLinkTransformer(img *ast.Image) {
+
// don't camo on dev
+
if rctx.IsDev {
+
return
+
}
+
+
dst := string(img.Destination)
+
+
if rctx.CamoUrl != "" && rctx.CamoSecret != "" {
+
img.Destination = []byte(generateCamoURL(rctx.CamoUrl, rctx.CamoSecret, dst))
+
}
+
}
+12 -1
appview/pages/markup/markdown.go
···
const (
// RendererTypeRepoMarkdown is for repository documentation markdown files
RendererTypeRepoMarkdown RendererType = iota
+
// RendererTypeDefault is non-repo markdown, like issues/pulls/comments.
+
RendererTypeDefault
)
// RenderContext holds the contextual data for rendering markdown.
// It can be initialized empty, and that'll skip any transformations.
type RenderContext struct {
+
CamoUrl string
+
CamoSecret string
repoinfo.RepoInfo
IsDev bool
RendererType RendererType
···
a.rctx.relativeLinkTransformer(n.(*ast.Link))
case *ast.Image:
a.rctx.imageFromKnotTransformer(n.(*ast.Image))
+
a.rctx.camoImageLinkTransformer(n.(*ast.Image))
}
-
// more types here like RendererTypeIssue/Pull etc.
+
+
case RendererTypeDefault:
+
switch n.(type) {
+
case *ast.Image:
+
a.rctx.imageFromKnotTransformer(n.(*ast.Image))
+
a.rctx.camoImageLinkTransformer(n.(*ast.Image))
+
}
}
return ast.WalkContinue, nil
+10 -13
appview/pages/pages.go
···
"path/filepath"
"strings"
+
"tangled.sh/tangled.sh/core/appview"
"tangled.sh/tangled.sh/core/appview/auth"
"tangled.sh/tangled.sh/core/appview/db"
"tangled.sh/tangled.sh/core/appview/pages/markup"
···
rctx *markup.RenderContext
}
-
func NewPages(dev bool) *Pages {
+
func NewPages(config *appview.Config) *Pages {
// initialized with safe defaults, can be overriden per use
rctx := &markup.RenderContext{
-
IsDev: dev,
+
IsDev: config.Dev,
+
CamoUrl: config.CamoHost,
+
CamoSecret: config.CamoSharedSecret,
}
p := &Pages{
t: make(map[string]*template.Template),
-
dev: dev,
+
dev: config.Dev,
embedFS: Files,
rctx: rctx,
templateDir: "appview/pages",
···
return p.executeRepo("repo/empty", w, params)
}
-
p.rctx = &markup.RenderContext{
-
RepoInfo: params.RepoInfo,
-
IsDev: p.dev,
-
RendererType: markup.RendererTypeRepoMarkdown,
-
}
+
p.rctx.RepoInfo = params.RepoInfo
+
p.rctx.RendererType = markup.RendererTypeRepoMarkdown
if params.ReadmeFileName != "" {
var htmlString string
···
if params.ShowRendered {
switch markup.GetFormat(params.Path) {
case markup.FormatMarkdown:
-
p.rctx = &markup.RenderContext{
-
RepoInfo: params.RepoInfo,
-
IsDev: p.dev,
-
RendererType: markup.RendererTypeRepoMarkdown,
-
}
+
p.rctx.RepoInfo = params.RepoInfo
+
p.rctx.RendererType = markup.RendererTypeRepoMarkdown
params.RenderedContents = template.HTML(p.rctx.RenderMarkdown(params.Contents))
}
}
+1 -1
appview/state/state.go
···
clock := syntax.NewTIDClock(0)
-
pgs := pages.NewPages(config.Dev)
+
pgs := pages.NewPages(config)
resolver := appview.NewResolver()