Improved timehandling (save everything as UTC) and new post status: unlisted and private

This commit is contained in:
Jan-Lukas Else 2021-07-14 15:44:57 +02:00
parent eecc3a7d35
commit caf21a07fd
17 changed files with 123 additions and 72 deletions

View File

@ -63,7 +63,7 @@ with filtered as (
from ( from (
select select
path, path,
coalesce(published, '') as pub, tolocal(published) as pub,
mdtext(coalesce(content, '')) as content mdtext(coalesce(content, '')) as content
from posts from posts
where status = @status and blog = @blog where status = @status and blog = @blog

View File

@ -30,7 +30,7 @@ func Test_captchaMiddleware(t *testing.T) {
}, },
} }
app.initDatabase(false) _ = app.initDatabase(false)
app.initSessions() app.initSessions()
_ = app.initTemplateStrings() _ = app.initTemplateStrings()
_ = app.initRendering() _ = app.initRendering()

View File

@ -22,7 +22,7 @@ func (a *goBlog) checkAllExternalLinks() {
log.Println(err.Error()) log.Println(err.Error())
return return
} }
a.checkLinks(log.Writer(), posts...) _ = a.checkLinks(log.Writer(), posts...)
} }
func (a *goBlog) checkLinks(w io.Writer, posts ...*post) error { func (a *goBlog) checkLinks(w io.Writer, posts ...*post) error {

View File

@ -230,18 +230,20 @@ func migrateDb(db *sql.DB, logging bool) error {
return err return err
}, },
}, },
&migrator.Migration{
Name: "00019",
Func: func(tx *sql.Tx) error {
_, err := tx.Exec(`
update posts set published = toutc(published), updated = toutc(updated);
insert into posts_fts(posts_fts) values ('rebuild');
`)
return err
},
},
), ),
) )
if err != nil { if err != nil {
return err return err
} }
err = m.Migrate(db) return m.Migrate(db)
if err != nil {
return err
}
// Update times in database to local time
_, err = db.Exec(`
update posts set published = tolocal(published), updated = tolocal(updated);
`)
return err
} }

View File

@ -17,9 +17,7 @@ func (a *goBlog) serveEditor(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string) blog := r.Context().Value(blogContextKey).(string)
a.render(w, r, templateEditor, &renderData{ a.render(w, r, templateEditor, &renderData{
BlogString: blog, BlogString: blog,
Data: map[string]interface{}{ Data: map[string]interface{}{},
"Drafts": a.db.getDrafts(blog),
},
}) })
} }
@ -32,7 +30,6 @@ func (a *goBlog) serveEditorPost(w http.ResponseWriter, r *http.Request) {
BlogString: blog, BlogString: blog,
Data: map[string]interface{}{ Data: map[string]interface{}{
"DeleteURL": r.FormValue("url"), "DeleteURL": r.FormValue("url"),
"Drafts": a.db.getDrafts(blog),
}, },
}) })
case "loadupdate": case "loadupdate":
@ -51,7 +48,6 @@ func (a *goBlog) serveEditorPost(w http.ResponseWriter, r *http.Request) {
Data: map[string]interface{}{ Data: map[string]interface{}{
"UpdatePostURL": parsedURL.String(), "UpdatePostURL": parsedURL.String(),
"UpdatePostContent": a.postToMfItem(post).Properties.Content[0], "UpdatePostContent": a.postToMfItem(post).Properties.Content[0],
"Drafts": a.db.getDrafts(blog),
}, },
}) })
case "updatepost": case "updatepost":
@ -77,14 +73,6 @@ func (a *goBlog) serveEditorPost(w http.ResponseWriter, r *http.Request) {
a.editorMicropubPost(w, req, false) a.editorMicropubPost(w, req, false)
case "upload": case "upload":
a.editorMicropubPost(w, r, true) a.editorMicropubPost(w, r, true)
case "viewdraft":
parsedURL, err := url.Parse(r.FormValue("url"))
if err != nil {
a.serveError(w, r, err.Error(), http.StatusBadRequest)
return
}
http.Redirect(w, r, parsedURL.Path, http.StatusFound)
return
default: default:
a.serveError(w, r, "Unknown editoraction", http.StatusBadRequest) a.serveError(w, r, "Unknown editoraction", http.StatusBadRequest)
} }

