Files
schreifuchs.ch/internal/components/page/page.go
T
2026-03-02 22:38:01 +01:00

95 lines
2.0 KiB
Go

package page
import (
"bytes"
"compress/flate"
"context"
"encoding/base64"
"errors"
"fmt"
"log/slog"
"regexp"
"strings"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/translate"
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/filesystem"
"github.com/studio-b12/gowebdav"
)
var titleRGX = regexp.MustCompile(`(?m)^#\s+(.+)$`)
var (
ErrMalFormedInput = errors.New("mal formed input")
ErrNotFound = errors.New("not found")
)
func (s *Service) getPageHeaders(ctx context.Context, uid string) (page PageHeader, err error) {
info, err := s.fs.ReadDir(uid)
if gowebdav.IsErrNotFound(err) { // try private
err = ErrNotFound
}
if err != nil {
return
}
lang := translate.Language(ctx)
var coverImage filesystem.FileInfo
var contentMD filesystem.FileInfo
for _, f := range info {
file, ok := f.(filesystem.FileInfo)
if !ok {
continue
}
if strings.HasPrefix(file.ContentType(), "image/") {
coverImage = file
}
parts := strings.Split(file.Name(), ".")
// fallback content
if contentMD == nil && len(parts) == 2 && parts[1] == "md" {
contentMD = file
}
// language content
if len(parts) == 3 && parts[1] == lang && parts[2] == "md" {
contentMD = file
}
}
slog.Debug("loaded page infos", "cover", coverImage, "content", contentMD)
content, err := s.fs.Read(contentMD.Path())
if err != nil {
return
}
title := titleRGX.FindStringSubmatch(string(content))
if len(title) < 2 {
err = fmt.Errorf("%w: no matches for title", ErrMalFormedInput)
return
}
page.UID = uid
page.Title = title[1]
if coverImage != nil {
page.CoverImageUID, err = images.UIDFromPath(coverImage.Path())
}
return
}
func getImageUID(path string) string {
var b bytes.Buffer
// NewWriter with NoDict (nil) creates a raw DEFLATE compressor
zw, _ := flate.NewWriter(&b, flate.BestCompression)
zw.Write([]byte(path))
zw.Close() // Essential to flush the final bits
return base64.RawURLEncoding.EncodeToString(b.Bytes())
}