home/internal/page/usecase/page_ucase.go

72 lines
1.6 KiB
Go

package usecase
import (
"context"
"fmt"
"path"
"source.toby3d.me/toby3d/home/internal/domain"
"source.toby3d.me/toby3d/home/internal/page"
"source.toby3d.me/toby3d/home/internal/resource"
"source.toby3d.me/toby3d/home/internal/urlutil"
)
type pageUseCase struct {
pages page.Repository
resources resource.Repository
}
func NewPageUseCase(pages page.Repository, resources resource.Repository) page.UseCase {
return &pageUseCase{
pages: pages,
resources: resources,
}
}
func (ucase *pageUseCase) Do(ctx context.Context, lang domain.Language, 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.resources.Fetch(ctx, out.File.Dir()+"*"); err != nil {
return out, nil
}
for _, res := range out.Resources.GetType(domain.ResourceTypePage) {
if res.File.TranslationBaseName() != out.File.TranslationBaseName() {
continue
}
translation, err := ucase.pages.Get(ctx, res.File.Language, targets[i])
if err != nil {
continue
}
out.Translations = append(out.Translations, translation)
}
return out, nil
}
return nil, fmt.Errorf("cannot find page on path '%s': %w", p, page.ErrNotExist)
}