2
go.mod
View File

@ -32,7 +32,7 @@ require (
github.com/jonboulle/clockwork v0.2.2 // indirect github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9 github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/lestrrat-go/strftime v1.0.5 // indirect
github.com/lib/pq v1.9.0 // indirect github.com/lib/pq v1.9.0 // indirect
github.com/lopezator/migrator v0.3.0 github.com/lopezator/migrator v0.3.0
github.com/mattn/go-sqlite3 v1.14.7 github.com/mattn/go-sqlite3 v1.14.7

4
go.sum
View File

@ -273,8 +273,8 @@ github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2t
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4= github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= github.com/lestrrat-go/strftime v1.0.5 h1:A7H3tT8DhTz8u65w+JRpiBxM4dINQhUXAZnhBa2xeOE=
github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= github.com/lestrrat-go/strftime v1.0.5/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=

40
http.go
View File

@ -198,6 +198,15 @@ func (a *goBlog) buildStaticHandlersRouters() error {
a.editorRouter.Get("/files", a.serveEditorFiles) a.editorRouter.Get("/files", a.serveEditorFiles)
a.editorRouter.Post("/files/view", a.serveEditorFilesView) a.editorRouter.Post("/files/view", a.serveEditorFilesView)
a.editorRouter.Post("/files/delete", a.serveEditorFilesDelete) a.editorRouter.Post("/files/delete", a.serveEditorFilesDelete)
a.editorRouter.Get("/drafts", a.serveDrafts)
a.editorRouter.Get("/drafts"+feedPath, a.serveDrafts)
a.editorRouter.Get("/drafts"+paginationPath, a.serveDrafts)
a.editorRouter.Get("/private", a.servePrivate)
a.editorRouter.Get("/private"+feedPath, a.servePrivate)
a.editorRouter.Get("/private"+paginationPath, a.servePrivate)
a.editorRouter.Get("/unlisted", a.serveUnlisted)
a.editorRouter.Get("/unlisted"+feedPath, a.serveUnlisted)
a.editorRouter.Get("/unlisted"+paginationPath, a.serveUnlisted)
a.commentsRouter = chi.NewRouter() a.commentsRouter = chi.NewRouter()
a.commentsRouter.Use(a.privateModeHandler...) a.commentsRouter.Use(a.privateModeHandler...)
@ -331,7 +340,7 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
r.Mount(notificationsPath, a.notificationsRouter) r.Mount(notificationsPath, a.notificationsRouter)
// Posts // Posts
pp, err := a.db.allPostPaths(statusPublished) pp, err := a.db.getPostPaths(statusPublished)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -343,8 +352,33 @@ func (a *goBlog) buildDynamicRouter() (*chi.Mux, error) {
} }
}) })
// Drafts // Unlisted posts
dp, err := a.db.allPostPaths(statusDraft) up, err := a.db.getPostPaths(statusUnlisted)
if err != nil {
return nil, err
}
r.Group(func(r chi.Router) {
r.Use(a.privateModeHandler...)
r.Use(a.checkActivityStreamsRequest, a.cache.cacheMiddleware)
for _, path := range up {
r.Get(path, a.servePost)
}
})
// Private posts
priv, err := a.db.getPostPaths(statusPrivate)
if err != nil {
return nil, err
}
r.Group(func(r chi.Router) {
r.Use(a.authMiddleware)
for _, path := range priv {
r.Get(path, a.servePost)
}
})
// Draft posts
dp, err := a.db.getPostPaths(statusDraft)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -40,6 +40,8 @@ const (
statusNil postStatus = "" statusNil postStatus = ""
statusPublished postStatus = "published" statusPublished postStatus = "published"
statusDraft postStatus = "draft" statusDraft postStatus = "draft"
statusPrivate postStatus = "private"
statusUnlisted postStatus = "unlisted"
) )
func (a *goBlog) servePost(w http.ResponseWriter, r *http.Request) { func (a *goBlog) servePost(w http.ResponseWriter, r *http.Request) {
@ -121,6 +123,33 @@ func (a *goBlog) serveHome(w http.ResponseWriter, r *http.Request) {
}))) })))
} }
func (a *goBlog) serveDrafts(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string)
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
path: a.getRelativePath(blog, "/editor/drafts"),
title: a.ts.GetTemplateStringVariant(a.cfg.Blogs[blog].Lang, "drafts"),
status: statusDraft,
})))
}
func (a *goBlog) servePrivate(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string)
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
path: a.getRelativePath(blog, "/editor/private"),
title: a.ts.GetTemplateStringVariant(a.cfg.Blogs[blog].Lang, "privateposts"),
status: statusPrivate,
})))
}
func (a *goBlog) serveUnlisted(w http.ResponseWriter, r *http.Request) {
blog := r.Context().Value(blogContextKey).(string)
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
path: a.getRelativePath(blog, "/editor/unlisted"),
title: a.ts.GetTemplateStringVariant(a.cfg.Blogs[blog].Lang, "unlistedposts"),
status: statusUnlisted,
})))
}
func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) { func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) {
var year, month, day int var year, month, day int
if ys := chi.URLParam(r, "year"); ys != "" && ys != "x" { if ys := chi.URLParam(r, "year"); ys != "" && ys != "x" {
@ -176,6 +205,7 @@ type indexConfig struct {
title string title string
description string description string
summaryTemplate string summaryTemplate string
status postStatus
} }
const defaultPhotosPath = "/photos" const defaultPhotosPath = "/photos"
@ -203,6 +233,10 @@ func (a *goBlog) serveIndex(w http.ResponseWriter, r *http.Request) {
sections = append(sections, sectionKey) sections = append(sections, sectionKey)
} }
} }
status := ic.status
if status == statusNil {
status = statusPublished
}
p := paginator.New(&postPaginationAdapter{config: &postsRequestConfig{ p := paginator.New(&postPaginationAdapter{config: &postsRequestConfig{
blog: blog, blog: blog,
sections: sections, sections: sections,
@ -213,7 +247,7 @@ func (a *goBlog) serveIndex(w http.ResponseWriter, r *http.Request) {
publishedYear: ic.year, publishedYear: ic.year,
publishedMonth: ic.month, publishedMonth: ic.month,
publishedDay: ic.day, publishedDay: ic.day,
status: statusPublished, status: status,
priorityOrder: true, priorityOrder: true,
}, db: a.db}, a.cfg.Blogs[blog].Pagination) }, db: a.db}, a.cfg.Blogs[blog].Pagination)
p.SetPage(pageNo) p.SetPage(pageNo)

View File

@ -132,7 +132,7 @@ func (a *goBlog) createOrReplacePost(p *post, o *postCreationOptions) error {
} }
// Trigger hooks // Trigger hooks
if p.Status == statusPublished { if p.Status == statusPublished {
if o.new || o.oldStatus == statusDraft { if o.new || o.oldStatus != statusPublished {
defer a.postPostHooks(p) defer a.postPostHooks(p)
} else { } else {
defer a.postUpdateHooks(p) defer a.postUpdateHooks(p)
@ -163,7 +163,7 @@ func (db *database) savePost(p *post, o *postCreationOptions) error {
} }
// Insert new post // Insert new post
sqlBuilder.WriteString("insert into posts (path, content, published, updated, blog, section, status, priority) values (?, ?, ?, ?, ?, ?, ?, ?);") sqlBuilder.WriteString("insert into posts (path, content, published, updated, blog, section, status, priority) values (?, ?, ?, ?, ?, ?, ?, ?);")
sqlArgs = append(sqlArgs, p.Path, p.Content, p.Published, p.Updated, p.Blog, p.Section, p.Status, p.Priority) sqlArgs = append(sqlArgs, p.Path, p.Content, toUTCSafe(p.Published), toUTCSafe(p.Updated), p.Blog, p.Section, p.Status, p.Priority)
// Insert post parameters // Insert post parameters
for param, value := range p.Parameters { for param, value := range p.Parameters {
for _, value := range value { for _, value := range value {
@ -278,15 +278,15 @@ func buildPostsQuery(c *postsRequestConfig, selection string) (query string, arg
wheres = append(wheres, ws) wheres = append(wheres, ws)
} }
if c.publishedYear != 0 { if c.publishedYear != 0 {
wheres = append(wheres, "substr(published, 1, 4) = @publishedyear") wheres = append(wheres, "substr(tolocal(published), 1, 4) = @publishedyear")
args = append(args, sql.Named("publishedyear", fmt.Sprintf("%0004d", c.publishedYear))) args = append(args, sql.Named("publishedyear", fmt.Sprintf("%0004d", c.publishedYear)))
} }
if c.publishedMonth != 0 { if c.publishedMonth != 0 {
wheres = append(wheres, "substr(published, 6, 2) = @publishedmonth") wheres = append(wheres, "substr(tolocal(published), 6, 2) = @publishedmonth")
args = append(args, sql.Named("publishedmonth", fmt.Sprintf("%02d", c.publishedMonth))) args = append(args, sql.Named("publishedmonth", fmt.Sprintf("%02d", c.publishedMonth)))
} }
if c.publishedDay != 0 { if c.publishedDay != 0 {
wheres = append(wheres, "substr(published, 9, 2) = @publishedday") wheres = append(wheres, "substr(tolocal(published), 9, 2) = @publishedday")
args = append(args, sql.Named("publishedday", fmt.Sprintf("%02d", c.publishedDay))) args = append(args, sql.Named("publishedday", fmt.Sprintf("%02d", c.publishedDay)))
} }
if len(wheres) > 0 { if len(wheres) > 0 {
@ -385,11 +385,6 @@ func (d *database) getPost(path string) (*post, error) {
return posts[0], nil return posts[0], nil
} }
func (d *database) getDrafts(blog string) []*post {
ps, _ := d.getPosts(&postsRequestConfig{status: statusDraft, blog: blog})
return ps
}
func (d *database) countPosts(config *postsRequestConfig) (count int, err error) { func (d *database) countPosts(config *postsRequestConfig) (count int, err error) {
query, params := buildPostsQuery(config, "path") query, params := buildPostsQuery(config, "path")
row, err := d.queryRow("select count(distinct path) from ("+query+")", params...) row, err := d.queryRow("select count(distinct path) from ("+query+")", params...)
@ -400,7 +395,7 @@ func (d *database) countPosts(config *postsRequestConfig) (count int, err error)
return return
} }
func (d *database) allPostPaths(status postStatus) ([]string, error) { func (d *database) getPostPaths(status postStatus) ([]string, error) {
var postPaths []string var postPaths []string
rows, err := d.query("select path from posts where status = @status", sql.Named("status", status)) rows, err := d.query("select path from posts where status = @status", sql.Named("status", status))
if err != nil { if err != nil {
@ -456,7 +451,7 @@ type publishedDate struct {
} }
func (d *database) allPublishedDates(blog string) (dates []publishedDate, err error) { func (d *database) allPublishedDates(blog string) (dates []publishedDate, err error) {
rows, err := d.query("select distinct substr(published, 1, 4) as year, substr(published, 6, 2) as month, substr(published, 9, 2) as day from posts where blog = @blog and status = @status and year != '' and month != '' and day != ''", sql.Named("blog", blog), sql.Named("status", statusPublished)) rows, err := d.query("select distinct substr(tolocal(published), 1, 4) as year, substr(tolocal(published), 6, 2) as month, substr(tolocal(published), 9, 2) as day from posts where blog = @blog and status = @status and year != '' and month != '' and day != ''", sql.Named("blog", blog), sql.Named("status", statusPublished))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -28,7 +28,7 @@ func Test_postsDb(t *testing.T) {
}, },
}, },
} }
app.initDatabase(false) _ = app.initDatabase(false)
now := toLocalSafe(time.Now().String()) now := toLocalSafe(time.Now().String())
nowPlus1Hour := toLocalSafe(time.Now().Add(1 * time.Hour).String()) nowPlus1Hour := toLocalSafe(time.Now().Add(1 * time.Hour).String())
@ -64,18 +64,21 @@ func Test_postsDb(t *testing.T) {
is.Equal([]string{"C", "A", "B"}, p.Parameters["tags"]) is.Equal([]string{"C", "A", "B"}, p.Parameters["tags"])
// Check number of post paths // Check number of post paths
pp, err := app.db.allPostPaths(statusDraft) pp, err := app.db.getPostPaths(statusDraft)
must.NoError(err) must.NoError(err)
if is.Len(pp, 1) { if is.Len(pp, 1) {
is.Equal("/test/abc", pp[0]) is.Equal("/test/abc", pp[0])
} }
pp, err = app.db.allPostPaths(statusPublished) pp, err = app.db.getPostPaths(statusPublished)
must.NoError(err) must.NoError(err)
is.Len(pp, 0) is.Len(pp, 0)
// Check drafts // Check drafts
drafts := app.db.getDrafts("en") drafts, _ := app.db.getPosts(&postsRequestConfig{
blog: "en",
status: statusDraft,
})
is.Len(drafts, 1) is.Len(drafts, 1)
// Check by parameter // Check by parameter
@ -222,7 +225,7 @@ func Test_ftsWithoutTitle(t *testing.T) {
}, },
}, },
} }
app.initDatabase(false) _ = app.initDatabase(false)
err := app.db.savePost(&post{ err := app.db.savePost(&post{
Path: "/test/abc", Path: "/test/abc",
@ -252,7 +255,7 @@ func Test_postsPriority(t *testing.T) {
}, },
}, },
} }
app.initDatabase(false) _ = app.initDatabase(false)
err := app.db.savePost(&post{ err := app.db.savePost(&post{
Path: "/test/abc", Path: "/test/abc",
@ -301,7 +304,7 @@ func Test_usesOfMediaFile(t *testing.T) {
}, },
}, },
} }
app.initDatabase(false) _ = app.initDatabase(false)
err := app.db.savePost(&post{ err := app.db.savePost(&post{
Path: "/test/abc", Path: "/test/abc",

View File

@ -133,7 +133,7 @@ func Test_telegram(t *testing.T) {
}, },
httpClient: fakeClient, httpClient: fakeClient,
} }
app.initDatabase(false) _ = app.initDatabase(false)
app.initTelegram() app.initTelegram()
@ -177,7 +177,7 @@ func Test_telegram(t *testing.T) {
}, },
httpClient: fakeClient, httpClient: fakeClient,
} }
app.initDatabase(false) _ = app.initDatabase(false)
app.initTelegram() app.initTelegram()

