weiro/providers/sitereader/provider.go

83 lines
1.4 KiB
Go

package sitereader
import (
"bytes"
"io"
"io/fs"
"gopkg.in/yaml.v3"
"lmika.dev/lmika/weiro/models"
)
type Provider struct {
fs fs.FS
}
func New(fs fs.FS) *Provider {
return &Provider{
fs: fs,
}
}
func (p *Provider) ReadSite() (models.Site, error) {
posts, err := p.ListPosts()
if err != nil {
return models.Site{}, err
}
meta := models.SiteMeta{}
metaBytes, err := fs.ReadFile(p.fs, "site.yaml")
if err != nil {
return models.Site{}, err
}
if err := yaml.Unmarshal(metaBytes, &meta); err != nil {
return models.Site{}, err
}
return models.Site{
Meta: meta,
Posts: posts,
}, nil
}
func (p *Provider) ListPosts() (posts []*models.Post, err error) {
err = fs.WalkDir(p.fs, "posts", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
} else if d.IsDir() {
return nil
}
post, err := p.ReadPost(path)
if err != nil {
return err
}
posts = append(posts, post)
return nil
})
return posts, err
}
func (p *Provider) ReadPost(path string) (*models.Post, error) {
data, err := fs.ReadFile(p.fs, path)
if err != nil {
return nil, err
}
// Split front matter and content
parts := bytes.SplitN(data, []byte("---"), 3)
if len(parts) < 3 {
return nil, io.ErrUnexpectedEOF
}
var meta models.PostMeta
if err := yaml.Unmarshal(parts[1], &meta); err != nil {
return nil, err
}
return &models.Post{
Meta: meta,
Content: string(bytes.TrimPrefix(parts[2], []byte("\n"))),
}, nil
}