From 0384d631d2edb8383d0840940be066d96a5badc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sun, 9 Jan 2022 01:20:34 +0100 Subject: #66: Support for specifying custom templates --- internal/feed/template/template.go | 42 ++++++++++++++++++++++++++++++++------ main.go | 22 ++++++++++++++++++++ pkg/config/config.go | 4 ++++ 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 -- cgit v1.2.3