View File

@ -44,6 +44,10 @@ tags:
<input type="submit" value="{{ string .Blog.Lang "delete" }}"> <input type="submit" value="{{ string .Blog.Lang "delete" }}">
{{ end }} {{ end }}
</form> </form>
<h2>{{ string .Blog.Lang "posts" }}</h2>
<p><a href="{{ .Blog.RelativePath "/editor/drafts" }}">{{ string .Blog.Lang "drafts" }}</a></p>
<p><a href="{{ .Blog.RelativePath "/editor/private" }}">{{ string .Blog.Lang "privateposts" }}</a></p>
<p><a href="{{ .Blog.RelativePath "/editor/unlisted" }}">{{ string .Blog.Lang "unlistedposts" }}</a></p>
<h2>{{ string .Blog.Lang "upload" }}</h2> <h2>{{ string .Blog.Lang "upload" }}</h2>
<form class="fw-form p" method="post" enctype="multipart/form-data"> <form class="fw-form p" method="post" enctype="multipart/form-data">
<input type="hidden" name="editoraction" value="upload"> <input type="hidden" name="editoraction" value="upload">
@ -51,18 +55,6 @@ tags:
<input type="submit" value="{{ string .Blog.Lang "upload" }}"> <input type="submit" value="{{ string .Blog.Lang "upload" }}">
</form> </form>
<p><a href="{{ .Blog.RelativePath "/editor/files" }}">{{ string .Blog.Lang "mediafiles" }}</a></p> <p><a href="{{ .Blog.RelativePath "/editor/files" }}">{{ string .Blog.Lang "mediafiles" }}</a></p>
{{ if .Data.Drafts }}
<h2>{{ string .Blog.Lang "drafts" }}</h2>
<form class="fw-form p" method="post">
<input type="hidden" name="editoraction" value="viewdraft">
<select name="url">
{{ range $i, $draft := .Data.Drafts }}
<option value="{{ absolute $draft.Path }}">{{ with ($draft.Title) }}{{ . }}{{ else }}{{ $draft.Path }}{{ end }}</option>
{{ end }}
</select>
<input type="submit" value="{{ string .Blog.Lang "view" }}">
</form>
{{ end }}
<h2>{{ string .Blog.Lang "location" }}</h2> <h2>{{ string .Blog.Lang "location" }}</h2>
<form class="fw-form p"> <form class="fw-form p">
<input id="geobtn" type="button" value="{{ string .Blog.Lang "locationget" }}" data-failed="{{ string .Blog.Lang "locationfailed" }}" data-notsupported="{{ string .Blog.Lang "locationnotsupported" }}"> <input id="geobtn" type="button" value="{{ string .Blog.Lang "locationget" }}" data-failed="{{ string .Blog.Lang "locationfailed" }}" data-notsupported="{{ string .Blog.Lang "locationnotsupported" }}">

