summaryrefslogtreecommitdiffci
path: root/internal
diff options
from:
to:
context:
space:
mode:
authorGravatar SayaAndy <saya.andy@posteo.com> 2026-04-15 16:11:51 +0700
committerGravatar SayaAndy <saya.andy@posteo.com> 2026-04-15 16:11:51 +0700
commit66b2a96fcca113105043be3cb9c49f8ee7fe240c (patch)
tree04a9d8b816f6507076bf778769f7990bf153fce4 /internal
parenta3aa1dd07abfbbb27a7dfeeb536a6fcc51709256 (diff)
downloadweb-66b2a96fcca113105043be3cb9c49f8ee7fe240c.tar.gz
web-66b2a96fcca113105043be3cb9c49f8ee7fe240c.zip
feat: support s3 for blog pages
refactor: make blog client an interface feat: claude.md
Diffstat (limited to 'internal')
-rw-r--r--internal/blog/b2.go (renamed from internal/b2/client.go)29
-rw-r--r--internal/blog/client.go27
-rw-r--r--internal/blog/s3.go140
-rw-r--r--internal/blogtrigger/blogtrigger.go22
-rw-r--r--internal/factgiver/factgiver.go10
-rw-r--r--internal/mailer/mailer.go4
-rw-r--r--internal/router/handlers/api-v1-blog-search.go6
-rw-r--r--internal/router/handlers/api-v1-like-get.go2
-rw-r--r--internal/router/handlers/api-v1-like-put.go2
-rw-r--r--internal/router/handlers/lang-blog-title.go16
-rw-r--r--internal/router/handlers/lang-blog.go8
-rw-r--r--internal/router/handlers/lang-map.go8
-rw-r--r--internal/router/handlers/lang-user.go2
-rw-r--r--internal/router/router.go10
14 files changed, 225 insertions, 61 deletions
diff --git a/internal/b2/client.go b/internal/blog/b2.go
index fda79e0..0caa0ba 100644
--- a/internal/b2/client.go
+++ b/internal/blog/b2.go
@@ -1,4 +1,4 @@
-package b2
+package blog
import (
"context"
@@ -18,30 +18,27 @@ type B2Client struct {
b2cl *b2.Client
}
-func NewB2Client(cfg *config.B2Config) (*B2Client, error) {
- b2cl, err := b2.NewClient(context.Background(), cfg.KeyID, cfg.ApplicationKey)
+func NewB2Client(cfg *config.StorageConfig) (Client, error) {
+ if cfg.Type != "b2" {
+ return nil, fmt.Errorf("invalid storage type for B2InputClient")
+ }
+ b2cfg := cfg.Config.(*config.B2Config)
+
+ b2cl, err := b2.NewClient(context.Background(), b2cfg.KeyID, b2cfg.ApplicationKey)
if err != nil {
return nil, err
}
- bucket, err := b2cl.Bucket(context.Background(), cfg.BucketName)
+ bucket, err := b2cl.Bucket(context.Background(), b2cfg.BucketName)
if err != nil {
return nil, err
}
- return &B2Client{b2cl: b2cl, bucket: bucket, prefix: cfg.Prefix}, nil
-}
-
-type BlogPage struct {
- Link string
- FileName string
- Lang string
- ModifiedTime time.Time
- Metadata *frontmatter.Metadata
+ return &B2Client{b2cl: b2cl, bucket: bucket, prefix: b2cfg.Prefix}, nil
}
-func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) {
- filePaths := []*BlogPage{}
+func (c *B2Client) Scan(prefix string) ([]*Page, error) {
+ filePaths := []*Page{}
iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix+prefix))
@@ -82,7 +79,7 @@ func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) {
lang, _ := strings.CutPrefix(linkParts[0], c.prefix)
- filePaths = append(filePaths, &BlogPage{
+ filePaths = append(filePaths, &Page{
Link: obj.Name(),
FileName: fileName,
Lang: lang,
diff --git a/internal/blog/client.go b/internal/blog/client.go
new file mode 100644
index 0000000..56bbee4
--- /dev/null
+++ b/internal/blog/client.go
@@ -0,0 +1,27 @@
+package blog
+
+import (
+ "time"
+
+ "github.com/SayaAndy/saya-today-web/config"
+ "github.com/SayaAndy/saya-today-web/internal/frontmatter"
+)
+
+type Page struct {
+ Link string
+ FileName string
+ Lang string
+ ModifiedTime time.Time
+ Metadata *frontmatter.Metadata
+}
+
+type Client interface {
+ Scan(prefix string) ([]*Page, error)
+ ReadAll(path string) ([]byte, error)
+ ReadFrontmatter(path string) (metadata *frontmatter.Metadata, markdown []byte, err error)
+}
+
+var NewClientMap = map[string]func(*config.StorageConfig) (Client, error){
+ "b2": NewB2Client,
+ "s3": NewS3Client,
+}
diff --git a/internal/blog/s3.go b/internal/blog/s3.go
new file mode 100644
index 0000000..de4eb3a
--- /dev/null
+++ b/internal/blog/s3.go
@@ -0,0 +1,140 @@
+package blog
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "slices"
+ "strings"
+ "time"
+
+ "github.com/SayaAndy/saya-today-web/config"
+ "github.com/SayaAndy/saya-today-web/internal/frontmatter"
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/credentials"
+ "github.com/aws/aws-sdk-go-v2/service/s3"
+)
+
+type S3Client struct {
+ prefix string
+ bucketName string
+ s3cl *s3.Client
+}
+
+func NewS3Client(cfg *config.StorageConfig) (Client, error) {
+ if cfg.Type != "s3" {
+ return nil, fmt.Errorf("invalid storage type for S3Client")
+ }
+ s3cfg := cfg.Config.(*config.S3Config)
+
+ s3cl := s3.New(s3.Options{
+ Region: s3cfg.Region,
+ BaseEndpoint: aws.String(s3cfg.Endpoint),
+ Credentials: credentials.NewStaticCredentialsProvider(s3cfg.AccessKeyID, s3cfg.SecretAccessKey, ""),
+ })
+
+ return &S3Client{s3cfg.Prefix, s3cfg.BucketName, s3cl}, nil
+}
+
+func (c *S3Client) Scan(prefix string) ([]*Page, error) {
+ pages := []*Page{}
+
+ fullPrefix := c.prefix + prefix
+ input := &s3.ListObjectsV2Input{
+ Bucket: aws.String(c.bucketName),
+ Prefix: aws.String(fullPrefix),
+ }
+
+ paginator := s3.NewListObjectsV2Paginator(c.s3cl, input)
+
+ for paginator.HasMorePages() {
+ output, err := paginator.NextPage(context.Background())
+ if err != nil {
+ return nil, fmt.Errorf("list S3 objects: %w", err)
+ }
+
+ for _, obj := range output.Contents {
+ key := aws.ToString(obj.Key)
+
+ if !strings.HasSuffix(key, ".md") {
+ continue
+ }
+
+ head, err := c.s3cl.HeadObject(context.Background(), &s3.HeadObjectInput{
+ Bucket: aws.String(c.bucketName),
+ Key: aws.String(key),
+ })
+ if err != nil {
+ return nil, fmt.Errorf("head S3 object %s: %w", key, err)
+ }
+
+ if head.ContentType == nil || !strings.Contains(*head.ContentType, "text/markdown") {
+ continue
+ }
+
+ meta := head.Metadata
+ if meta["title"] == "" {
+ continue
+ }
+
+ publishedTime, err := time.Parse(time.RFC3339, meta["published-time"])
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse published time metadata field: %w", err)
+ }
+
+ linkParts := strings.Split(key, "/")
+ nameParts := strings.Split(linkParts[len(linkParts)-1], ".")
+ fileName := strings.Join(nameParts[:len(nameParts)-1], ".")
+
+ tags := strings.Split(meta["tags"], ",")
+ slices.Sort(tags)
+
+ lang, _ := strings.CutPrefix(linkParts[0], c.prefix)
+
+ pages = append(pages, &Page{
+ Link: key,
+ FileName: fileName,
+ Lang: lang,
+ ModifiedTime: aws.ToTime(obj.LastModified),
+ Metadata: &frontmatter.Metadata{
+ Title: meta["title"],
+ ShortDescription: meta["short-description"],
+ ActionDate: meta["action-date"],
+ PublishedTime: publishedTime,
+ Thumbnail: meta["thumbnail"],
+ Tags: tags,
+ Geolocation: meta["geolocation"],
+ },
+ })
+ }
+ }
+
+ return pages, nil
+}
+
+func (c *S3Client) ReadAll(path string) ([]byte, error) {
+ output, err := c.s3cl.GetObject(context.Background(), &s3.GetObjectInput{
+ Bucket: aws.String(c.bucketName),
+ Key: aws.String(c.prefix + path),
+ })
+ if err != nil {
+ return nil, fmt.Errorf("get S3 object: %w", err)
+ }
+ defer output.Body.Close()
+
+ content, err := io.ReadAll(output.Body)
+ if err != nil {
+ return nil, fmt.Errorf("read S3 object body: %w", err)
+ }
+
+ return content, nil
+}
+
+func (c *S3Client) ReadFrontmatter(path string) (metadata *frontmatter.Metadata, markdown []byte, err error) {
+ contentBytes, err := c.ReadAll(path)
+ if err != nil {
+ return nil, nil, fmt.Errorf("failed to read file for frontmatter parsing: %w", err)
+ }
+
+ return frontmatter.ParseFrontmatter(contentBytes)
+}
diff --git a/internal/blogtrigger/blogtrigger.go b/internal/blogtrigger/blogtrigger.go
index c5b3097..81efafe 100644
--- a/internal/blogtrigger/blogtrigger.go
+++ b/internal/blogtrigger/blogtrigger.go
@@ -5,29 +5,29 @@ import (
"log/slog"
"github.com/SayaAndy/saya-today-web/config"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/go-co-op/gocron/v2"
)
type BlogTriggerScheduler struct {
s gocron.Scheduler
- knownBlogPages map[string]map[string]*b2.BlogPage
- b2Client *b2.B2Client
- onTrigger func([]*b2.BlogPage) error
+ knownBlogPages map[string]map[string]*blog.Page
+ blogClient blog.Client
+ onTrigger func([]*blog.Page) error
}
-func NewBlogTriggerScheduler(b2Client *b2.B2Client, availableLanguages []config.AvailableLanguageConfig, cron string, onTrigger func([]*b2.BlogPage) error) (*BlogTriggerScheduler, error) {
+func NewBlogTriggerScheduler(blogClient blog.Client, availableLanguages []config.AvailableLanguageConfig, cron string, onTrigger func([]*blog.Page) error) (*BlogTriggerScheduler, error) {
s, err := gocron.NewScheduler()
if err != nil {
return nil, fmt.Errorf("failed to create new scheduler: %w", err)
}
- knownBlogPages := make(map[string]map[string]*b2.BlogPage, len(availableLanguages))
+ knownBlogPages := make(map[string]map[string]*blog.Page, len(availableLanguages))
for _, lang := range availableLanguages {
- knownBlogPages[lang.Name] = make(map[string]*b2.BlogPage)
+ knownBlogPages[lang.Name] = make(map[string]*blog.Page)
}
- bts := &BlogTriggerScheduler{s, knownBlogPages, b2Client, onTrigger}
+ bts := &BlogTriggerScheduler{s, knownBlogPages, blogClient, onTrigger}
defer bts.s.Start()
bts.s.NewJob(gocron.CronJob(cron, false), gocron.NewTask(func(bts *BlogTriggerScheduler) {
@@ -53,10 +53,10 @@ func (bts *BlogTriggerScheduler) Close() error {
return bts.s.Shutdown()
}
-func (bts *BlogTriggerScheduler) scan() (newPages []*b2.BlogPage, err error) {
- newPages = make([]*b2.BlogPage, 0)
+func (bts *BlogTriggerScheduler) scan() (newPages []*blog.Page, err error) {
+ newPages = make([]*blog.Page, 0)
for lang := range bts.knownBlogPages {
- posts, err := bts.b2Client.Scan(lang + "/")
+ posts, err := bts.blogClient.Scan(lang + "/")
if err != nil {
return nil, fmt.Errorf("failed to scan blog pages in b2 on '%s': %w", lang, err)
}
diff --git a/internal/factgiver/factgiver.go b/internal/factgiver/factgiver.go
index 5b418ee..c5b8bc4 100644
--- a/internal/factgiver/factgiver.go
+++ b/internal/factgiver/factgiver.go
@@ -8,11 +8,11 @@ import (
"time"
"github.com/SayaAndy/saya-today-web/config"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
)
type FactGiver struct {
- b2Client *b2.B2Client
+ blogClient blog.Client
cache map[string][]string
langs []config.AvailableLanguageConfig
factsFileName string
@@ -21,13 +21,13 @@ type FactGiver struct {
}
func NewFactGiver(cfg *config.FactGiverConfig, langs []config.AvailableLanguageConfig) (*FactGiver, error) {
- b2Client, err := b2.NewB2Client(&cfg.Storage.Config)
+ blogClient, err := blog.NewClientMap[cfg.Storage.Type](&cfg.Storage)
if err != nil {
return nil, fmt.Errorf("fail to init b2 client for a new fact giver: %s", err.Error())
}
factGiver := &FactGiver{
- b2Client: b2Client,
+ blogClient: blogClient,
cache: make(map[string][]string, len(langs)),
langs: langs,
factsFileName: cfg.FactsFileName,
@@ -53,7 +53,7 @@ func (g *FactGiver) Give(lang string) [3]string {
func (g *FactGiver) initCache() error {
for _, lang := range g.langs {
localFacts := strings.Replace(g.factsFileName, "*", lang.Name, 1)
- factsContentBytes, err := g.b2Client.ReadAll(localFacts)
+ factsContentBytes, err := g.blogClient.ReadAll(localFacts)
if err != nil {
return fmt.Errorf("fail to read '%s' facts file: %s", lang.Name, err.Error())
}
diff --git a/internal/mailer/mailer.go b/internal/mailer/mailer.go
index d6dbd17..ffa7b30 100644
--- a/internal/mailer/mailer.go
+++ b/internal/mailer/mailer.go
@@ -14,7 +14,7 @@ import (
"sync"
"time"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/templatemanager"
"github.com/SayaAndy/saya-today-web/locale"
"github.com/dgraph-io/ristretto/v2"
@@ -418,7 +418,7 @@ func (m *Mailer) Subscribe(userIdHash []byte, subscriptionType SubscriptionType,
return nil
}
-func (m *Mailer) NewPost(post *b2.BlogPage) error {
+func (m *Mailer) NewPost(post *blog.Page) error {
tx, err := m.db.Begin()
if err != nil {
return fmt.Errorf("failed to initialize transaction with db: %s", err)
diff --git a/internal/router/handlers/api-v1-blog-search.go b/internal/router/handlers/api-v1-blog-search.go
index 1e8a480..c9a91ad 100644
--- a/internal/router/handlers/api-v1-blog-search.go
+++ b/internal/router/handlers/api-v1-blog-search.go
@@ -10,7 +10,7 @@ import (
"strings"
"time"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/router"
"github.com/gofiber/fiber/v2"
)
@@ -56,11 +56,11 @@ func (r *BlogSearchHandler) Render(c *fiber.Ctx, supplements *router.Supplements
cacheKey := "blog-search." + lang + ".pages-list"
- var pages []*b2.BlogPage
+ var pages []*blog.Page
if pagesBytes, ok := supplements.PageCache.Get(cacheKey); pagesBytes != nil || ok {
json.Unmarshal(pagesBytes, &pages)
} else {
- pages, err = supplements.B2Client.Scan(lang + "/")
+ pages, err = supplements.BlogClient.Scan(lang + "/")
if err != nil {
return fiber.StatusInternalServerError, fmt.Errorf("failed to scan pages for '%s' lang: %w", lang, err)
}
diff --git a/internal/router/handlers/api-v1-like-get.go b/internal/router/handlers/api-v1-like-get.go
index e9c176e..0eaf5f6 100644
--- a/internal/router/handlers/api-v1-like-get.go
+++ b/internal/router/handlers/api-v1-like-get.go
@@ -48,7 +48,7 @@ func (r *GetLikeHandler) Render(c *fiber.Ctx, supplements *router.Supplements, l
page := pathParts[2]
pageLink := lang + "/" + page + ".md"
- if pages, _ := supplements.B2Client.Scan(pageLink); len(pages) == 0 {
+ if pages, _ := supplements.BlogClient.Scan(pageLink); len(pages) == 0 {
return fiber.StatusNotFound, fmt.Errorf("server did not find '%s' article", pageLink)
}
diff --git a/internal/router/handlers/api-v1-like-put.go b/internal/router/handlers/api-v1-like-put.go
index ea4ef4b..434f15a 100644
--- a/internal/router/handlers/api-v1-like-put.go
+++ b/internal/router/handlers/api-v1-like-put.go
@@ -49,7 +49,7 @@ func (r *PutLikeHandler) Render(c *fiber.Ctx, supplements *router.Supplements, l
page := pathParts[2]
pageLink := lang + "/" + page + ".md"
- if pages, _ := supplements.B2Client.Scan(pageLink); len(pages) == 0 {
+ if pages, _ := supplements.BlogClient.Scan(pageLink); len(pages) == 0 {
return fiber.StatusNotFound, fmt.Errorf("server did not find '%s' article", pageLink)
}
diff --git a/internal/router/handlers/lang-blog-title.go b/internal/router/handlers/lang-blog-title.go
index 5bfc6e7..f1be0a5 100644
--- a/internal/router/handlers/lang-blog-title.go
+++ b/internal/router/handlers/lang-blog-title.go
@@ -7,7 +7,7 @@ import (
"strings"
"time"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/frontmatter"
"github.com/SayaAndy/saya-today-web/internal/router"
"github.com/gofiber/fiber/v2"
@@ -49,7 +49,7 @@ func (r *BlogPageHandler) ToValidateLang() router.LangSetting {
func (r *BlogPageHandler) SitemapInfo(supplements *router.Supplements) []router.SitemapInfo {
sitemapInfo := []router.SitemapInfo{}
- pages, err := supplements.B2Client.Scan("")
+ pages, err := supplements.BlogClient.Scan("")
if err != nil {
return sitemapInfo
}
@@ -66,7 +66,7 @@ func (r *BlogPageHandler) SitemapInfo(supplements *router.Supplements) []router.
}
func (r *BlogPageHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (meta []router.MetaField, err error) {
- metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + c.Params("title") + ".md")
+ metadata, _, err := supplements.BlogClient.ReadFrontmatter(lang + "/" + c.Params("title") + ".md")
if err != nil {
return nil, fmt.Errorf("failed to read frontmatter of the desired blog post: %w", err)
}
@@ -82,7 +82,7 @@ func (r *BlogPageHandler) AddMeta(c *fiber.Ctx, supplements *router.Supplements,
}
func (r *BlogPageHandler) AddLinkedData(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (ld map[string]any, err error) {
- metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + c.Params("title") + ".md")
+ metadata, _, err := supplements.BlogClient.ReadFrontmatter(lang + "/" + c.Params("title") + ".md")
if err != nil {
return nil, fmt.Errorf("failed to read frontmatter of the desired blog post: %w", err)
}
@@ -103,7 +103,7 @@ func (r *BlogPageHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplemen
return fiber.StatusBadRequest, fmt.Errorf("failed to get path from referer: %w", err)
}
- metadata, parsedMarkdown, err := readBlogPost(supplements.MarkdownRenderer, supplements.B2Client, lang+"/"+pathParts[2])
+ metadata, parsedMarkdown, err := readBlogPost(supplements.MarkdownRenderer, supplements.BlogClient, lang+"/"+pathParts[2])
if err != nil {
return fiber.StatusNotFound, fmt.Errorf("failed to find '%s' post: %w", pathParts[2], err)
}
@@ -138,7 +138,7 @@ func (r *BlogPageHandler) RenderHeader(c *fiber.Ctx, supplements *router.Supplem
return fiber.StatusBadRequest, fmt.Errorf("failed to get path from referer: %w", err)
}
- metadata, _, err := supplements.B2Client.ReadFrontmatter(lang + "/" + pathParts[2] + ".md")
+ metadata, _, err := supplements.BlogClient.ReadFrontmatter(lang + "/" + pathParts[2] + ".md")
if err != nil {
return fiber.StatusNotFound, fmt.Errorf("could not read '%s' for metadata: %w", path, err)
}
@@ -148,8 +148,8 @@ func (r *BlogPageHandler) RenderHeader(c *fiber.Ctx, supplements *router.Supplem
return fiber.StatusOK, nil
}
-func readBlogPost(md goldmark.Markdown, b2Client *b2.B2Client, sourceName string) (metadata *frontmatter.Metadata, html string, err error) {
- metadata, markdown, err := b2Client.ReadFrontmatter(sourceName + ".md")
+func readBlogPost(md goldmark.Markdown, blogClient blog.Client, sourceName string) (metadata *frontmatter.Metadata, html string, err error) {
+ metadata, markdown, err := blogClient.ReadFrontmatter(sourceName + ".md")
if err != nil {
return nil, "", fmt.Errorf("failed to read a frontmatter file: %w", err)
}
diff --git a/internal/router/handlers/lang-blog.go b/internal/router/handlers/lang-blog.go
index 709d3dc..79ec9f3 100644
--- a/internal/router/handlers/lang-blog.go
+++ b/internal/router/handlers/lang-blog.go
@@ -9,7 +9,7 @@ import (
"strings"
"time"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/router"
"github.com/gofiber/fiber/v2"
)
@@ -79,7 +79,7 @@ func (r *CatalogueHandler) RenderBody(c *fiber.Ctx, supplements *router.Suppleme
queryTags = append(queryTags, string(match[1]))
}
- tagsArray, err := getTags(supplements.B2Client, lang)
+ tagsArray, err := getTags(supplements.BlogClient, lang)
if err != nil {
return fiber.StatusInternalServerError, fmt.Errorf("failed to get the available tags")
}
@@ -102,8 +102,8 @@ type Tag struct {
Count int `json:"Count" yaml:"count"`
}
-func getTags(b2Client *b2.B2Client, lang string) (tags []Tag, err error) {
- pages, err := b2Client.Scan(lang + "/")
+func getTags(blogClient blog.Client, lang string) (tags []Tag, err error) {
+ pages, err := blogClient.Scan(lang + "/")
if err != nil {
slog.Warn("failed to scan pages via b2", slog.String("error", err.Error()))
return nil, fmt.Errorf("failed to scan pages via b2: %w", err)
diff --git a/internal/router/handlers/lang-map.go b/internal/router/handlers/lang-map.go
index 551b485..d452bc7 100644
--- a/internal/router/handlers/lang-map.go
+++ b/internal/router/handlers/lang-map.go
@@ -7,7 +7,7 @@ import (
"strconv"
"strings"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/router"
"github.com/gofiber/fiber/v2"
)
@@ -49,8 +49,8 @@ func (r *MapHandler) SitemapInfo(supplements *router.Supplements) []router.Sitem
}
func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang string, templateMap fiber.Map) (statusCode int, err error) {
- pages, err := supplements.B2Client.Scan(lang + "/")
- slices.SortFunc(pages, func(a *b2.BlogPage, b *b2.BlogPage) int {
+ pages, err := supplements.BlogClient.Scan(lang + "/")
+ slices.SortFunc(pages, func(a *blog.Page, b *blog.Page) int {
return a.Metadata.PublishedTime.Compare(b.Metadata.PublishedTime)
})
status := fiber.StatusOK
@@ -60,7 +60,7 @@ func (r *MapHandler) Render(c *fiber.Ctx, supplements *router.Supplements, lang
slog.String("lang", lang),
)
status = fiber.StatusPartialContent
- pages = []*b2.BlogPage{}
+ pages = []*blog.Page{}
}
type MapMarker struct {
diff --git a/internal/router/handlers/lang-user.go b/internal/router/handlers/lang-user.go
index eae1685..0dda529 100644
--- a/internal/router/handlers/lang-user.go
+++ b/internal/router/handlers/lang-user.go
@@ -55,7 +55,7 @@ func (r *UserHandler) RenderBody(c *fiber.Ctx, supplements *router.Supplements,
slog.Error("get info from mailer about a client", slog.String("error", err.Error()))
}
- tagsArray, err := getTags(supplements.B2Client, lang)
+ tagsArray, err := getTags(supplements.BlogClient, lang)
if err != nil {
return fiber.ErrInternalServerError.Code, fmt.Errorf("failed to get the available tags")
}
diff --git a/internal/router/router.go b/internal/router/router.go
index 3242759..e8fb47a 100644
--- a/internal/router/router.go
+++ b/internal/router/router.go
@@ -13,7 +13,7 @@ import (
"time"
"github.com/SayaAndy/saya-today-web/config"
- "github.com/SayaAndy/saya-today-web/internal/b2"
+ "github.com/SayaAndy/saya-today-web/internal/blog"
"github.com/SayaAndy/saya-today-web/internal/blogtrigger"
"github.com/SayaAndy/saya-today-web/internal/factgiver"
"github.com/SayaAndy/saya-today-web/internal/glightbox"
@@ -90,7 +90,7 @@ type Route interface {
type Supplements struct {
DB *sql.DB
- B2Client *b2.B2Client
+ BlogClient blog.Client
Localization map[string]*locale.LocaleConfig
AvailableLanguages []config.AvailableLanguageConfig
ClientCache *ClientCache
@@ -140,7 +140,7 @@ func NewRouter(cfg *config.Config) (*Router, error) {
}
slog.Debug("successfully applied migrations")
- supplements.B2Client, err = b2.NewB2Client(&cfg.BlogPages.Storage.Config)
+ supplements.BlogClient, err = blog.NewClientMap[cfg.BlogPages.Storage.Type](&cfg.BlogPages.Storage)
if err != nil {
return nil, fmt.Errorf("fail to initialize b2 client: %w", err)
}
@@ -198,8 +198,8 @@ func NewRouter(cfg *config.Config) (*Router, error) {
return nil, fmt.Errorf("fail to initialize mailer: %w", err)
}
- supplements.BlogTrigger, err = blogtrigger.NewBlogTriggerScheduler(supplements.B2Client, cfg.AvailableLanguages, cfg.Mail.Trigger.OnNewPost,
- func(bp []*b2.BlogPage) error {
+ supplements.BlogTrigger, err = blogtrigger.NewBlogTriggerScheduler(supplements.BlogClient, cfg.AvailableLanguages, cfg.Mail.Trigger.OnNewPost,
+ func(bp []*blog.Page) error {
for _, post := range bp {
if err := supplements.Mailer.NewPost(post); err != nil {
return err