repos / pico

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

commit
0f04902
parent
d177fb9
author
Eric Bower
date
2022-07-31 01:05:38 +0000 UTC
fix: adjusted slug migration

We need to ensure that the prod db has the correct filenames since we
are not including the extension in the record.

We also updated all the post urls to use the slug field.
10 files changed,  +37, -33
M db/migrations/20220730_post_change_filename_to_slug.sql
+4, -1
1@@ -1,3 +1,6 @@
2 ALTER TABLE posts ADD COLUMN slug character varying(255) NOT NULL DEFAULT '';
3-ALTER TABLE posts ADD CONSTRAINT unique_slug_for_user UNIQUE (user_id, cur_space, slug);
4 UPDATE posts SET slug = filename;
5+UPDATE posts SET filename = '_styles.css' WHERE filename = '_styles' AND cur_space = 'prose';
6+UPDATE posts SET filename = filename || '.md' WHERE filename <> '_styles.css' AND cur_space = 'prose';
7+UPDATE posts SET filename = filename || '.txt' WHERE cur_space = 'lists';
8+ALTER TABLE posts ADD CONSTRAINT unique_slug_for_user UNIQUE (user_id, cur_space, slug);
M filehandlers/post_handler.go
+1, -1
1@@ -158,5 +158,5 @@ func (h *ScpUploadHandler) Write(s ssh.Session, entry *utils.FileEntry) (string,
2 		}
3 	}
4 
5-	return h.Cfg.FullPostURL(user.Name, filename, h.Cfg.IsSubdomains(), true), nil
6+	return h.Cfg.FullPostURL(user.Name, metadata.Slug, h.Cfg.IsSubdomains(), true), nil
7 }
M lists/api.go
+7, -7
 1@@ -208,7 +208,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 2 			}
 3 		} else {
 4 			p := PostItemData{
 5-				URL:            template.URL(cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)),
 6+				URL:            template.URL(cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)),
 7 				BlogURL:        template.URL(cfg.FullBlogURL(post.Username, onSubdomain, withUserName)),
 8 				Title:          shared.FilenameToTitle(post.Filename, post.Title),
 9 				PublishAt:      post.PublishAt.Format("02 Jan, 2006"),
10@@ -306,7 +306,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
11 		data = PostPageData{
12 			Site:         *cfg.GetSiteData(),
13 			PageTitle:    GetPostTitle(post),
14-			URL:          template.URL(cfg.PostURL(post.Username, post.Filename)),
15+			URL:          template.URL(cfg.PostURL(post.Username, post.Slug)),
16 			BlogURL:      template.URL(cfg.BlogURL(username)),
17 			Description:  post.Description,
18 			ListType:     parsedText.MetaData.ListType,
19@@ -427,7 +427,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
20 	}
21 	for _, post := range pager.Data {
22 		item := PostItemData{
23-			URL:            template.URL(cfg.PostURL(post.Username, post.Filename)),
24+			URL:            template.URL(cfg.PostURL(post.Username, post.Slug)),
25 			BlogURL:        template.URL(cfg.BlogURL(post.Username)),
26 			Title:          shared.FilenameToTitle(post.Filename, post.Title),
27 			Description:    post.Description,
28@@ -520,9 +520,9 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
29 		}
30 
31 		item := &feeds.Item{
32-			Id:      cfg.PostURL(post.Username, post.Filename),
33+			Id:      cfg.PostURL(post.Username, post.Slug),
34 			Title:   shared.FilenameToTitle(post.Filename, post.Title),
35-			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Filename)},
36+			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Slug)},
37 			Content: tpl.String(),
38 			Created: *post.PublishAt,
39 		}
40@@ -591,9 +591,9 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
41 		}
42 
43 		item := &feeds.Item{
44-			Id:      cfg.PostURL(post.Username, post.Filename),
45+			Id:      cfg.PostURL(post.Username, post.Slug),
46 			Title:   post.Title,
47-			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Filename)},
48+			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Slug)},
49 			Content: tpl.String(),
50 			Created: *post.PublishAt,
51 		}
M lists/gemini/gemini.go
+7, -7
 1@@ -131,7 +131,7 @@ func blogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
 2 			}
 3 		} else {
 4 			p := lists.PostItemData{
 5-				URL:            html.URL(cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)),
 6+				URL:            html.URL(cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)),
 7 				BlogURL:        html.URL(cfg.FullBlogURL(post.Username, onSubdomain, withUserName)),
 8 				Title:          shared.FilenameToTitle(post.Filename, post.Title),
 9 				PublishAt:      post.PublishAt.Format("02 Jan, 2006"),