View File

@ -29,6 +29,7 @@ oldcontent: "⚠️ Dieser Eintrag ist bereits über ein Jahr alt. Er ist mögli
pinned: "Angepinnt" pinned: "Angepinnt"
posts: "Posts" posts: "Posts"
prev: "Zurück" prev: "Zurück"
privateposts: "Private Posts"
publishedon: "Veröffentlicht am" publishedon: "Veröffentlicht am"
replyto: "Antwort an" replyto: "Antwort an"
search: "Suchen" search: "Suchen"
@ -40,6 +41,7 @@ stopspeak: "Vorlesen stoppen"
total: "Gesamt" total: "Gesamt"
translate: "Übersetzen" translate: "Übersetzen"
translations: "Übersetzungen" translations: "Übersetzungen"
unlistedposts: "Ungelistete Posts"
update: "Aktualisieren" update: "Aktualisieren"
updatedon: "Aktualisiert am" updatedon: "Aktualisiert am"
upload: "Hochladen" upload: "Hochladen"

View File

@ -41,6 +41,7 @@ password: "Password"
pinned: "Pinned" pinned: "Pinned"
posts: "Posts" posts: "Posts"
prev: "Previous" prev: "Previous"
privateposts: "Private posts"
publishedon: "Published on" publishedon: "Published on"
replyto: "Reply to" replyto: "Reply to"
reverify: "Reverify" reverify: "Reverify"
@ -56,6 +57,7 @@ total: "Total"
totp: "TOTP" totp: "TOTP"
translate: "Translate" translate: "Translate"
translations: "Translations" translations: "Translations"
unlistedposts: "Unlisted posts"
update: "Update" update: "Update"
updatedon: "Updated on" updatedon: "Updated on"
upload: "Upload" upload: "Upload"

