diff --git a/activityPub.go b/activityPub.go index 877ad0b..d9110e3 100644 --- a/activityPub.go +++ b/activityPub.go @@ -383,28 +383,26 @@ func (db *database) apRemoveInbox(inbox string) error { } func (a *goBlog) apPost(p *post) { - blogConfig := a.cfg.Blogs[p.Blog] - note := a.toAPNote(p) - create := ap.CreateNew(a.activityPubId(p), note) - create.Actor = a.apAPIri(blogConfig) - create.Published = time.Now() - a.apSendToAllFollowers(p.Blog, create) + blogConfig := a.getBlogFromPost(p) + c := ap.CreateNew(a.activityPubId(p), a.toAPNote(p)) + c.Actor = a.apAPIri(blogConfig) + c.Published = time.Now() + a.apSendToAllFollowers(p.Blog, c) } func (a *goBlog) apUpdate(p *post) { - blogConfig := a.cfg.Blogs[p.Blog] - note := a.toAPNote(p) - update := ap.UpdateNew(a.activityPubId(p), note) - update.Actor = a.apAPIri(blogConfig) - update.Published = time.Now() - a.apSendToAllFollowers(p.Blog, update) + blogConfig := a.getBlogFromPost(p) + u := ap.UpdateNew(a.activityPubId(p), a.toAPNote(p)) + u.Actor = a.apAPIri(blogConfig) + u.Published = time.Now() + a.apSendToAllFollowers(p.Blog, u) } func (a *goBlog) apDelete(p *post) { - blogConfig := a.cfg.Blogs[p.Blog] - delete := ap.DeleteNew(a.apNewID(blogConfig), a.activityPubId(p)) - delete.Actor = a.apAPIri(blogConfig) - a.apSendToAllFollowers(p.Blog, delete) + blogConfig := a.getBlogFromPost(p) + d := ap.DeleteNew(a.apNewID(blogConfig), a.activityPubId(p)) + d.Actor = a.apAPIri(blogConfig) + a.apSendToAllFollowers(p.Blog, d) } func (a *goBlog) apUndelete(p *post) { diff --git a/activityStreams.go b/activityStreams.go index 968443e..1b579fb 100644 --- a/activityStreams.go +++ b/activityStreams.go @@ -48,7 +48,7 @@ func (a *goBlog) toAPNote(p *post) *ap.Note { note.MediaType = ap.MimeType(contenttype.HTML) note.ID = a.activityPubId(p) note.URL = ap.IRI(a.fullPostURL(p)) - note.AttributedTo = a.apAPIri(a.cfg.Blogs[p.Blog]) + note.AttributedTo = a.apAPIri(a.getBlogFromPost(p)) // Name and Type if title := p.RenderedTitle; title != "" { note.Type = ap.ArticleType diff --git a/comments.go b/comments.go index 42a213a..5bb6410 100644 --- a/comments.go +++ b/comments.go @@ -209,12 +209,12 @@ func (db *database) commentIdByOriginal(original string) (bool, int, error) { return true, id, nil } -func (a *goBlog) commentsEnabledForBlog(blog *configBlog) bool { +func (blog *configBlog) commentsEnabled() bool { return blog.Comments != nil && blog.Comments.Enabled } const commentsPostParam = "comments" func (a *goBlog) commentsEnabledForPost(post *post) bool { - return post != nil && a.commentsEnabledForBlog(a.getBlogFromPost(post)) && post.firstParameter(commentsPostParam) != "false" + return post != nil && a.getBlogFromPost(post).commentsEnabled() && post.firstParameter(commentsPostParam) != "false" } diff --git a/editor.go b/editor.go index 24fc77d..bfb3eee 100644 --- a/editor.go +++ b/editor.go @@ -82,7 +82,7 @@ func (a *goBlog) createMarkdownPreview(w io.Writer, blog string, markdown io.Rea } // Render post (using post's blog config) hb := htmlbuilder.NewHtmlBuilder(w) - a.renderEditorPreview(hb, a.cfg.Blogs[p.Blog], p) + a.renderEditorPreview(hb, a.getBlogFromPost(p), p) } func (a *goBlog) serveEditorPost(w http.ResponseWriter, r *http.Request) { diff --git a/editorState.go b/editorState.go index 0c44e35..0969c0d 100644 --- a/editorState.go +++ b/editorState.go @@ -68,7 +68,7 @@ func (a *goBlog) serveEditorStateSync(w http.ResponseWriter, r *http.Request) { } } -func (a *goBlog) sendNewEditorStateToAllConnections(ctx context.Context, bc *configBlog, origin string, state []byte) { +func (*goBlog) sendNewEditorStateToAllConnections(ctx context.Context, bc *configBlog, origin string, state []byte) { bc.esws.Range(func(key, value any) bool { if key == origin { return true diff --git a/geoTrack.go b/geoTrack.go index a3ccaab..d1b0e93 100644 --- a/geoTrack.go +++ b/geoTrack.go @@ -55,7 +55,7 @@ func (a *goBlog) getTrack(p *post, withMapFeatures bool) (result *trackResult, e return nil, nil } - l, _ := language.Parse(a.cfg.Blogs[p.Blog].Lang) + l, _ := language.Parse(a.getBlogFromPost(p).Lang) lp := message.NewPrinter(l) result = &trackResult{ diff --git a/indieAuthServer.go b/indieAuthServer.go index ad4159f..80cf36c 100644 --- a/indieAuthServer.go +++ b/indieAuthServer.go @@ -122,7 +122,7 @@ func (a *goBlog) indieAuthVerificationToken(w http.ResponseWriter, r *http.Reque // Token Revocation (new way) // https://indieauth.spec.indieweb.org/#token-revocation-p-4 -func (a *goBlog) indieAuthTokenRevokation(w http.ResponseWriter, r *http.Request) { +func (a *goBlog) indieAuthTokenRevokation(_ http.ResponseWriter, r *http.Request) { a.db.indieAuthRevokeToken(r.Form.Get("token")) } diff --git a/microformats.go b/microformats.go index 2d13644..dcfa8ad 100644 --- a/microformats.go +++ b/microformats.go @@ -1,8 +1,8 @@ package main import ( - "bytes" "context" + "io" "net/http" "net/url" "strings" @@ -50,25 +50,30 @@ func (a *goBlog) parseMicroformats(u string, cache bool) (*microformatsResult, e if err != nil { return nil, err } - return a.parseMicroformatsFromBytes(u, buf.Bytes()) + return parseMicroformatsFromReader(u, buf) } -func (a *goBlog) parseMicroformatsFromBytes(u string, b []byte) (*microformatsResult, error) { +func parseMicroformatsFromReader(u string, r io.Reader) (*microformatsResult, error) { parsedUrl, err := url.Parse(u) if err != nil { return nil, err } + // Temporary buffer + buf := bufferpool.Get() + defer bufferpool.Put(buf) + // Parse microformats m := µformatsResult{ source: u, } - // Fill from microformats - m.fillFromData(microformats.Parse(bytes.NewReader(b), parsedUrl)) + mfd := microformats.Parse(io.TeeReader(r, buf), parsedUrl) + m.fillFromData(mfd) + // Set URL if not parsed from microformats if m.Url == "" { m.Url = u } - // Set title when content is empty as well + // Parse title from HTML if needed if m.Title == "" && m.Content == "" { - doc, err := goquery.NewDocumentFromReader(bytes.NewReader(b)) + doc, err := goquery.NewDocumentFromReader(buf) if err != nil { return nil, err } diff --git a/postsDb.go b/postsDb.go index 899bbaa..325dfc1 100644 --- a/postsDb.go +++ b/postsDb.go @@ -30,11 +30,11 @@ func (a *goBlog) checkPost(p *post) (err error) { // Maybe add section if p.Path == "" && p.Section == "" { // Has no path or section -> default section - p.Section = a.cfg.Blogs[p.Blog].DefaultSection + p.Section = a.getBlogFromPost(p).DefaultSection } // Check section if p.Section != "" { - if _, ok := a.cfg.Blogs[p.Blog].Sections[p.Section]; !ok { + if _, ok := a.getBlogFromPost(p).Sections[p.Section]; !ok { return errors.New("section doesn't exist") } } @@ -87,7 +87,7 @@ func (a *goBlog) checkPost(p *post) (err error) { } // Automatically add reply title if replyLink := p.firstParameter(a.cfg.Micropub.ReplyParam); replyLink != "" && p.firstParameter(a.cfg.Micropub.ReplyTitleParam) == "" && - a.cfg.Blogs[p.Blog].addReplyTitle { + a.getBlogFromPost(p).addReplyTitle { // Is reply, but has no reply title if mf, err := a.parseMicroformats(replyLink, true); err == nil && mf.Title != "" { p.addParameter(a.cfg.Micropub.ReplyTitleParam, mf.Title) @@ -95,7 +95,7 @@ func (a *goBlog) checkPost(p *post) (err error) { } // Automatically add like title if likeLink := p.firstParameter(a.cfg.Micropub.LikeParam); likeLink != "" && p.firstParameter(a.cfg.Micropub.LikeTitleParam) == "" && - a.cfg.Blogs[p.Blog].addLikeTitle { + a.getBlogFromPost(p).addLikeTitle { // Is like, but has no like title if mf, err := a.parseMicroformats(likeLink, true); err == nil && mf.Title != "" { p.addParameter(a.cfg.Micropub.LikeTitleParam, mf.Title) @@ -114,7 +114,7 @@ func (a *goBlog) checkPost(p *post) (err error) { p.Slug = fmt.Sprintf("%v-%02d-%02d-%v", published.Year(), int(published.Month()), published.Day(), randomString(5)) } pathTmplString := defaultIfEmpty( - a.cfg.Blogs[p.Blog].Sections[p.Section].PathTemplate, + a.getBlogFromPost(p).Sections[p.Section].PathTemplate, "{{printf \""+a.getRelativePath(p.Blog, "/%v/%02d/%02d/%v")+"\" .Section .Year .Month .Slug}}", ) pathTmpl, err := template.New("location").Parse(pathTmplString) diff --git a/postsFuncs.go b/postsFuncs.go index 328b4ea..13ec596 100644 --- a/postsFuncs.go +++ b/postsFuncs.go @@ -193,7 +193,7 @@ func (a *goBlog) showFull(p *post) bool { if p.Section == "" { return false } - sec, ok := a.cfg.Blogs[p.Blog].Sections[p.Section] + sec, ok := a.getBlogFromPost(p).Sections[p.Section] return ok && sec != nil && sec.ShowFull } diff --git a/telegram.go b/telegram.go index d4ee510..3f7b434 100644 --- a/telegram.go +++ b/telegram.go @@ -26,7 +26,7 @@ func (tg *configTelegram) enabled() bool { func (a *goBlog) tgPost(silent bool) func(*post) { return func(p *post) { - if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() && p.isPublishedSectionPost() { + if tg := a.getBlogFromPost(p).Telegram; tg.enabled() && p.isPublishedSectionPost() { tgChat := p.firstParameter("telegramchat") tgMsg := p.firstParameter("telegrammsg") if tgChat != "" && tgMsg != "" { @@ -62,7 +62,7 @@ func (a *goBlog) tgPost(silent bool) func(*post) { } func (a *goBlog) tgUpdate(p *post) { - if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() { + if tg := a.getBlogFromPost(p).Telegram; tg.enabled() { tgChat := p.firstParameter("telegramchat") tgMsg := p.firstParameter("telegrammsg") if tgChat == "" || tgMsg == "" { @@ -95,7 +95,7 @@ func (a *goBlog) tgUpdate(p *post) { } func (a *goBlog) tgDelete(p *post) { - if tg := a.cfg.Blogs[p.Blog].Telegram; tg.enabled() { + if tg := a.getBlogFromPost(p).Telegram; tg.enabled() { tgChat := p.firstParameter("telegramchat") tgMsg := p.firstParameter("telegrammsg") if tgChat == "" || tgMsg == "" { diff --git a/tts.go b/tts.go index cd221e7..615a77f 100644 --- a/tts.go +++ b/tts.go @@ -60,7 +60,7 @@ func (a *goBlog) ttsEnabled() bool { func (a *goBlog) createPostTTSAudio(p *post) error { // Get required values - lang := defaultIfEmpty(a.cfg.Blogs[p.Blog].Lang, "en") + lang := defaultIfEmpty(a.getBlogFromPost(p).Lang, "en") // Create TTS text parts parts := []string{} diff --git a/ui.go b/ui.go index d4fc1a9..6da930d 100644 --- a/ui.go +++ b/ui.go @@ -145,7 +145,7 @@ func (a *goBlog) renderBase(hb *htmlbuilder.HtmlBuilder, rd *renderData, title, hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "webmentions")) hb.WriteElementClose("a") } - if a.commentsEnabledForBlog(rd.Blog) { + if rd.Blog.commentsEnabled() { hb.WriteUnescaped(" • ") hb.WriteElementOpen("a", "href", rd.Blog.getRelativePath(commentPath)) hb.WriteEscaped(a.ts.GetTemplateStringVariant(rd.Blog.Lang, "comments")) @@ -382,7 +382,7 @@ func (a *goBlog) renderComment(h *htmlbuilder.HtmlBuilder, rd *renderData) { hb.WriteElementClose("div") } // Interactions - if a.commentsEnabledForBlog(rd.Blog) { + if rd.Blog.commentsEnabled() { a.renderInteractions(hb, rd) } }, @@ -491,7 +491,7 @@ func (a *goBlog) renderBlogStats(hb *htmlbuilder.HtmlBuilder, rd *renderData) { hb.WriteElementClose("script") hb.WriteElementClose("main") // Interactions - if a.commentsEnabledForBlog(rd.Blog) { + if rd.Blog.commentsEnabled() { a.renderInteractions(hb, rd) } }, @@ -649,7 +649,7 @@ func (a *goBlog) renderGeoMap(hb *htmlbuilder.HtmlBuilder, rd *renderData) { hb.WriteElementClose("script") } hb.WriteElementClose("main") - if a.commentsEnabledForBlog(rd.Blog) { + if rd.Blog.commentsEnabled() { a.renderInteractions(hb, rd) } }, @@ -724,7 +724,7 @@ func (a *goBlog) renderBlogroll(hb *htmlbuilder.HtmlBuilder, rd *renderData) { } hb.WriteElementClose("main") // Interactions - if a.commentsEnabledForBlog(rd.Blog) { + if rd.Blog.commentsEnabled() { a.renderInteractions(hb, rd) } }, diff --git a/webmentionVerification.go b/webmentionVerification.go index e92c0d4..e6274c8 100644 --- a/webmentionVerification.go +++ b/webmentionVerification.go @@ -184,7 +184,7 @@ func (a *goBlog) verifyReader(m *mention, body io.Reader) error { return errors.New("target not found in source") } // Fill mention attributes - mf, err := a.parseMicroformatsFromBytes(defaultIfEmpty(m.NewSource, m.Source), mfBuffer.Bytes()) + mf, err := parseMicroformatsFromReader(defaultIfEmpty(m.NewSource, m.Source), mfBuffer) if err != nil { return err }