10@@ -209,7 +209,7 @@ func readHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
11 
12 	for _, post := range pager.Data {
13 		item := lists.PostItemData{
14-			URL:            html.URL(cfg.PostURL(post.Username, post.Filename)),
15+			URL:            html.URL(cfg.PostURL(post.Username, post.Slug)),
16 			BlogURL:        html.URL(cfg.BlogURL(post.Username)),
17 			Title:          shared.FilenameToTitle(post.Filename, post.Title),
18 			Description:    post.Description,
19@@ -281,7 +281,7 @@ func postHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request
20 	data := lists.PostPageData{
21 		Site:         *cfg.GetSiteData(),
22 		PageTitle:    lists.GetPostTitle(post),
23-		URL:          html.URL(cfg.PostURL(post.Username, post.Filename)),
24+		URL:          html.URL(cfg.PostURL(post.Username, post.Slug)),
25 		BlogURL:      html.URL(cfg.BlogURL(username)),
26 		Description:  post.Description,
27 		ListType:     parsedText.MetaData.ListType,
28@@ -417,9 +417,9 @@ func rssBlogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Requ
29 		}
30 
31 		item := &feeds.Item{
32-			Id:      cfg.PostURL(post.Username, post.Filename),
33+			Id:      cfg.PostURL(post.Username, post.Slug),
34 			Title:   shared.FilenameToTitle(post.Filename, post.Title),
35-			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Filename)},
36+			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Slug)},
37 			Content: tpl.String(),
38 			Created: *post.PublishAt,
39 		}
40@@ -489,9 +489,9 @@ func rssHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request)
41 		}
42 
43 		item := &feeds.Item{
44-			Id:      cfg.PostURL(post.Username, post.Filename),
45+			Id:      cfg.PostURL(post.Username, post.Slug),
46 			Title:   post.Title,
47-			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Filename)},
48+			Link:    &feeds.Link{Href: cfg.PostURL(post.Username, post.Slug)},
49 			Content: tpl.String(),
50 			Created: *post.PublishAt,
51 		}
M makefile
+2, -1
 1@@ -59,10 +59,11 @@ migrate:
 2 	docker exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./db/migrations/20220721_analytics.sql
 3 	docker exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./db/migrations/20220722_post_hidden.sql
 4 	docker exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./db/migrations/20220727_post_change_post_contraints.sql
 5+	docker exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./db/migrations/20220730_post_change_filename_to_slug.sql
 6 .PHONY: migrate
 7 
 8 latest:
 9-	docker exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./db/migrations/20220727_post_change_post_contraints.sql
10+	docker exec -i $(DB_CONTAINER) psql -U $(PGUSER) -d $(PGDATABASE) < ./db/migrations/20220730_post_change_filename_to_slug.sql
11 .PHONY: latest
12 
13 psql:
M pastes/api.go
+3, -3
 1@@ -166,7 +166,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 2 	postCollection := make([]PostItemData, 0, len(posts))
 3 	for _, post := range posts {
 4 		p := PostItemData{
 5-			URL:            template.URL(cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)),
 6+			URL:            template.URL(cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)),
 7 			BlogURL:        template.URL(cfg.FullBlogURL(post.Username, onSubdomain, withUserName)),
 8 			Title:          shared.FilenameToTitle(post.Filename, post.Title),
 9 			PublishAt:      post.PublishAt.Format("02 Jan, 2006"),
10@@ -241,8 +241,8 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
11 		data = PostPageData{
12 			Site:         *cfg.GetSiteData(),
13 			PageTitle:    GetPostTitle(post),
14-			URL:          template.URL(cfg.PostURL(post.Username, post.Filename)),
15-			RawURL:       template.URL(cfg.RawPostURL(post.Username, post.Filename)),
16+			URL:          template.URL(cfg.PostURL(post.Username, post.Slug)),
17+			RawURL:       template.URL(cfg.RawPostURL(post.Username, post.Slug)),
18 			BlogURL:      template.URL(cfg.BlogURL(username)),
19 			Description:  post.Description,
20 			Title:        shared.FilenameToTitle(post.Filename, post.Title),
M prose/api.go
+5, -5
 1@@ -238,7 +238,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 2 			}
 3 		} else {
 4 			p := PostItemData{
 5-				URL:            template.URL(cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)),
 6+				URL:            template.URL(cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)),
 7 				BlogURL:        template.URL(cfg.FullBlogURL(post.Username, onSubdomain, withUserName)),
 8 				Title:          shared.FilenameToTitle(post.Filename, post.Title),
 9 				PublishAt:      post.PublishAt.Format("02 Jan, 2006"),
