hazycora
edd35305e6
All checks were successful
Deploy to VPS / build_site (push) Successful in 5s
this was in the JS version, and forgotten in the port
134 lines
3.2 KiB
Go
134 lines
3.2 KiB
Go
package pagerouter
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.gay/gitgay/pages/cache"
|
|
"git.gay/gitgay/pages/errors"
|
|
"git.gay/gitgay/pages/forgejo"
|
|
"git.gay/gitgay/pages/redirects"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
var (
|
|
commentsRe = regexp.MustCompile(`#.*?$`)
|
|
PAGE_CACHE_TTL = time.Hour * 24
|
|
|
|
pageCache = cache.NewMemCache[*PageRouter]("page", PAGE_CACHE_TTL)
|
|
)
|
|
|
|
func GetPage(info *Target) (pageRouter *PageRouter, err error) {
|
|
pageCacheKey := fmt.Sprintf("%s:%s:%s", info.Repository.Owner, info.Repository.Name, info.SHA)
|
|
pageRouter, err = pageCache.Get(pageCacheKey)
|
|
if err == nil {
|
|
return
|
|
}
|
|
|
|
files, err := forgejo.GetTree(info.Repository.Owner, info.Repository.Name, info.SHA)
|
|
if err != nil {
|
|
err = errors.NewErrorCouldNotGetTree()
|
|
return
|
|
}
|
|
|
|
pageRouter = &PageRouter{
|
|
Info: info,
|
|
Files: files,
|
|
}
|
|
|
|
if domains, ok := files[".domains"]; ok && domains.Type == "blob" {
|
|
var bytes []byte
|
|
bytes, err = domains.Bytes()
|
|
if err != nil {
|
|
return
|
|
}
|
|
pageRouter.Domains = strings.Split(string(commentsRe.ReplaceAll(bytes, []byte(""))), "\n")
|
|
}
|
|
|
|
if settings, ok := files[".pages.json"]; ok && settings.Type == "blob" {
|
|
var bytes []byte
|
|
bytes, err = settings.Bytes()
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = json.Unmarshal(bytes, &pageRouter.Settings)
|
|
if err != nil {
|
|
// Logging this error, but otherwise ignoring it as it's not critical
|
|
log.Err(err).Str("owner", pageRouter.Info.Repository.Owner).Str("repo", pageRouter.Info.Repository.Name).Msg("Could not unmarshal .pages.json")
|
|
} else {
|
|
pageRouter.Settings.BasePath = strings.Trim(path.Clean(pageRouter.Settings.BasePath), "/")
|
|
if pageRouter.Settings.BasePath == "." {
|
|
pageRouter.Settings.BasePath = ""
|
|
}
|
|
if pageRouter.Settings.BasePath != "" && !strings.HasSuffix(pageRouter.Settings.BasePath, "/") {
|
|
pageRouter.Settings.BasePath += "/"
|
|
}
|
|
}
|
|
}
|
|
|
|
if redirectFile, ok := files["_redirects"]; ok && redirectFile.Type == "blob" {
|
|
var bytes []byte
|
|
bytes, err = redirectFile.Bytes()
|
|
if err != nil {
|
|
return
|
|
}
|
|
var engine *redirects.RedirectEngine
|
|
engine, err = redirects.ParseRedirects(string(bytes))
|
|
if err != nil {
|
|
return
|
|
}
|
|
pageRouter.Redirects = engine
|
|
}
|
|
|
|
CleanPathsOfRouter(pageRouter)
|
|
|
|
err = pageCache.Set(pageCacheKey, pageRouter)
|
|
if err != nil {
|
|
log.Err(err).Msg("Could not cache page")
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func tryPaths(pr *PageRouter, paths []string) (file *forgejo.TreeFile, ok bool) {
|
|
for _, path := range paths {
|
|
var found forgejo.TreeFile
|
|
found, ok = pr.Files[path]
|
|
if ok && found.Type == "blob" {
|
|
file = &found
|
|
return
|
|
}
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
func (pr *PageRouter) GetFile(filePath string) (file *forgejo.TreeFile, isIndex bool, err error) {
|
|
if pr.Info.Repository.Private && !pr.Settings.AllowPrivate {
|
|
err = errors.NewErrorNotFound()
|
|
return
|
|
}
|
|
filePath = trimSlashes(filePath)
|
|
var dir string
|
|
if filePath != "" {
|
|
found, ok := tryPaths(pr, []string{filePath, filePath + ".html", filePath + ".htm", filePath + ".md"})
|
|
if ok {
|
|
file = found
|
|
return
|
|
}
|
|
dir = filePath + "/"
|
|
}
|
|
isIndex = true
|
|
index, ok := tryPaths(pr, []string{dir + "index.html", dir + "index.htm", dir + "README.md"})
|
|
if ok {
|
|
file = index
|
|
return
|
|
}
|
|
err = errors.NewErrorNotFound()
|
|
return
|
|
}
|