repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
324796b
parent
bc3e29b
author
Eric Bower
date
2022-11-08 00:45:15 +0000 UTC
feat(lists): relative image urls now route to imgs.sh

This reaches feature parity with prose.sh where we can reference images
hosted by imgs.sh from lists.sh

Both "/image", "./image", and "./image.jpg" are supported.
5 files changed,  +53, -35
M lists/api.go
+15, -9
 1@@ -12,6 +12,7 @@ import (
 2 
 3 	"git.sr.ht/~erock/pico/db"
 4 	"git.sr.ht/~erock/pico/db/postgres"
 5+	"git.sr.ht/~erock/pico/imgs"
 6 	"git.sr.ht/~erock/pico/imgs/storage"
 7 	"git.sr.ht/~erock/pico/shared"
 8 	"github.com/gorilla/feeds"
 9@@ -159,7 +160,8 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
10 	}
11 	header, err := dbpool.FindPostWithFilename("_header.txt", user.ID, cfg.Space)
12 	if err == nil {
13-		parsedText := ParseText(header.Text)
14+		linkify := imgs.NewImgsLinkify(username)
15+		parsedText := ParseText(header.Text, linkify)
16 		if parsedText.MetaData.Title != "" {
17 			headerTxt.Title = parsedText.MetaData.Title
18 		}
19@@ -181,7 +183,8 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
20 	readmeTxt := &ReadmeTxt{}
21 	readme, err := dbpool.FindPostWithFilename("_readme.txt", user.ID, cfg.Space)
22 	if err == nil {
23-		parsedText := ParseText(readme.Text)
24+		linkify := imgs.NewImgsLinkify(username)
25+		parsedText := ParseText(readme.Text, linkify)
26 		readmeTxt.Items = parsedText.Items
27 		readmeTxt.ListType = parsedText.MetaData.ListType
28 		if len(readmeTxt.Items) > 0 {
29@@ -296,8 +299,9 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
30 
31 	header, _ := dbpool.FindPostWithFilename("_header.txt", user.ID, cfg.Space)
32 	blogName := GetBlogName(username)
33+	linkify := imgs.NewImgsLinkify(username)
34 	if header != nil {
35-		headerParsed := ParseText(header.Text)
36+		headerParsed := ParseText(header.Text, linkify)
37 		if headerParsed.MetaData.Title != "" {
38 			blogName = headerParsed.MetaData.Title
39 		}
40@@ -306,12 +310,12 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
41 	var data PostPageData
42 	post, err := dbpool.FindPostWithSlug(slug, user.ID, cfg.Space)
43 	if err == nil {
44-		parsedText := ParseText(post.Text)
45+		parsedText := ParseText(post.Text, linkify)
46 
47 		// we need the blog name from the readme unfortunately
48 		readme, err := dbpool.FindPostWithFilename("_readme.txt", user.ID, cfg.Space)
49 		if err == nil {
50-			readmeParsed := ParseText(readme.Text)
51+			readmeParsed := ParseText(readme.Text, linkify)
52 			if readmeParsed.MetaData.Title != "" {
53 				blogName = readmeParsed.MetaData.Title
54 			}
55@@ -529,7 +533,8 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
56 	}
57 	header, err := dbpool.FindPostWithFilename("_header.txt", user.ID, cfg.Space)
58 	if err == nil {
59-		parsedText := ParseText(header.Text)
60+		linkify := imgs.NewImgsLinkify(username)
61+		parsedText := ParseText(header.Text, linkify)
62 		if parsedText.MetaData.Title != "" {
63 			headerTxt.Title = parsedText.MetaData.Title
64 		}
65@@ -552,8 +557,8 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
66 		if slices.Contains(cfg.HiddenPosts, post.Filename) {
67 			continue
68 		}
69-
70-		parsed := ParseText(post.Text)
71+		linkify := imgs.NewImgsLinkify(username)
72+		parsed := ParseText(post.Text, linkify)
73 		var tpl bytes.Buffer
74 		data := &PostPageData{
75 			ListType: parsed.MetaData.ListType,
76@@ -627,7 +632,8 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
77 
78 	var feedItems []*feeds.Item
79 	for _, post := range pager.Data {
80-		parsed := ParseText(post.Text)
81+		linkify := imgs.NewImgsLinkify(post.Username)
82+		parsed := ParseText(post.Text, linkify)
83 		var tpl bytes.Buffer
84 		data := &PostPageData{
85 			ListType: parsed.MetaData.ListType,
M lists/parser.go
+14, -5
 1@@ -7,6 +7,7 @@ import (
 2 	"strings"
 3 	"time"
 4 
 5+	"git.sr.ht/~erock/pico/shared"
 6 	"github.com/araddon/dateparse"
 7 )
 8 
 9@@ -114,7 +115,7 @@ func KeyAsValue(token *SplitToken) string {
10 	return token.Value
11 }
12 
13-func parseItem(meta *MetaData, li *ListItem, prevItem *ListItem, pre bool, mod int) (bool, bool, int) {
14+func parseItem(meta *MetaData, li *ListItem, prevItem *ListItem, pre bool, mod int, linkify shared.Linkify) (bool, bool, int) {
15 	skip := false
16 
17 	if strings.HasPrefix(li.Value, preToken) {
18@@ -141,7 +142,15 @@ func parseItem(meta *MetaData, li *ListItem, prevItem *ListItem, pre bool, mod i
19 	} else if strings.HasPrefix(li.Value, imgToken) {
20 		li.IsImg = true
21 		split := TextToSplitToken(strings.Replace(li.Value, imgToken, "", 1))
22-		li.URL = template.URL(split.Key)
23+		key := split.Key
24+		if strings.HasPrefix(key, "/") {
25+			frag := shared.SanitizeFileExt(key)
26+			key = linkify.Create(frag)
27+		} else if strings.HasPrefix(key, "./") {
28+			name := shared.SanitizeFileExt(key[1:])
29+			key = linkify.Create(name)
30+		}
31+		li.URL = template.URL(key)
32 		li.Value = KeyAsValue(split)
33 	} else if strings.HasPrefix(li.Value, varToken) {
34 		split := TextToSplitToken(strings.Replace(li.Value, varToken, "", 1))
35@@ -157,7 +166,7 @@ func parseItem(meta *MetaData, li *ListItem, prevItem *ListItem, pre bool, mod i
36 		old := len(li.Value)
37 		li.Value = trim
38 
39-		pre, skip, _ = parseItem(meta, li, prevItem, pre, mod)
40+		pre, skip, _ = parseItem(meta, li, prevItem, pre, mod, linkify)
41 		if prevItem != nil && prevItem.Indent == 0 {
42 			mod = old - len(trim)
43 			li.Indent = 1
44@@ -176,7 +185,7 @@ func parseItem(meta *MetaData, li *ListItem, prevItem *ListItem, pre bool, mod i
45 	return pre, skip, mod
46 }
47 
48-func ParseText(text string) *ParsedText {
49+func ParseText(text string, linkify shared.Linkify) *ParsedText {
50 	textItems := SplitByNewline(text)
51 	items := []*ListItem{}
52 	meta := MetaData{
53@@ -198,7 +207,7 @@ func ParseText(text string) *ParsedText {
54 			Value: t,
55 		}
56 
57-		pre, skip, mod = parseItem(&meta, &li, prevItem, pre, mod)
58+		pre, skip, mod = parseItem(&meta, &li, prevItem, pre, mod, linkify)
59 
60 		if li.IsText && li.Value == "" {
61 			skip = true
M lists/scp_hooks.go
+3, -1
 1@@ -6,6 +6,7 @@ import (
 2 
 3 	"git.sr.ht/~erock/pico/db"
 4 	"git.sr.ht/~erock/pico/filehandlers"
 5+	"git.sr.ht/~erock/pico/imgs"
 6 	"git.sr.ht/~erock/pico/shared"
 7 	"golang.org/x/exp/slices"
 8 )
 9@@ -38,7 +39,8 @@ func (p *ListHooks) FileValidate(data *filehandlers.PostMetaData) (bool, error)
10 }
11 
12 func (p *ListHooks) FileMeta(data *filehandlers.PostMetaData) error {
13-	parsedText := ParseText(string(data.Text))
14+	linkify := imgs.NewImgsLinkify(data.Username)
15+	parsedText := ParseText(string(data.Text), linkify)
16 
17 	if parsedText.MetaData.Title == "" {
18 		data.Title = shared.ToUpper(data.Slug)
M shared/img.go
+20, -0
 1@@ -1,6 +1,7 @@
 2 package shared
 3 
 4 import (
 5+	"bytes"
 6 	"fmt"
 7 	"image"
 8 	gif "image/gif"
 9@@ -38,6 +39,25 @@ type Ratio struct {
10 	Height int
11 }
12 
13+type Linkify interface {
14+	Create(fname string) string
15+}
16+
17+func CreateImgURL(linkify Linkify) func([]byte) []byte {
18+	return func(url []byte) []byte {
19+		if url[0] == '/' {
20+			name := SanitizeFileExt(string(url))
21+			nextURL := linkify.Create(name)
22+			return []byte(nextURL)
23+		} else if bytes.HasPrefix(url, []byte{'.', '/'}) {
24+			name := SanitizeFileExt(string(url[1:]))
25+			nextURL := linkify.Create(name)
26+			return []byte(nextURL)
27+		}
28+		return url
29+	}
30+}
31+
32 func GetRatio(dimes string) (*Ratio, error) {
33 	if dimes == "" {
34 		return nil, nil
M shared/mdparser.go
+1, -20
 1@@ -166,25 +166,6 @@ func (r *ImgRender) renderImage(w util.BufWriter, source []byte, node ast.Node,
 2 	return ast.WalkSkipChildren, nil
 3 }
 4 
 5-type Linkify interface {
 6-	Create(fname string) string
 7-}
 8-
 9-func createImgURL(linkify Linkify) func([]byte) []byte {
10-	return func(url []byte) []byte {
11-		if url[0] == '/' {
12-			name := SanitizeFileExt(string(url))
13-			nextURL := linkify.Create(name)
14-			return []byte(nextURL)
15-		} else if bytes.HasPrefix(url, []byte{'.', '/'}) {
16-			name := SanitizeFileExt(string(url[1:]))
17-			nextURL := linkify.Create(name)
18-			return []byte(nextURL)
19-		}
20-		return url
21-	}
22-}
23-
24 func ParseText(text string, linkify Linkify) (*ParsedText, error) {
25 	parsed := ParsedText{
26 		MetaData: &MetaData{
27@@ -211,7 +192,7 @@ func ParseText(text string, linkify Linkify) (*ParsedText, error) {
28 		goldmark.WithRendererOptions(
29 			ghtml.WithUnsafe(),
30 			renderer.WithNodeRenderers(
31-				util.Prioritized(NewImgsRenderer(createImgURL(linkify)), 0),
32+				util.Prioritized(NewImgsRenderer(CreateImgURL(linkify)), 0),
33 			),
34 		),
35 	)