Skip to content

Commit

Permalink
Add editor option to update posts without setting updated timestamp
Browse files Browse the repository at this point in the history
  • Loading branch information
jlelse committed Dec 28, 2024
1 parent c37dec3 commit 2ccbb94
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 32 deletions.
5 changes: 4 additions & 1 deletion editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ func (a *goBlog) serveEditorPost(w http.ResponseWriter, r *http.Request) {
if action == "updatepost" {
reqBody["action"] = micropub.ActionUpdate
reqBody["url"] = r.FormValue("url")
reqBody["replace"] = map[string][]string{"content": {r.FormValue("content")}}
reqBody["replace"] = map[string][]string{
"content": {r.FormValue("content")},
"goblog-editor": r.Form["options"],
}
} else {
blog, _ := a.getBlog(r)
reqBody["type"] = []string{"h-entry"}
Expand Down
2 changes: 1 addition & 1 deletion editorWebsocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (a *goBlog) sendEditorPreview(ctx context.Context, c *ws.Conn, blog string,
_, werr := io.WriteString(w, err.Error())
return errors.Join(werr, w.Close())
}
if err := a.checkPost(p, true); err != nil {
if err := a.checkPost(p, true, true); err != nil {
_, werr := io.WriteString(w, err.Error())
return errors.Join(werr, w.Close())
}
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
git.jlel.se/jlelse/go-shutdowner v0.0.0-20210707065515-773db8099c30
git.jlel.se/jlelse/goldmark-mark v0.0.0-20210522162520-9788c89266a4
git.jlel.se/jlelse/template-strings v0.0.0-20220211095702-c012e3b5045b
github.com/PuerkitoBio/goquery v1.10.0
github.com/PuerkitoBio/goquery v1.10.1
github.com/alecthomas/chroma/v2 v2.14.0
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500
Expand All @@ -18,8 +18,8 @@ require (
github.com/elnormous/contenttype v1.0.4
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6
github.com/emersion/go-smtp v0.21.3
github.com/go-ap/activitypub v0.0.0-20241223153938-9c1f6077f836
github.com/go-ap/client v0.0.0-20241212174032-4826270ad6a3
github.com/go-ap/activitypub v0.0.0-20241228090954-75890bd9cfda
github.com/go-ap/client v0.0.0-20241228091406-581647f214a8
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
github.com/go-chi/chi/v5 v5.2.0
github.com/go-fed/httpsig v1.1.0
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ git.sr.ht/~mariusor/lw v0.0.0-20241117105956-4b4009e28502 h1:vHrLbbAzwxsIqPiIuYD
git.sr.ht/~mariusor/lw v0.0.0-20241117105956-4b4009e28502/go.mod h1:kXJ4JsgGBu7IVBKlrVvGjSLJmpsAGqZwq/JU/kTUaLw=
git.sr.ht/~mariusor/mask v0.0.0-20240327084502-ef2a9438457e h1:IrPLQI6txX0tCcdTBNjvF16UZk6SFb9MqyVE0TKVFJ4=
git.sr.ht/~mariusor/mask v0.0.0-20240327084502-ef2a9438457e/go.mod h1:Mw0HVQc45uMVOiZNDngXg6zQiO2h/yTsNhI5cm0uk3A=
github.com/PuerkitoBio/goquery v1.10.0 h1:6fiXdLuUvYs2OJSvNRqlNPoBm6YABE226xrbavY5Wv4=
github.com/PuerkitoBio/goquery v1.10.0/go.mod h1:TjZZl68Q3eGHNBA8CWaxAN7rOU1EbDz3CWuolcO5Yu4=
github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU=
github.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY=
github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
Expand Down Expand Up @@ -66,10 +66,10 @@ github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-ap/activitypub v0.0.0-20241223153938-9c1f6077f836 h1:LrcUX5TUtk5sRkSs7OE0gzXRBy4wU1nu6hC6plcniuc=
github.com/go-ap/activitypub v0.0.0-20241223153938-9c1f6077f836/go.mod h1:5UpNlwO44EF+iKBvyr2djy6vKwsvai9h6KH6N9OL2ZI=
github.com/go-ap/client v0.0.0-20241212174032-4826270ad6a3 h1:nMF0d9OEjUyaxNB1wvAvRILxVXklnc8nF0vegPLoNg8=
github.com/go-ap/client v0.0.0-20241212174032-4826270ad6a3/go.mod h1:aEowIV4wYt3Y6HexHcRA9JfSx08J8VemNR1RTd+TehQ=
github.com/go-ap/activitypub v0.0.0-20241228090954-75890bd9cfda h1:BcuDVID/DpaTdPn5jjuaS9d2U1g2/agTRNEQu+fgU6Q=
github.com/go-ap/activitypub v0.0.0-20241228090954-75890bd9cfda/go.mod h1:5UpNlwO44EF+iKBvyr2djy6vKwsvai9h6KH6N9OL2ZI=
github.com/go-ap/client v0.0.0-20241228091406-581647f214a8 h1:C15a668u8xRLBiWcq1cUjEH4Ykh8VvgJgsSFYBnsAME=
github.com/go-ap/client v0.0.0-20241228091406-581647f214a8/go.mod h1:zO+J2RiLS1yP2mmEnC1EQC9j4YNMrXUKsQXPXu8czSE=
github.com/go-ap/errors v0.0.0-20241212155021-5a598b6bf467 h1:sltFaR21xTEWIfw/UCfiNb2d7ET0YIQyTv4v1hVUlTw=
github.com/go-ap/errors v0.0.0-20241212155021-5a598b6bf467/go.mod h1:Vkh+Z3f24K8nMsJKXo1FHn5ebPsXvB/WDH5JRtYqdNo=
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw=
Expand Down
9 changes: 8 additions & 1 deletion micropub.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"path/filepath"
"reflect"
"regexp"
"slices"
"strings"

"github.com/samber/lo"
Expand Down Expand Up @@ -187,6 +188,11 @@ func (s *micropubImplementation) Create(req *micropub.Request) (string, error) {
}

func (s *micropubImplementation) Update(req *micropub.Request) (string, error) {
// Get editor options
editorOptions := req.Updates.Replace["goblog-editor"]
if editorOptions == nil {
editorOptions = []any{}
}
// Get post
url, err := urlpkg.Parse(req.URL)
if err != nil {
Expand Down Expand Up @@ -219,7 +225,7 @@ func (s *micropubImplementation) Update(req *micropub.Request) (string, error) {
if err != nil {
return "", fmt.Errorf("%w: %w", micropub.ErrBadRequest, err)
}
err = s.a.replacePost(entry, oldPath, oldStatus, oldVisibility)
err = s.a.replacePost(entry, oldPath, oldStatus, oldVisibility, slices.Contains(editorOptions, "noupdated"))
if err != nil {
return "", fmt.Errorf("%w: %w", micropub.ErrBadRequest, err)
}
Expand Down Expand Up @@ -407,6 +413,7 @@ func micropubVisibility(visibility string) postVisibility {

func micropubUpdateMfProperties(properties map[string][]any, req micropub.RequestUpdate) (map[string][]any, error) {
if req.Replace != nil {
delete(req.Replace, "goblog-editor")
for key, value := range req.Replace {
properties[key] = value
}
Expand Down
28 changes: 18 additions & 10 deletions postsDb.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"go.goblog.app/app/pkgs/builderpool"
)

func (a *goBlog) checkPost(p *post, new bool) (err error) {
func (a *goBlog) checkPost(p *post, new, noUpdated bool) (err error) {
if p == nil {
return errors.New("no post")
}
Expand Down Expand Up @@ -64,12 +64,14 @@ func (a *goBlog) checkPost(p *post, new bool) (err error) {
p.Published = nowString
}
// Maybe set updated date
if !new && p.Published != "" {
if new || noUpdated {
// Do nothing
} else if p.Published != "" {
if published, err := dateparse.ParseLocal(p.Published); err == nil && now.After(published) {
// Has published date in the past, so add updated date
p.Updated = nowString
}
} else if !new && p.Updated != "" {
} else if p.Updated != "" {
if updated, err := dateparse.ParseLocal(p.Updated); err == nil && now.After(updated) {
// Has updated date in the past, so add new updated date
p.Updated = nowString
Expand Down Expand Up @@ -158,20 +160,26 @@ func (a *goBlog) createPost(p *post) error {
return a.createOrReplacePost(p, &postCreationOptions{new: true})
}

func (a *goBlog) replacePost(p *post, oldPath string, oldStatus postStatus, oldVisibility postVisibility) error {
return a.createOrReplacePost(p, &postCreationOptions{new: false, oldPath: oldPath, oldStatus: oldStatus, oldVisibility: oldVisibility})
func (a *goBlog) replacePost(p *post, oldPath string, oldStatus postStatus, oldVisibility postVisibility, noUpdated bool) error {
return a.createOrReplacePost(p, &postCreationOptions{
new: false,
oldPath: oldPath,
oldStatus: oldStatus,
oldVisibility: oldVisibility,
noUpdated: noUpdated,
})
}

type postCreationOptions struct {
new bool
oldPath string
oldStatus postStatus
oldVisibility postVisibility
new, noUpdated bool
oldPath string
oldStatus postStatus
oldVisibility postVisibility
}

func (a *goBlog) createOrReplacePost(p *post, o *postCreationOptions) error {
// Check post
if err := a.checkPost(p, o.new); err != nil {
if err := a.checkPost(p, o.new, o.noUpdated); err != nil {
return err
}
// Save to db
Expand Down
16 changes: 8 additions & 8 deletions postsDb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ func Test_checkPost(t *testing.T) {

t.Run("New post should get published date", func(t *testing.T) {
p := &post{}
app.checkPost(p, true)
app.checkPost(p, true, false)

assert.NotEmpty(t, p.Published)
})
Expand All @@ -443,7 +443,7 @@ func Test_checkPost(t *testing.T) {
p := &post{
Path: "/abc",
}
app.checkPost(p, true)
app.checkPost(p, true, false)

assert.Empty(t, p.Published)
})
Expand All @@ -452,7 +452,7 @@ func Test_checkPost(t *testing.T) {
p := &post{
Published: time.Now().Local().Add(-1 * time.Hour).Format(time.RFC3339),
}
app.checkPost(p, false)
app.checkPost(p, false, false)

assert.NotEmpty(t, p.Updated)
})
Expand All @@ -461,7 +461,7 @@ func Test_checkPost(t *testing.T) {
p := &post{
Published: time.Now().Local().Add(time.Hour).Format(time.RFC3339),
}
app.checkPost(p, false)
app.checkPost(p, false, false)

assert.Empty(t, p.Updated)
})
Expand All @@ -472,7 +472,7 @@ func Test_checkPost(t *testing.T) {
Published: time.Now().Local().Add(-2 * time.Hour).Format(time.RFC3339),
Updated: oldUpdate,
}
app.checkPost(p, false)
app.checkPost(p, false, false)

assert.NotEmpty(t, p.Updated)
assert.NotEqual(t, oldUpdate, p.Updated)
Expand All @@ -483,7 +483,7 @@ func Test_checkPost(t *testing.T) {
p := &post{
Updated: oldUpdate,
}
app.checkPost(p, false)
app.checkPost(p, false, false)

assert.Empty(t, p.Published)
assert.NotEmpty(t, p.Updated)
Expand All @@ -494,7 +494,7 @@ func Test_checkPost(t *testing.T) {
p := &post{
Status: "unlisted",
}
err := app.checkPost(p, true)
err := app.checkPost(p, true, false)

assert.ErrorContains(t, err, "invalid post status")
})
Expand All @@ -503,7 +503,7 @@ func Test_checkPost(t *testing.T) {
p := &post{
Visibility: "published",
}
err := app.checkPost(p, true)
err := app.checkPost(p, true, false)

assert.ErrorContains(t, err, "invalid post visibility")
})
Expand Down
2 changes: 1 addition & 1 deletion postsScheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (a *goBlog) checkScheduledPosts() {
}
for _, post := range postsToPublish {
post.Status = statusPublished
err := a.replacePost(post, post.Path, statusScheduled, post.Visibility)
err := a.replacePost(post, post.Path, statusScheduled, post.Visibility, true)
if err != nil {
a.error("Error publishing scheduled post", "err", err)
continue
Expand Down
6 changes: 6 additions & 0 deletions postsScheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@ func Test_postsScheduler(t *testing.T) {
assert.Equal(t, 1, postHook)
assert.Equal(t, 0, updateHook)

// Check that the published post has no updated date
p, err := app.db.a.getPost("/test/abc")
require.NoError(t, err)
assert.NotEmpty(t, p.Published)
assert.Empty(t, p.Updated)

}
2 changes: 1 addition & 1 deletion reactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Test_reactionsLowLevel(t *testing.T) {
Path: "/newpost",
Content: "test",
Status: statusPublished,
}, "/testpost", statusPublished, visibilityPublic)
}, "/testpost", statusPublished, visibilityPublic, false)
require.NoError(t, err)

// Check if reaction count is 4
Expand Down
1 change: 1 addition & 0 deletions strings/de.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ deletedposts: "Gelöschte Posts"
deletedpostsdesc: "Gelöschte Posts, die nach 7 Tagen endgültig gelöscht werden."
deletepasskey: "Passkey löschen"
docomment: "Kommentieren"
donotsetupdated: "Den Aktualisierungszeitstempel nicht ändern"
download: "Herunterladen"
drafts: "Entwürfe"
draftsdesc: "Posts mit dem Status `draft`."
Expand Down
1 change: 1 addition & 0 deletions strings/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ deletedposts: "Deleted posts"
deletedpostsdesc: "Deleted posts that will be permanently deleted after 7 days."
deletepasskey: "Delete Passkey"
docomment: "Comment"
donotsetupdated: "Do not change the update timestamp"
download: "Download"
drafts: "Drafts"
draftsdesc: "Posts with status `draft`."
Expand Down
3 changes: 3 additions & 0 deletions ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,9 @@ func (a *goBlog) renderEditor(hb *htmlbuilder.HtmlBuilder, rd *renderData) {
)
hb.WriteEscaped(edrd.updatePostContent)
hb.WriteElementClose("textarea")
hb.WriteElementOpen("input", "type", "checkbox", "name", "options", "value", "noupdated")
hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "donotsetupdated"))
hb.WriteElementClose("input")
hb.WriteElementOpen("div", "id", "update-preview", "class", "hide")
hb.WriteElementClose("div")
hb.WriteElementOpen("input", "type", "submit", "value", a.ts.GetTemplateStringVariant(rd.Blog.Lang, "update"))
Expand Down

0 comments on commit 2ccbb94

Please sign in to comment.