Added a template for creating link posts

This commit is contained in:
Leon Mika 2025-03-11 21:17:59 +11:00
parent 38ebb21a34
commit 836d6a337a
9 changed files with 231 additions and 23 deletions

View file

@ -1,11 +1,16 @@
package posts
import (
"bytes"
"context"
"github.com/PuerkitoBio/goquery"
"github.com/Southclaws/fault"
"html/template"
"lmika.dev/lmika/hugo-cms/models"
"lmika.dev/lmika/hugo-cms/providers/db"
"lmika.dev/lmika/hugo-cms/services/jobs"
"lmika.dev/lmika/hugo-cms/services/sitebuilder"
"resty.dev/v3"
"time"
)
@ -69,6 +74,26 @@ func (s *Service) Create(ctx context.Context, site models.Site, req NewPost) (mo
return post, nil
}
func (s *Service) CreateLinkPost(ctx context.Context, site models.Site, req NewLinkPost) (models.Post, error) {
fl, err := s.fetchLinkedPage(ctx, req)
if err != nil {
return models.Post{}, err
}
var bodyTemplate bytes.Buffer
if err := linkedPostTemplate.Execute(&bodyTemplate, fl); err != nil {
return models.Post{}, err
}
post := models.Post{
SiteID: site.ID,
Title: fl.LinkTitle,
Body: bodyTemplate.String(),
}
return post, nil
}
func (s *Service) Save(ctx context.Context, site models.Site, post *models.Post) error {
post.SiteID = site.ID
@ -88,8 +113,66 @@ func (s *Service) Save(ctx context.Context, site models.Site, post *models.Post)
return s.jobs.Queue(ctx, s.sb.WritePost(site, *post))
}
func (s *Service) fetchLinkedPage(ctx context.Context, req NewLinkPost) (fl fetchedLink, err error) {
client := resty.New()
defer client.Close()
// Fetch the linked site
res, err := client.R().WithContext(ctx).Get(req.LinkURL)
if err != nil {
return fetchedLink{}, err
} else if res.StatusCode() != 200 {
return fetchedLink{}, fault.Newf("page returns non-200 status code %d", res.StatusCode())
}
if len(res.RedirectHistory()) > 0 {
fl.LinkURL = res.RedirectHistory()[len(res.RedirectHistory())-1].URL
} else {
fl.LinkURL = req.LinkURL
}
resDom, err := goquery.NewDocumentFromReader(bytes.NewReader(res.Bytes()))
if err != nil {
return fetchedLink{}, err
}
fl.LinkTitle = resDom.Find("title").Text()
// Fetch the via site
if req.ViaURL != "" {
if res, err := client.R().WithContext(ctx).Get(req.ViaURL); err == nil && res.StatusCode() == 200 {
if len(res.RedirectHistory()) > 0 {
fl.ViaURL = res.RedirectHistory()[len(res.RedirectHistory())-1].URL
} else {
fl.ViaURL = req.LinkURL
}
if viaDom, err := goquery.NewDocumentFromReader(bytes.NewReader(res.Bytes())); err == nil {
fl.ViaTitle = viaDom.Find("title").Text()
}
}
}
return fl, nil
}
type NewPost struct {
Title string `json:"title" form:"title"`
Body string `json:"body" form:"body"`
Params map[string]string `json:"params" form:"params"`
}
type NewLinkPost struct {
LinkURL string `json:"title" form:"link_url"`
ViaURL string `json:"body" form:"via_url"`
}
type fetchedLink struct {
LinkURL string
LinkTitle string
ViaURL string
ViaTitle string
}
var linkedPostTemplate = template.Must(template.New("").Parse(`🔗 [{{.LinkTitle}}]({{.LinkURL}})
{{if .ViaURL}}Via: [{{.ViaTitle}}]({{.ViaURL}}){{end}}`))