summaryrefslogtreecommitdiff
path: root/internal
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/b2/client.go12
-rw-r--r--internal/frontmatter/parser.go1
-rw-r--r--internal/lightgallery/block.go9
-rw-r--r--internal/lightgallery/html_renderer.go3
-rw-r--r--internal/lightgallery/parser.go19
-rw-r--r--internal/templatemanager/templatemanager.go57
6 files changed, 91 insertions, 10 deletions
diff --git a/internal/b2/client.go b/internal/b2/client.go
index f2b6cad..5322b84 100644
--- a/internal/b2/client.go
+++ b/internal/b2/client.go
@@ -33,13 +33,14 @@ func NewB2Client(cfg *config.B2Config) (*B2Client, error) {
type BlogPage struct {
Link string
+ FileName string
Metadata *frontmatter.Metadata
}
-func (c *B2Client) Scan() ([]*BlogPage, error) {
+func (c *B2Client) Scan(prefix string) ([]*BlogPage, error) {
filePaths := []*BlogPage{}
- iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix))
+ iter := c.bucket.List(context.Background(), b2.ListPrefix(c.prefix+prefix))
for iter.Next() {
obj := iter.Object()
@@ -69,10 +70,13 @@ func (c *B2Client) Scan() ([]*BlogPage, error) {
return nil, fmt.Errorf("failed to parse published time metadata field: %w", err)
}
- linkParts := strings.Split(obj.Name(), ".")
+ linkParts := strings.Split(obj.Name(), "/")
+ nameParts := strings.Split(linkParts[len(linkParts)-1], ".")
+ fileName := strings.Join(nameParts[:len(linkParts)-1], ".")
filePaths = append(filePaths, &BlogPage{
- Link: strings.Join(linkParts[:len(linkParts)-1], "."),
+ Link: obj.Name(),
+ FileName: fileName,
Metadata: &frontmatter.Metadata{
Title: attrs.Info["title"],
ShortDescription: attrs.Info["short-description"],
diff --git a/internal/frontmatter/parser.go b/internal/frontmatter/parser.go
index 1a521c0..3c00a7f 100644
--- a/internal/frontmatter/parser.go
+++ b/internal/frontmatter/parser.go
@@ -16,6 +16,7 @@ type Metadata struct {
Thumbnail string `yaml:"thumbnail"`
Tags []string `yaml:"tags"`
Geolocation string `yaml:"geolocation"`
+ Timezone string `yaml:"timezone"`
}
func ParseFrontmatter(content []byte) (metadata *Metadata, markdown []byte, err error) {
diff --git a/internal/lightgallery/block.go b/internal/lightgallery/block.go
index dade2ea..072aa3c 100644
--- a/internal/lightgallery/block.go
+++ b/internal/lightgallery/block.go
@@ -1,11 +1,16 @@
package lightgallery
-import "github.com/yuin/goldmark/ast"
+import (
+ "time"
+
+ "github.com/yuin/goldmark/ast"
+)
// LightGalleryBlock represents a light gallery block in the AST
type LightGalleryBlock struct {
ast.BaseBlock
- Images []LightGalleryImage
+ Images []LightGalleryImage
+ Location *time.Location
}
type LightGalleryImage struct {
diff --git a/internal/lightgallery/html_renderer.go b/internal/lightgallery/html_renderer.go
index e611f0b..77b9785 100644
--- a/internal/lightgallery/html_renderer.go
+++ b/internal/lightgallery/html_renderer.go
@@ -54,6 +54,7 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [
imageNameParts := strings.Split(imageUrlWithoutExt, "-")
dayDate, _ := time.Parse("20060102 150405", imageNameParts[len(imageNameParts)-2]+" "+imageNameParts[len(imageNameParts)-1])
+ dayDate = dayDate.In(gallery.Location)
dynamicElements = append(dynamicElements, fmt.Sprintf(`{
src:
"https://f003.backblazeb2.com/file/sayana-photos/full/%s",
@@ -70,7 +71,7 @@ func (r *LightGalleryHTMLRenderer) renderLightGallery(w util.BufWriter, source [
<p class="grow !text-[1vmax]/[0.9] text-left font-spectral text-main-dark">%s</p>
<p class="!text-[1vmax]/[0.9] text-right font-spectral text-secondary">%s</p>
</div>`+"`"+`
- }`, img.URL, img.URL, img.Caption, imageUrlWithoutExt, imageUrlWithoutExt, img.Caption, dayDate.Format("2006-01-02 15:04:05 -07:00")))
+ }`, img.URL, img.URL, escapeHTML(img.Caption), imageUrlWithoutExt, imageUrlWithoutExt, escapeHTML(img.Caption), dayDate.Format("2006-01-02 15:04:05 -07:00")))
}
w.WriteString(fmt.Sprintf(`
diff --git a/internal/lightgallery/parser.go b/internal/lightgallery/parser.go
index 0ce209c..bd7483a 100644
--- a/internal/lightgallery/parser.go
+++ b/internal/lightgallery/parser.go
@@ -2,7 +2,10 @@ package lightgallery
import (
"bytes"
+ "log/slog"
+ "regexp"
"strings"
+ "time"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
@@ -22,16 +25,26 @@ func (p *LightGalleryParser) Trigger() []byte {
func (p *LightGalleryParser) Open(parent ast.Node, reader text.Reader, pc parser.Context) (ast.Node, parser.State) {
line, _ := reader.PeekLine()
- if !bytes.HasPrefix(line, []byte("{Gallery}")) {
+ if !bytes.HasPrefix(line, []byte("{Gallery")) {
return nil, parser.NoChildren
}
+ r := regexp.MustCompile(`^\{Gallery:([A-Za-z0-9\+\-/]+)\}$`)
+
trimmed := bytes.TrimSpace(line)
- if !bytes.Equal(trimmed, []byte("{Gallery}")) {
+ parts := r.FindSubmatch(trimmed)
+ if len(parts) < 2 {
+ slog.Warn("invalid gallery header format", slog.String("line", string(trimmed)), slog.Int("submatch_count", len(parts)))
+ return nil, parser.NoChildren
+ }
+
+ loc, err := time.LoadLocation(string(parts[1]))
+ if err != nil {
+ slog.Warn("invalid location specified for a gallery", slog.String("error", err.Error()), slog.String("line", string(trimmed)), slog.String("location", string(parts[1])))
return nil, parser.NoChildren
}
- return &LightGalleryBlock{}, parser.NoChildren
+ return &LightGalleryBlock{Location: loc}, parser.NoChildren
}
func (p *LightGalleryParser) Continue(node ast.Node, reader text.Reader, pc parser.Context) parser.State {
diff --git a/internal/templatemanager/templatemanager.go b/internal/templatemanager/templatemanager.go
new file mode 100644
index 0000000..5effcb3
--- /dev/null
+++ b/internal/templatemanager/templatemanager.go
@@ -0,0 +1,57 @@
+package templatemanager
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "path/filepath"
+ "strings"
+)
+
+type TemplateManager struct {
+ templates map[string]templateManagerRender
+}
+
+type templateManagerRender struct {
+ Main string
+ Tmpl *template.Template
+}
+
+type TemplateManagerTemplates struct {
+ Name string
+ Files []string
+}
+
+func NewTemplateManager(templates []TemplateManagerTemplates) (*TemplateManager, error) {
+ templateMap := make(map[string]templateManagerRender)
+
+ for _, tmplStruct := range templates {
+ tmpl := template.New("").Funcs(template.FuncMap{
+ "contains": strings.Contains,
+ })
+ tmpl, err := tmpl.ParseFiles(tmplStruct.Files...)
+ if err != nil {
+ return nil, err
+ }
+ templateMap[tmplStruct.Name] = templateManagerRender{
+ Main: filepath.Base(tmplStruct.Files[0]),
+ Tmpl: tmpl,
+ }
+
+ }
+
+ return &TemplateManager{
+ templates: templateMap,
+ }, nil
+}
+
+func (tm *TemplateManager) Render(name string, data interface{}) ([]byte, error) {
+ tmpl, exists := tm.templates[name]
+ if !exists {
+ return nil, fmt.Errorf("template %s is not found", name)
+ }
+
+ var buf bytes.Buffer
+ err := tmpl.Tmpl.ExecuteTemplate(&buf, tmpl.Main, data)
+ return buf.Bytes(), err
+}