summaryrefslogtreecommitdiff
path: root/pkg/config/config.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pkg/config/config.go137
1 files changed, 137 insertions, 0 deletions
diff --git a/pkg/config/config.go b/pkg/config/config.go
new file mode 100644
index 0000000..83c952f
--- /dev/null
+++ b/pkg/config/config.go
@@ -0,0 +1,137 @@
+package config
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/user"
+ "runtime"
+ "runtime/debug"
+ "strings"
+
+ "github.com/Necoro/feed2imap-go/pkg/log"
+ "github.com/Necoro/feed2imap-go/pkg/util"
+)
+
+// Convenience type for the non-mapped configuration options
+// Mostly used for legacy options
+type Map map[string]interface{}
+
+// Global options, not feed specific
+type GlobalOptions struct {
+ Timeout int `yaml:"timeout"`
+ DefaultEmail string `yaml:"default-email"`
+ Target string `yaml:"target"`
+ Parts []string `yaml:"parts"`
+}
+
+// Default global options
+var DefaultGlobalOptions = GlobalOptions{
+ Timeout: 30,
+ DefaultEmail: username() + "@" + hostname(),
+ Target: "",
+ Parts: []string{"text", "html"},
+}
+
+// Per feed options
+type Options struct {
+ MinFreq *int `yaml:"min-frequency"`
+ InclImages *bool `yaml:"include-images"`
+}
+
+// Default feed options
+var DefaultFeedOptions Options
+
+func init() {
+ one := 1
+ fal := false
+ DefaultFeedOptions = Options{
+ MinFreq: &one,
+ InclImages: &fal,
+ }
+}
+
+// Config holds the global configuration options and the configured feeds
+type Config struct {
+ GlobalOptions `yaml:",inline"`
+ GlobalConfig Map `yaml:",inline"`
+ FeedOptions Options `yaml:"options"`
+ Feeds Feeds `yaml:"-"`
+}
+
+// WithDefault returns a configuration initialized with default values.
+func WithDefault() *Config {
+ return &Config{
+ GlobalOptions: DefaultGlobalOptions,
+ FeedOptions: DefaultFeedOptions,
+ GlobalConfig: Map{},
+ Feeds: Feeds{},
+ }
+}
+
+// Validates the configuration against common mistakes
+func (cfg *Config) Validate() error {
+ if cfg.Target == "" {
+ return fmt.Errorf("No target set!")
+ }
+
+ return nil
+}
+
+// Marks whether 'text' part should be included in mails
+func (cfg *Config) WithPartText() bool {
+ return util.StrContains(cfg.Parts, "text")
+}
+
+// Marks whether 'html' part should be included in mails
+func (cfg *Config) WithPartHtml() bool {
+ return util.StrContains(cfg.Parts, "html")
+}
+
+// Current feed2imap version
+func Version() string {
+ bi, ok := debug.ReadBuildInfo()
+ if !ok {
+ return "(unknown)"
+ }
+ return bi.Main.Version
+}
+
+// Load configuration from file
+func Load(path string) (*Config, error) {
+ log.Printf("Reading configuration file '%s'", path)
+
+ buf, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, fmt.Errorf("while reading '%s': %w", path, err)
+ }
+
+ cfg := WithDefault()
+ if err = cfg.parse(buf); err != nil {
+ return nil, fmt.Errorf("while parsing: %w", err)
+ }
+
+ return cfg, nil
+}
+
+func hostname() (hostname string) {
+ hostname, err := os.Hostname()
+ if err != nil {
+ hostname = "localhost"
+ }
+ return
+}
+
+func username() string {
+ u, err := user.Current()
+ switch {
+ case err != nil:
+ return "user"
+ case runtime.GOOS == "windows":
+ // the domain is attached -- remove it again
+ split := strings.Split(u.Username, "\\")
+ return split[len(split)-1]
+ default:
+ return u.Username
+ }
+}