repos / pico

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

commit
dae7622
parent
bf4d03e
author
Antonio Mika
date
2022-08-02 23:46:19 +0000 UTC
Support any date format and light refactor
8 files changed,  +33, -35
M go.mod
M go.sum
M cmd/tags/tags.go
+2, -1
 1@@ -80,7 +80,8 @@ func main() {
 2 			continue
 3 		}
 4 		if len(parsed.Tags) > 0 {
 5-			picoDb.ReplaceTagsForPost(parsed.Tags, post.ID)
 6+			err := picoDb.ReplaceTagsForPost(parsed.Tags, post.ID)
 7+			panic(err)
 8 		}
 9 	}
10 }
M go.mod
+1, -0
1@@ -28,6 +28,7 @@ require (
2 
3 require (
4 	github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
5+	github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
6 	github.com/atotto/clipboard v0.1.4 // indirect
7 	github.com/caarlos0/sshmarshal v0.1.0 // indirect
8 	github.com/charmbracelet/keygen v0.3.0 // indirect
M go.sum
+3, -0
 1@@ -6,6 +6,8 @@ github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbf
 2 github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
 3 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
 4 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
 5+github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
 6+github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
 7 github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
 8 github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
 9 github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
10@@ -82,6 +84,7 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
11 github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
12 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
13 github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
14+github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
15 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
16 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
17 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
M lists/api.go
+12, -13
  1@@ -11,7 +11,6 @@ import (
  2 	"strings"
  3 	"time"
  4 
  5-	"git.sr.ht/~erock/pico/lists/pkg"
  6 	"git.sr.ht/~erock/pico/shared"
  7 	"git.sr.ht/~erock/pico/wish/cms/db"
  8 	"git.sr.ht/~erock/pico/wish/cms/db/postgres"
  9@@ -61,7 +60,7 @@ type PostPageData struct {
 10 	Username     string
 11 	BlogName     string
 12 	ListType     string
 13-	Items        []*pkg.ListItem
 14+	Items        []*ListItem
 15 	PublishAtISO string
 16 	PublishAt    string
 17 	Tags         []string
 18@@ -75,14 +74,14 @@ type TransparencyPageData struct {
 19 type HeaderTxt struct {
 20 	Title    string
 21 	Bio      string
 22-	Nav      []*pkg.ListItem
 23+	Nav      []*ListItem
 24 	HasItems bool
 25 }
 26 
 27 type ReadmeTxt struct {
 28 	HasItems bool
 29 	ListType string
 30-	Items    []*pkg.ListItem
 31+	Items    []*ListItem
 32 }
 33 
 34 func getPostsForUser(r *http.Request, user *db.User, tag string) ([]*db.Post, error) {
 35@@ -159,7 +158,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 36 	postCollection := make([]PostItemData, 0, len(posts))
 37 	for _, post := range posts {
 38 		if post.Filename == "_header.txt" {
 39-			parsedText := pkg.ParseText(post.Text)
 40+			parsedText := ParseText(post.Text)
 41 			if parsedText.MetaData.Title != "" {
 42 				headerTxt.Title = parsedText.MetaData.Title
 43 			}
 44@@ -173,7 +172,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 45 				headerTxt.HasItems = true
 46 			}
 47 		} else if post.Filename == "_readme.txt" {
 48-			parsedText := pkg.ParseText(post.Text)
 49+			parsedText := ParseText(post.Text)
 50 			readmeTxt.Items = parsedText.Items
 51 			readmeTxt.ListType = parsedText.MetaData.ListType
 52 			if len(readmeTxt.Items) > 0 {
 53@@ -249,7 +248,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
 54 	header, _ := dbpool.FindPostWithFilename("_header.txt", user.ID, cfg.Space)
 55 	blogName := GetBlogName(username)
 56 	if header != nil {
 57-		headerParsed := pkg.ParseText(header.Text)
 58+		headerParsed := ParseText(header.Text)
 59 		if headerParsed.MetaData.Title != "" {
 60 			blogName = headerParsed.MetaData.Title
 61 		}
 62@@ -258,12 +257,12 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
 63 	var data PostPageData
 64 	post, err := dbpool.FindPostWithSlug(slug, user.ID, cfg.Space)
 65 	if err == nil {
 66-		parsedText := pkg.ParseText(post.Text)
 67+		parsedText := ParseText(post.Text)
 68 
 69 		// we need the blog name from the readme unfortunately
 70 		readme, err := dbpool.FindPostWithFilename("_readme.txt", user.ID, cfg.Space)
 71 		if err == nil {
 72-			readmeParsed := pkg.ParseText(readme.Text)
 73+			readmeParsed := ParseText(readme.Text)
 74 			if readmeParsed.MetaData.Title != "" {
 75 				blogName = readmeParsed.MetaData.Title
 76 			}
 77@@ -305,7 +304,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
 78 			PublishAtISO: time.Now().Format(time.RFC3339),
 79 			Username:     username,
 80 			BlogName:     blogName,
 81-			Items: []*pkg.ListItem{
 82+			Items: []*ListItem{
 83 				{
 84 					Value:  "oops!  we can't seem to find this post.",
 85 					IsText: true,
 86@@ -459,7 +458,7 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
 87 
 88 	for _, post := range posts {
 89 		if post.Filename == "_header.txt" {
 90-			parsedText := pkg.ParseText(post.Text)
 91+			parsedText := ParseText(post.Text)
 92 			if parsedText.MetaData.Title != "" {
 93 				headerTxt.Title = parsedText.MetaData.Title
 94 			}
 95@@ -486,7 +485,7 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
 96 			continue
 97 		}
 98 
 99-		parsed := pkg.ParseText(post.Text)
100+		parsed := ParseText(post.Text)
101 		var tpl bytes.Buffer
102 		data := &PostPageData{
103 			ListType: parsed.MetaData.ListType,
104@@ -557,7 +556,7 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
105 
106 	var feedItems []*feeds.Item
107 	for _, post := range pager.Data {
108-		parsed := pkg.ParseText(post.Text)
109+		parsed := ParseText(post.Text)
110 		var tpl bytes.Buffer
111 		data := &PostPageData{
112 			ListType: parsed.MetaData.ListType,
M lists/gemini/gemini.go
+8, -9
 1@@ -17,7 +17,6 @@ import (
 2 	"git.sr.ht/~adnano/go-gemini/certificate"
 3 	feeds "git.sr.ht/~aw/gorilla-feeds"
 4 	"git.sr.ht/~erock/pico/lists"
 5-	"git.sr.ht/~erock/pico/lists/pkg"
 6 	"git.sr.ht/~erock/pico/shared"
 7 	"git.sr.ht/~erock/pico/wish/cms/db"
 8 	"git.sr.ht/~erock/pico/wish/cms/db/postgres"
 9@@ -109,7 +108,7 @@ func blogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
10 	postCollection := make([]lists.PostItemData, 0, len(posts))
11 	for _, post := range posts {
12 		if post.Filename == "_header.txt" {
13-			parsedText := pkg.ParseText(post.Text)
14+			parsedText := lists.ParseText(post.Text)
15 			if parsedText.MetaData.Title != "" {
16 				headerTxt.Title = parsedText.MetaData.Title
17 			}
18@@ -123,7 +122,7 @@ func blogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
19 				headerTxt.HasItems = true
20 			}
21 		} else if post.Filename == "_readme.txt" {
22-			parsedText := pkg.ParseText(post.Text)
23+			parsedText := lists.ParseText(post.Text)
24 			readmeTxt.Items = parsedText.Items
25 			readmeTxt.ListType = parsedText.MetaData.ListType
26 			if len(readmeTxt.Items) > 0 {
27@@ -249,7 +248,7 @@ func postHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
28 	header, _ := dbpool.FindPostWithFilename("_header.txt", user.ID, cfg.Space)
29 	blogName := lists.GetBlogName(username)
30 	if header != nil {
31-		headerParsed := pkg.ParseText(header.Text)
32+		headerParsed := lists.ParseText(header.Text)
33 		if headerParsed.MetaData.Title != "" {
34 			blogName = headerParsed.MetaData.Title
35 		}
36@@ -262,12 +261,12 @@ func postHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
37 		return
38 	}
39 
40-	parsedText := pkg.ParseText(post.Text)
41+	parsedText := lists.ParseText(post.Text)
42 
43 	// we need the blog name from the readme unfortunately
44 	readme, err := dbpool.FindPostWithFilename("_readme.txt", user.ID, cfg.Space)
45 	if err == nil {
46-		readmeParsed := pkg.ParseText(readme.Text)
47+		readmeParsed := lists.ParseText(readme.Text)
48 		if readmeParsed.MetaData.Title != "" {
49 			blogName = readmeParsed.MetaData.Title
50 		}
51@@ -380,7 +379,7 @@ func rssBlogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Requ
52 
53 	for _, post := range posts {
54 		if post.Filename == "_header.txt" {
55-			parsedText := pkg.ParseText(post.Text)
56+			parsedText := lists.ParseText(post.Text)
57 			if parsedText.MetaData.Title != "" {
58 				headerTxt.Title = parsedText.MetaData.Title
59 			}
60@@ -406,7 +405,7 @@ func rssBlogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Requ
61 		if slices.Contains(cfg.HiddenPosts, post.Filename) {
62 			continue
63 		}
64-		parsed := pkg.ParseText(post.Text)
65+		parsed := lists.ParseText(post.Text)
66 		var tpl bytes.Buffer
67 		data := &lists.PostPageData{
68 			ListType: parsed.MetaData.ListType,
69@@ -478,7 +477,7 @@ func rssHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request)
70 
71 	var feedItems []*feeds.Item
72 	for _, post := range pager.Data {
73-		parsed := pkg.ParseText(post.Text)
74+		parsed := lists.ParseText(post.Text)
75 		var tpl bytes.Buffer
76 		data := &lists.PostPageData{
77 			ListType: parsed.MetaData.ListType,
R lists/pkg/parser.go => lists/parser.go
+4, -2
 1@@ -1,10 +1,12 @@
 2-package pkg
 3+package lists
 4 
 5 import (
 6 	"fmt"
 7 	"html/template"
 8 	"strings"
 9 	"time"
10+
11+	"github.com/araddon/dateparse"
12 )
13 
14 type ParsedText struct {
15@@ -73,7 +75,7 @@ func SplitByNewline(text string) []string {
16 }
17 
18 func PublishAtDate(date string) (*time.Time, error) {
19-	t, err := time.Parse("2006-01-02", date)
20+	t, err := dateparse.ParseStrict(date)
21 	return &t, err
22 }
23 
M lists/scp_hooks.go
+1, -2
 1@@ -5,7 +5,6 @@ import (
 2 	"strings"
 3 
 4 	"git.sr.ht/~erock/pico/filehandlers"
 5-	"git.sr.ht/~erock/pico/lists/pkg"
 6 	"git.sr.ht/~erock/pico/shared"
 7 	"golang.org/x/exp/slices"
 8 )
 9@@ -37,7 +36,7 @@ func (p *ListHooks) FileValidate(text string, filename string) (bool, error) {
10 }
11 
12 func (p *ListHooks) FileMeta(text string, data *filehandlers.PostMetaData) error {
13-	parsedText := pkg.ParseText(text)
14+	parsedText := ParseText(text)
15 
16 	if parsedText.MetaData.Title != "" {
17 		data.Title = parsedText.MetaData.Title
M prose/parser.go
+2, -8
 1@@ -3,11 +3,11 @@ package prose
 2 import (
 3 	"bytes"
 4 	"fmt"
 5-	"regexp"
 6 	"strings"
 7 	"time"
 8 
 9 	"github.com/alecthomas/chroma/formatters/html"
10+	"github.com/araddon/dateparse"
11 	"github.com/yuin/goldmark"
12 	highlighting "github.com/yuin/goldmark-highlighting"
13 	meta "github.com/yuin/goldmark-meta"
14@@ -92,8 +92,6 @@ func toTags(obj interface{}) ([]string, error) {
15 	return arr, nil
16 }
17 
18-var reTimestamp = regexp.MustCompile(`T.+`)
19-
20 func ParseText(text string) (*ParsedText, error) {
21 	parsed := ParsedText{
22 		MetaData: &MetaData{
23@@ -127,11 +125,7 @@ func ParseText(text string) (*ParsedText, error) {
24 	var err error
25 	date := toString(metaData["date"])
26 	if date != "" {
27-		if strings.Contains(date, "T") {
28-			date = reTimestamp.ReplaceAllString(date, "")
29-		}
30-
31-		nextDate, err := time.Parse("2006-01-02", date)
32+		nextDate, err := dateparse.ParseStrict(date)
33 		if err != nil {
34 			return &parsed, err
35 		}