90 lines
1.8 KiB
Go
90 lines
1.8 KiB
Go
package post
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"go.jolheiser.com/blog/markdown"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
func NewBlog(basePath string) (*Blog, error) {
|
|
posts, err := Scan(basePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Blog{
|
|
Path: basePath,
|
|
Posts: posts,
|
|
}, nil
|
|
}
|
|
|
|
func Scan(basePath string) (map[string]*Post, error) {
|
|
posts := make(map[string]*Post)
|
|
ents, err := os.ReadDir(basePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, ent := range ents {
|
|
var apn string
|
|
if ent.IsDir() {
|
|
apn = filepath.Join(basePath, ent.Name(), "index.md")
|
|
if _, err := os.Stat(apn); err != nil {
|
|
log.Error().Err(err).Msgf("could not parse %s", ent.Name())
|
|
continue
|
|
}
|
|
} else {
|
|
if !strings.HasSuffix(ent.Name(), ".md") {
|
|
continue
|
|
}
|
|
apn = filepath.Join(basePath, ent.Name())
|
|
}
|
|
|
|
fi, err := os.Open(apn)
|
|
if err != nil {
|
|
log.Error().Err(err).Msg("could not open file")
|
|
continue
|
|
}
|
|
post := &Post{Path: apn, Slug: strings.TrimSuffix(ent.Name(), ".md")}
|
|
if err := markdown.Meta(fi, &post); err != nil {
|
|
log.Error().Err(err).Msg("could not extract meta")
|
|
continue
|
|
}
|
|
posts[post.Slug] = post
|
|
if err := fi.Close(); err != nil {
|
|
log.Error().Err(err).Msg("could not close file")
|
|
continue
|
|
}
|
|
}
|
|
return posts, nil
|
|
}
|
|
|
|
type Blog struct {
|
|
Path string
|
|
Posts map[string]*Post
|
|
}
|
|
|
|
func (b *Blog) SortedPosts() []*Post {
|
|
posts := make([]*Post, 0, len(b.Posts))
|
|
for _, post := range b.Posts {
|
|
posts = append(posts, post)
|
|
}
|
|
sort.Slice(posts, func(i, j int) bool {
|
|
return posts[i].Date.After(posts[j].Date)
|
|
})
|
|
return posts
|
|
}
|
|
|
|
type Post struct {
|
|
Path string `toml:"-"`
|
|
Slug string `toml:"-"`
|
|
Title string `toml:"title"`
|
|
Author string `toml:"author"`
|
|
Date time.Time `toml:"date"`
|
|
Tags []string `toml:"tags"`
|
|
}
|