aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.eu>2022-01-09 01:20:34 +0100
committerRené 'Necoro' Neumann <necoro@necoro.eu>2022-01-09 13:18:32 +0100
commit0384d631d2edb8383d0840940be066d96a5badc7 (patch)
tree71cac6f7f309794b4a72e88afa1c3aedcc6bd6b2
parent914be83c6066ffb8103707528f8e8279df97bf63 (diff)
downloadfeed2imap-go-0384d631d2edb8383d0840940be066d96a5badc7.tar.gz
feed2imap-go-0384d631d2edb8383d0840940be066d96a5badc7.tar.bz2
feed2imap-go-0384d631d2edb8383d0840940be066d96a5badc7.zip
#66: Support for specifying custom templates
-rw-r--r--internal/feed/template/template.go42
-rw-r--r--main.go22
-rw-r--r--pkg/config/config.go4
3 files changed, 62 insertions, 6 deletions
diff --git a/internal/feed/template/template.go b/internal/feed/template/template.go
index 8b3fb73..d66a8e4 100644
--- a/internal/feed/template/template.go
+++ b/internal/feed/template/template.go
@@ -2,13 +2,20 @@ package template
import (
_ "embed"
+ "errors"
+ "fmt"
html "html/template"
"io"
+ "io/fs"
+ "os"
text "text/template"
+
+ "github.com/Necoro/feed2imap-go/pkg/log"
)
type template interface {
Execute(wr io.Writer, data interface{}) error
+ Name() string
}
type Template struct {
@@ -24,21 +31,44 @@ var defaultHtmlTpl string
var defaultTextTpl string
var Html = Template{
- useHtml: true,
- dflt: defaultHtmlTpl,
+ useHtml: true,
+ dflt: defaultHtmlTpl,
+ template: html.New("Html").Funcs(funcMap),
}
var Text = Template{
- useHtml: false,
- dflt: defaultTextTpl,
+ useHtml: false,
+ dflt: defaultTextTpl,
+ template: text.New("Text").Funcs(funcMap),
}
func (tpl *Template) loadDefault() {
+ if err := tpl.load(tpl.dflt); err != nil {
+ panic(err)
+ }
+}
+
+func (tpl *Template) load(content string) (err error) {
if tpl.useHtml {
- tpl.template = html.Must(html.New("Html").Funcs(funcMap).Parse(tpl.dflt))
+ _, err = tpl.template.(*html.Template).Parse(content)
} else {
- tpl.template = text.Must(text.New("Text").Funcs(funcMap).Parse(tpl.dflt))
+ _, err = tpl.template.(*text.Template).Parse(content)
}
+ return
+}
+
+func (tpl *Template) LoadFile(file string) error {
+ content, err := os.ReadFile(file)
+ if err != nil {
+ if errors.Is(err, fs.ErrNotExist) {
+ log.Errorf("Template file '%s' does not exist, keeping default.", file)
+ return nil
+ } else {
+ return fmt.Errorf("reading template file '%s': %w", file, err)
+ }
+ }
+
+ return tpl.load(string(content))
}
func init() {
diff --git a/main.go b/main.go
index d2d0a3c..e4593be 100644
--- a/main.go
+++ b/main.go
@@ -6,6 +6,7 @@ import (
"os"
"github.com/Necoro/feed2imap-go/internal/feed/cache"
+ "github.com/Necoro/feed2imap-go/internal/feed/template"
"github.com/Necoro/feed2imap-go/internal/imap"
"github.com/Necoro/feed2imap-go/pkg/config"
"github.com/Necoro/feed2imap-go/pkg/log"
@@ -62,6 +63,18 @@ func processFeed(cf cache.CachedFeed, client *imap.Client, dryRun bool) {
cf.Commit()
}
+func loadTemplate(path string, tpl template.Template) error {
+ if path == "" {
+ return nil
+ }
+
+ log.Printf("Loading custom %s template from %s", tpl.Name(), path)
+ if err := tpl.LoadFile(path); err != nil {
+ return fmt.Errorf("loading %s template from %s: %w", tpl.Name(), path, err)
+ }
+ return nil
+}
+
func run() error {
flag.Parse()
if printVersion {
@@ -107,6 +120,15 @@ func run() error {
return nil
}
+ if !buildCache {
+ if err = loadTemplate(cfg.HtmlTemplate, template.Html); err != nil {
+ return err
+ }
+ if err = loadTemplate(cfg.TextTemplate, template.Text); err != nil {
+ return err
+ }
+ }
+
imapErr := make(chan error, 1)
var c *imap.Client
if !dryRun && !buildCache {
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 218ccb3..a580337 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -24,6 +24,8 @@ type GlobalOptions struct {
Parts []string `yaml:"parts"`
MaxFailures int `yaml:"max-failures"`
AutoTarget bool `yaml:"auto-target"`
+ HtmlTemplate string `yaml:"html-template"`
+ TextTemplate string `yaml:"text-template"`
}
var DefaultGlobalOptions = GlobalOptions{
@@ -34,6 +36,8 @@ var DefaultGlobalOptions = GlobalOptions{
Target: Url{},
Parts: []string{"text", "html"},
AutoTarget: true,
+ HtmlTemplate: "",
+ TextTemplate: "",
}
// Options are feed specific