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" "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 *gowebdav.File var contentMD *gowebdav.File for _, f := range info { file := f.(gowebdav.File) 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] 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()) }