10@@ -389,7 +389,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
11 		data = PostPageData{
12 			Site:         *cfg.GetSiteData(),
13 			PageTitle:    GetPostTitle(post),
14-			URL:          template.URL(cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)),
15+			URL:          template.URL(cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)),
16 			BlogURL:      template.URL(cfg.FullBlogURL(username, onSubdomain, withUserName)),
17 			Description:  post.Description,
18 			Title:        shared.FilenameToTitle(post.Filename, post.Title),
19@@ -527,7 +527,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
20 	}
21 	for _, post := range pager.Data {
22 		item := PostItemData{
23-			URL:            template.URL(cfg.FullPostURL(post.Username, post.Filename, true, true)),
24+			URL:            template.URL(cfg.FullPostURL(post.Username, post.Slug, true, true)),
25 			BlogURL:        template.URL(cfg.FullBlogURL(post.Username, true, true)),
26 			Title:          shared.FilenameToTitle(post.Filename, post.Title),
27 			Description:    post.Description,
28@@ -627,7 +627,7 @@ func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
29 			continue
30 		}
31 
32-		realUrl := cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)
33+		realUrl := cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)
34 		if !onSubdomain && !withUserName {
35 			realUrl = fmt.Sprintf("%s://%s%s", cfg.Protocol, r.Host, realUrl)
36 		}
37@@ -709,7 +709,7 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
38 			continue
39 		}
40 
41-		realUrl := cfg.FullPostURL(post.Username, post.Filename, onSubdomain, withUserName)
42+		realUrl := cfg.FullPostURL(post.Username, post.Slug, onSubdomain, withUserName)
43 		if !onSubdomain && !withUserName {
44 			realUrl = fmt.Sprintf("%s://%s%s", cfg.Protocol, r.Host, realUrl)
45 		}
M shared/config.go
+6, -6
 1@@ -52,8 +52,8 @@ func (c *ConfigSite) FullBlogURL(username string, onSubdomain bool, withUserName
 2 	return "/"
 3 }
 4 
 5-func (c *ConfigSite) PostURL(username, filename string) string {
 6-	fname := url.PathEscape(filename)
 7+func (c *ConfigSite) PostURL(username, slug string) string {
 8+	fname := url.PathEscape(slug)
 9 	if c.IsSubdomains() {
10 		return fmt.Sprintf("%s://%s.%s/%s", c.Protocol, username, c.Domain, fname)
11 	}
12@@ -62,8 +62,8 @@ func (c *ConfigSite) PostURL(username, filename string) string {
13 
14 }
15 
16-func (c *ConfigSite) FullPostURL(username, filename string, onSubdomain bool, withUserName bool) string {
17-	fname := url.PathEscape(filename)
18+func (c *ConfigSite) FullPostURL(username, slug string, onSubdomain bool, withUserName bool) string {
19+	fname := url.PathEscape(slug)
20 	if c.IsSubdomains() && onSubdomain {
21 		return fmt.Sprintf("%s://%s.%s/%s", c.Protocol, username, c.Domain, fname)
22 	}
23@@ -123,8 +123,8 @@ func (c *ConfigSite) StaticPath(fname string) string {
24 	return path.Join(c.Space, fname)
25 }
26 
27-func (c *ConfigSite) RawPostURL(username, filename string) string {
28-	fname := url.PathEscape(filename)
29+func (c *ConfigSite) RawPostURL(username, slug string) string {
30+	fname := url.PathEscape(slug)
31 	if c.IsSubdomains() {
32 		return fmt.Sprintf("%s://%s.%s/raw/%s", c.Protocol, username, c.Domain, fname)
33 	}
M wish/cms/db/postgres/storage.go
+1, -1
1@@ -68,7 +68,7 @@ const (
2 	LIMIT $1 OFFSET $2`
3 
4 	sqlInsertPublicKey = `INSERT INTO public_keys (user_id, public_key) VALUES ($1, $2)`
5-	sqlInsertPost      = `INSERT INTO posts (user_id, filename, slug, title, text, description, publish_at, hidden, cur_space) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id`
6+	sqlInsertPost      = `INSERT INTO posts (user_id, filename, slug, title, text, description, publish_at, hidden, cur_space) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id`
7 	sqlInsertUser      = `INSERT INTO app_users DEFAULT VALUES returning id`
8 
9 	sqlUpdatePost     = `UPDATE posts SET slug = $1, title = $2, text = $3, description = $4, updated_at = $5, publish_at = $6 WHERE id = $7`
M wish/cms/ui/posts/post_view.go
+1, -1
1@@ -32,7 +32,7 @@ func (m Model) newStyledKey(styles common.Styles, post *db.Post, urls config.Con
2 		dateVal:   styles.LabelDim.Render(publishAt.Format("02 Jan, 2006")),
3 		title:     post.Title,
4 		urlLabel:  "url:",
5-		url:       urls.PostURL(post.Username, post.Filename),
6+		url:       urls.PostURL(post.Username, post.Slug),
7 	}
8 }
9