83 lines
1.4 KiB
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
|
|
}
|