summaryrefslogtreecommitdiff
path: root/internal/router
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'internal/router')
-rw-r--r--internal/router/api-v1-blog-search.go17
-rw-r--r--internal/router/api-v1-general-page-body.go23
-rw-r--r--internal/router/api-v1-general-page-bottom-embeds.go12
-rw-r--r--internal/router/api-v1-general-page-footer.go13
-rw-r--r--internal/router/api-v1-general-page-header.go14
-rw-r--r--internal/router/api-v1-general-page-top-embeds.go13
-rw-r--r--internal/router/api-v1-general-page.go52
-rw-r--r--internal/router/client-cache.go5
-rw-r--r--internal/router/page-cache.go5
9 files changed, 140 insertions, 14 deletions
diff --git a/internal/router/api-v1-blog-search.go b/internal/router/api-v1-blog-search.go
index e22fabe..946b830 100644
--- a/internal/router/api-v1-blog-search.go
+++ b/internal/router/api-v1-blog-search.go
@@ -1,6 +1,7 @@
package router
import (
+ "encoding/json"
"fmt"
"log/slog"
"net/url"
@@ -35,10 +36,18 @@ func Api_V1_BlogSearch(l map[string]*locale.LocaleConfig, langs []string, b2Clie
slog.Warn("unable to parse a client timezone, defaulting to UTC", slog.String("error", err.Error()), slog.String("tz", tz))
}
- pages, err := b2Client.Scan(lang + "/")
- if err != nil {
- c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
- return c.Status(fiber.ErrInternalServerError.Code).SendString(fmt.Sprintf("failed to scan pages for '%s' lang: %v", lang, err))
+ cacheKey := "blog-search." + lang + ".pages-list"
+ var pages []*b2.BlogPage
+ if pagesBytes, ok := PCache.Get(cacheKey); pagesBytes != nil || ok {
+ json.Unmarshal(pagesBytes, &pages)
+ } else {
+ pages, err = b2Client.Scan(lang + "/")
+ if err != nil {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
+ return c.Status(fiber.ErrInternalServerError.Code).SendString(fmt.Sprintf("failed to scan pages for '%s' lang: %v", lang, err))
+ }
+ pagesBytes, _ := json.Marshal(pages)
+ PCache.SetWithTTL(cacheKey, pagesBytes, int64(len(pagesBytes)), 5*time.Minute)
}
encodedQuery := c.Request().URI().QueryString()
diff --git a/internal/router/api-v1-general-page-body.go b/internal/router/api-v1-general-page-body.go
index 4108a4f..f27e0c0 100644
--- a/internal/router/api-v1-general-page-body.go
+++ b/internal/router/api-v1-general-page-body.go
@@ -4,17 +4,22 @@ import (
"fmt"
"html/template"
"log/slog"
+ "math/rand"
"net/url"
"regexp"
"slices"
"strings"
+ "time"
"github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/factgiver"
"github.com/SayaAndy/saya-today-web/locale"
"github.com/gofiber/fiber/v2"
"github.com/yuin/goldmark"
)
+var FactGiver *factgiver.FactGiver
+
func init() {
tm.Add("general-page-body", "views/partials/general-page-body.html")
}
@@ -33,8 +38,15 @@ func Api_V1_GeneralPage_Body(l map[string]*locale.LocaleConfig, langs []string,
}
path := urlStruct.EscapedPath()
+
+ cacheKey := fmt.Sprintf("body.%s", path)
+ if val, ok := PCache.Get(cacheKey); val != nil && ok {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
+ }
+
pathParts := strings.Split(strings.Trim(path, "/"), "/")
- if len(pathParts) < 2 {
+ if len(pathParts) == 0 {
return c.Status(fiber.ErrBadRequest.Code).SendString("'Referer' header is invalid: expect format '/{lang}/...'")
}
@@ -100,6 +112,7 @@ func Api_V1_GeneralPage_Body(l map[string]*locale.LocaleConfig, langs []string,
values["Tags"] = tagsArray
values["QuerySort"] = querySort
values["QueryTags"] = strings.Join(queryTags, ",")
+ values["Title"] = l[lang].BlogSearch.Header
additionalTemplates = append(additionalTemplates, "views/pages/blog-catalogue.html")
} else if len(pathParts) == 3 && pathParts[1] == "blog" {
@@ -125,6 +138,13 @@ func Api_V1_GeneralPage_Body(l map[string]*locale.LocaleConfig, langs []string,
values["ParsedMarkdown"] = template.HTML(parsedMarkdown)
additionalTemplates = append(additionalTemplates, "views/pages/blog-page.html")
+ } else if len(pathParts) == 1 {
+ values["Title"] = l[lang].HomePage.Header
+ values["FilledHeartCount"] = uint(40)
+ values["OutlineHeartCount"] = uint(40)
+ values["GifName"] = fmt.Sprintf("otter-%d.gif", rand.Int()%3+1)
+ values["FunFacts"] = FactGiver.Give(lang)
+ additionalTemplates = append(additionalTemplates, "views/pages/home-page.html")
}
content, err := tm.Render("general-page-body", values, additionalTemplates...)
@@ -133,6 +153,7 @@ func Api_V1_GeneralPage_Body(l map[string]*locale.LocaleConfig, langs []string,
return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div")
}
+ go PCache.SetWithTTL(cacheKey, content, int64(len(content)), 5*time.Minute)
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
return c.Status(fiber.StatusOK).Type("html").Send(content)
}
diff --git a/internal/router/api-v1-general-page-bottom-embeds.go b/internal/router/api-v1-general-page-bottom-embeds.go
index f0957f3..c4d9543 100644
--- a/internal/router/api-v1-general-page-bottom-embeds.go
+++ b/internal/router/api-v1-general-page-bottom-embeds.go
@@ -6,6 +6,7 @@ import (
"net/url"
"slices"
"strings"
+ "time"
"github.com/SayaAndy/saya-today-web/internal/b2"
"github.com/SayaAndy/saya-today-web/locale"
@@ -30,8 +31,14 @@ func Api_V1_GeneralPage_BottomEmbeds(l map[string]*locale.LocaleConfig, langs []
}
path := urlStruct.EscapedPath()
+ cacheKey := fmt.Sprintf("bottom-embeds.%s", path)
+ if val, ok := PCache.Get(cacheKey); val != nil && ok {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
+ }
+
pathParts := strings.Split(strings.Trim(path, "/"), "/")
- if len(pathParts) < 2 {
+ if len(pathParts) == 0 {
return c.Status(fiber.ErrBadRequest.Code).SendString("'Referer' header is invalid: expect format '/{lang}/...'")
}
@@ -51,6 +58,8 @@ func Api_V1_GeneralPage_BottomEmbeds(l map[string]*locale.LocaleConfig, langs []
additionalTemplates = append(additionalTemplates, "views/pages/blog-catalogue.html")
} else if len(pathParts) == 3 && pathParts[1] == "blog" {
additionalTemplates = append(additionalTemplates, "views/pages/blog-page.html")
+ } else if len(pathParts) == 1 {
+ additionalTemplates = append(additionalTemplates, "views/pages/home-page.html")
}
content, err := tm.Render("general-page-bottom-embeds", values, additionalTemplates...)
@@ -59,6 +68,7 @@ func Api_V1_GeneralPage_BottomEmbeds(l map[string]*locale.LocaleConfig, langs []
return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div")
}
+ go PCache.SetWithTTL(cacheKey, content, int64(len(content)), 5*time.Minute)
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
return c.Status(fiber.StatusOK).Type("html").Send(content)
}
diff --git a/internal/router/api-v1-general-page-footer.go b/internal/router/api-v1-general-page-footer.go
index 39b6bea..003f54c 100644
--- a/internal/router/api-v1-general-page-footer.go
+++ b/internal/router/api-v1-general-page-footer.go
@@ -6,6 +6,7 @@ import (
"net/url"
"slices"
"strings"
+ "time"
"github.com/SayaAndy/saya-today-web/locale"
"github.com/gofiber/fiber/v2"
@@ -29,8 +30,15 @@ func Api_V1_GeneralPage_Footer(l map[string]*locale.LocaleConfig, langs []string
}
path := urlStruct.EscapedPath()
+
+ cacheKey := fmt.Sprintf("footer.%s", path)
+ if val, ok := PCache.Get(cacheKey); val != nil && ok {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
+ }
+
pathParts := strings.Split(strings.Trim(path, "/"), "/")
- if len(pathParts) < 2 {
+ if len(pathParts) == 0 {
return c.Status(fiber.ErrBadRequest.Code).SendString("'Referer' header is invalid: expect format '/{lang}/...'")
}
@@ -50,6 +58,8 @@ func Api_V1_GeneralPage_Footer(l map[string]*locale.LocaleConfig, langs []string
additionalTemplates = append(additionalTemplates, "views/pages/blog-catalogue.html")
} else if len(pathParts) == 3 && pathParts[1] == "blog" {
additionalTemplates = append(additionalTemplates, "views/pages/blog-page.html")
+ } else if len(pathParts) == 1 {
+ additionalTemplates = append(additionalTemplates, "views/pages/home-page.html")
}
content, err := tm.Render("general-page-footer", values, additionalTemplates...)
@@ -58,6 +68,7 @@ func Api_V1_GeneralPage_Footer(l map[string]*locale.LocaleConfig, langs []string
return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div")
}
+ go PCache.SetWithTTL(cacheKey, content, int64(len(content)), 5*time.Minute)
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
return c.Status(fiber.StatusOK).Type("html").Send(content)
}
diff --git a/internal/router/api-v1-general-page-header.go b/internal/router/api-v1-general-page-header.go
index 0529ba6..80228f7 100644
--- a/internal/router/api-v1-general-page-header.go
+++ b/internal/router/api-v1-general-page-header.go
@@ -6,6 +6,7 @@ import (
"net/url"
"slices"
"strings"
+ "time"
"github.com/SayaAndy/saya-today-web/internal/b2"
"github.com/SayaAndy/saya-today-web/locale"
@@ -30,8 +31,15 @@ func Api_V1_GeneralPage_Header(l map[string]*locale.LocaleConfig, langs []string
}
path := urlStruct.EscapedPath()
+
+ cacheKey := fmt.Sprintf("header.%s", path)
+ if val, ok := PCache.Get(cacheKey); val != nil && ok {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
+ }
+
pathParts := strings.Split(strings.Trim(path, "/"), "/")
- if len(pathParts) < 2 {
+ if len(pathParts) == 0 {
return c.Status(fiber.ErrBadRequest.Code).SendString("'Referer' header is invalid: expect format '/{lang}/...'")
}
@@ -59,6 +67,9 @@ func Api_V1_GeneralPage_Header(l map[string]*locale.LocaleConfig, langs []string
values["PublishedDate"] = metadata.PublishedTime.Format("2006-01-02 15:04:05 -07:00")
values["ActionDate"] = metadata.ActionDate
additionalTemplates = append(additionalTemplates, "views/pages/blog-page.html")
+ } else if len(pathParts) == 1 {
+ values["Title"] = l[lang].HomePage.Header
+ additionalTemplates = append(additionalTemplates, "views/pages/home-page.html")
}
content, err := tm.Render("general-page-header", values, additionalTemplates...)
@@ -67,6 +78,7 @@ func Api_V1_GeneralPage_Header(l map[string]*locale.LocaleConfig, langs []string
return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div")
}
+ go PCache.SetWithTTL(cacheKey, content, int64(len(content)), 5*time.Minute)
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
return c.Status(fiber.StatusOK).Type("html").Send(content)
}
diff --git a/internal/router/api-v1-general-page-top-embeds.go b/internal/router/api-v1-general-page-top-embeds.go
index 090107b..78021b2 100644
--- a/internal/router/api-v1-general-page-top-embeds.go
+++ b/internal/router/api-v1-general-page-top-embeds.go
@@ -6,6 +6,7 @@ import (
"net/url"
"slices"
"strings"
+ "time"
"github.com/SayaAndy/saya-today-web/locale"
"github.com/gofiber/fiber/v2"
@@ -29,8 +30,15 @@ func Api_V1_GeneralPage_TopEmbeds(l map[string]*locale.LocaleConfig, langs []str
}
path := urlStruct.EscapedPath()
+
+ cacheKey := fmt.Sprintf("top-embeds.%s", path)
+ if val, ok := PCache.Get(cacheKey); val != nil && ok {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
+ }
+
pathParts := strings.Split(strings.Trim(path, "/"), "/")
- if len(pathParts) < 2 {
+ if len(pathParts) == 0 {
return c.Status(fiber.ErrBadRequest.Code).SendString("'Referer' header is invalid: expect format '/{lang}/...'")
}
@@ -50,6 +58,8 @@ func Api_V1_GeneralPage_TopEmbeds(l map[string]*locale.LocaleConfig, langs []str
additionalTemplates = append(additionalTemplates, "views/pages/blog-catalogue.html")
} else if len(pathParts) == 3 && pathParts[1] == "blog" {
additionalTemplates = append(additionalTemplates, "views/pages/blog-page.html")
+ } else if len(pathParts) == 1 {
+ additionalTemplates = append(additionalTemplates, "views/pages/home-page.html")
}
content, err := tm.Render("general-page-top-embeds", values, additionalTemplates...)
@@ -58,6 +68,7 @@ func Api_V1_GeneralPage_TopEmbeds(l map[string]*locale.LocaleConfig, langs []str
return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div")
}
+ go PCache.SetWithTTL(cacheKey, content, int64(len(content)), 5*time.Minute)
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
return c.Status(fiber.StatusOK).Type("html").Send(content)
}
diff --git a/internal/router/api-v1-general-page.go b/internal/router/api-v1-general-page.go
new file mode 100644
index 0000000..d0ea559
--- /dev/null
+++ b/internal/router/api-v1-general-page.go
@@ -0,0 +1,52 @@
+package router
+
+import (
+ "fmt"
+ "log/slog"
+ "slices"
+ "strings"
+
+ "github.com/SayaAndy/saya-today-web/locale"
+ "github.com/gofiber/fiber/v2"
+)
+
+func init() {
+ tm.Add("general-page", "views/layouts/general-page.html")
+}
+
+func Api_V1_GeneralPage(l map[string]*locale.LocaleConfig, langs []string) func(c *fiber.Ctx) error {
+ return func(c *fiber.Ctx) error {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextPlainCharsetUTF8)
+ path := c.Path()
+
+ pathParts := strings.Split(strings.Trim(path, "/"), "/")
+ if len(pathParts) == 0 {
+ return c.Status(fiber.ErrBadRequest.Code).SendString("url path is invalid: expect format '/{lang}/...'")
+ }
+
+ lang := pathParts[0]
+ if !slices.Contains(langs, lang) {
+ return c.Status(fiber.ErrNotFound.Code).SendString(fmt.Sprintf("server does not support '%s' language... yet??", lang))
+ }
+
+ cacheKey := "general-page." + lang
+ if val, ok := PCache.Get(cacheKey); val != nil && ok {
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(val)
+ }
+
+ content, err := tm.Render("general-page", fiber.Map{
+ "L": l[lang],
+ "Lang": lang,
+ "QueryString": string(c.Request().URI().QueryString()),
+ })
+ if err != nil {
+ slog.Warn("failed to generate div", slog.String("path", path), slog.String("error", err.Error()))
+ return c.Status(fiber.ErrInternalServerError.Code).SendString("failed to generate div")
+ }
+
+ go PCache.Set(cacheKey, content, int64(len(content)))
+ c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
+ return c.Status(fiber.StatusOK).Type("html").Send(content)
+ }
+}
diff --git a/internal/router/client-cache.go b/internal/router/client-cache.go
index 81d7641..e448fb3 100644
--- a/internal/router/client-cache.go
+++ b/internal/router/client-cache.go
@@ -11,11 +11,6 @@ import (
"golang.org/x/crypto/argon2"
)
-type PageLike struct {
- PageRef string
- UserId string
-}
-
type ClientCache struct {
hashMap map[string]string
hashMapMutex sync.RWMutex
diff --git a/internal/router/page-cache.go b/internal/router/page-cache.go
new file mode 100644
index 0000000..01e4792
--- /dev/null
+++ b/internal/router/page-cache.go
@@ -0,0 +1,5 @@
+package router
+
+import "github.com/dgraph-io/ristretto/v2"
+
+var PCache *ristretto.Cache[string, []byte]