home/internal/page/usecase/page_ucase.go

91 lines
2.1 KiB
Go

package usecase
import (
"context"
"fmt"
"path"
"strings"
"golang.org/x/text/language"
"source.toby3d.me/toby3d/home/internal/domain"
"source.toby3d.me/toby3d/home/internal/page"
"source.toby3d.me/toby3d/home/internal/static"
"source.toby3d.me/toby3d/home/internal/urlutil"
)
type pageUseCase struct {
pages page.Repository
statics static.Repository
}
func NewPageUseCase(pages page.Repository, statics static.Repository) page.UseCase {
return &pageUseCase{
pages: pages,
statics: statics,
}
}
func (ucase *pageUseCase) Do(ctx context.Context, lang language.Tag, p string) (*domain.Page, error) {
ext := path.Ext(p)
if ext == ".html" {
p = p[:len(p)-len(ext)]
}
hasTrailingSlash := p[len(p)-1] == '/'
head, tail := urlutil.ShiftPath(p)
targets := []string{path.Join(head, tail)}
if tail == "/" {
if hasTrailingSlash || ext == "" {
targets = append([]string{path.Join(head, "index")}, targets...)
}
targets = append(targets, head)
}
for i := range targets {
out, err := ucase.pages.Get(ctx, lang, targets[i])
if err != nil {
continue
}
if out.Resources, _, err = ucase.statics.Fetch(ctx, out.File.Dir()+"*"); err != nil {
return out, nil
}
for _, res := range out.Resources.GetType(domain.ResourceTypePage) {
// TODO(toby3d): simplify this, it's awful
resName := path.Base(res.Key())
resExt := path.Ext(resName)
resParts := strings.Split(resName[:len(resName)-len(resExt)], ".")
translationBaseName := strings.Join(resParts[:len(resParts)-1], ".")
if translationBaseName != out.File.TranslationBaseName() {
continue
}
resLang := language.Make(resParts[len(resParts)-1])
if resLang == language.Und {
continue
}
translation, err := ucase.pages.Get(ctx, resLang, targets[i])
if err != nil {
continue
}
out.Translations = append(out.Translations, translation)
}
translations := make([]string, 0)
for i := range out.Translations {
translations = append(translations, out.Translations[i].Language.String())
}
return out, nil
}
return nil, fmt.Errorf("cannot find page on path '%s': %w", p, page.ErrNotExist)
}