View File

@ -34,9 +34,7 @@ type mention struct {
func (a *goBlog) initWebmention() { func (a *goBlog) initWebmention() {
// Add hooks // Add hooks
hookFunc := func(p *post) { hookFunc := func(p *post) {
if p.Status == statusPublished { _ = a.sendWebmentions(p)
_ = a.sendWebmentions(p)
}
} }
a.pPostHooks = append(a.pPostHooks, hookFunc) a.pPostHooks = append(a.pPostHooks, hookFunc)
a.pUpdateHooks = append(a.pUpdateHooks, hookFunc) a.pUpdateHooks = append(a.pUpdateHooks, hookFunc)

View File

@ -15,6 +15,10 @@ import (
) )
func (a *goBlog) sendWebmentions(p *post) error { func (a *goBlog) sendWebmentions(p *post) error {
if p.Status != statusPublished && p.Status != statusUnlisted {
// Not published or unlisted
return nil
}
if wm := a.cfg.Webmention; wm != nil && wm.DisableSending { if wm := a.cfg.Webmention; wm != nil && wm.DisableSending {
// Just ignore the mentions // Just ignore the mentions
return nil return nil
@ -43,10 +47,7 @@ func (a *goBlog) sendWebmentions(p *post) error {
// Private mode, don't send external mentions // Private mode, don't send external mentions
continue continue
} }
if wm := a.cfg.Webmention; wm != nil && wm.DisableSending { // Send webmention
// Just ignore the mention
continue
}
endpoint := a.discoverEndpoint(link) endpoint := a.discoverEndpoint(link)
if endpoint == "" { if endpoint == "" {
continue continue