diff options
-rw-r--r-- | cmd/feed2imap-go.go | 30 | ||||
-rw-r--r-- | internal/config/config.go | 52 | ||||
-rw-r--r-- | internal/config/yaml.go | 71 | ||||
-rw-r--r-- | main.go | 138 |
4 files changed, 153 insertions, 138 deletions
diff --git a/cmd/feed2imap-go.go b/cmd/feed2imap-go.go new file mode 100644 index 0000000..20e6ed7 --- /dev/null +++ b/cmd/feed2imap-go.go @@ -0,0 +1,30 @@ +package main + +import ( + "flag" + "github.com/Necoro/feed2imap-go/internal/config" + "log" + "os" +) + +var cfgFile = flag.String("f", "config.yml", "configuration file") + +func run() error { + log.Print("Starting up...") + flag.Parse() + + log.Printf("Reading configuration file '%s'", *cfgFile) + if _, err := config.Load(*cfgFile); err != nil { + return err + } + + return nil +} + +func main() { + if err := run(); err != nil { + log.SetOutput(os.Stderr) + log.Print("Error: ", err) + os.Exit(1) + } +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..2df7d98 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,52 @@ +package config + +import ( + "fmt" + "gopkg.in/yaml.v3" + "io/ioutil" +) + +type Map map[string]interface{} +type Feeds map[string]*Feed + +type config struct { + GlobalConfig Map `yaml:",inline"` + Feeds []configGroupFeed +} + +type Config struct { + GlobalConfig Map `yaml:",inline"` + Feeds Feeds +} + +type Feed struct { + Name string + Target string + Url string + MinFreq int + Config Map +} + +func Load(path string) (*Config, error) { + buf, err := ioutil.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("while reading '%s': %w", path, err) + } + + var parsedCfg config + if err := yaml.Unmarshal(buf, &parsedCfg); err != nil { + return nil, fmt.Errorf("while unmarshalling: %w", err) + } + fmt.Printf("--- parsedCfg:\n%+v\n\n", parsedCfg) + + var finishedCfg = Config{ + GlobalConfig: parsedCfg.GlobalConfig, + Feeds: make(Feeds), + } + + if err := buildFeeds(parsedCfg.Feeds, "", finishedCfg.Feeds); err != nil { + return nil, fmt.Errorf("while parsing: %w", err) + } + + return &finishedCfg, nil +} diff --git a/internal/config/yaml.go b/internal/config/yaml.go new file mode 100644 index 0000000..335dede --- /dev/null +++ b/internal/config/yaml.go @@ -0,0 +1,71 @@ +package config + +import "fmt" + +type Group struct { + Group string + Feeds []configGroupFeed +} + +type configGroupFeed struct { + Target *string + Feed `yaml:",inline"` + Group `yaml:",inline"` +} + +func (grpFeed *configGroupFeed) isGroup() bool { + return grpFeed.Group.Group != "" +} + +func (grpFeed *configGroupFeed) isFeed() bool { + return grpFeed.Name != "" +} + +func (grpFeed *configGroupFeed) target() string { + if grpFeed.Target != nil { + return *grpFeed.Target + } + if grpFeed.Name != "" { + return grpFeed.Name + } + + return grpFeed.Group.Group +} + +func appTarget(target, app string) string { + if target == "" { + return app + } + + if app == "" { + return target + } + + return target + "/" + app +} + +// Parse the group structure and populate the `Target` fields in the feeds +func buildFeeds(cfg []configGroupFeed, target string, feeds Feeds) error { + for _, f := range cfg { + target := appTarget(target, f.target()) + switch { + case f.isFeed() && f.isGroup(): + return fmt.Errorf("Entry with Target %s is both a Feed and a group", target) + + case f.isFeed(): + name := f.Feed.Name + if _, ok := feeds[name]; !ok { + return fmt.Errorf("Duplicate Feed Name '%s'", name) + } + f.Feed.Target = target + feeds[name] = &f.Feed + + case f.isGroup(): + if err := buildFeeds(f.Group.Feeds, target, feeds); err != nil { + return err + } + } + } + + return nil +} diff --git a/main.go b/main.go deleted file mode 100644 index b238ff0..0000000 --- a/main.go +++ /dev/null @@ -1,138 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "io/ioutil" - "log" - "os" - - "gopkg.in/yaml.v3" -) - -var cfg = flag.String("f", "config.yml", "configuration file") - -type ConfigMap map[string]interface{} - -type configFeed struct { - Name string - Url string - MinFreq int `yaml:"min-frequency"` - ConfigMap `yaml:",inline"` -} - -type configGroup struct { - Group string - Feeds []configGroupFeed -} - -type configGroupFeed struct { - Target *string - configFeed `yaml:",inline"` - configGroup `yaml:",inline"` -} - -func (grpFeed *configGroupFeed) isGroup() bool { - return grpFeed.configGroup.Group != "" -} - -func (grpFeed *configGroupFeed) isFeed() bool { - return grpFeed.configFeed.Name != "" -} - -func (grpFeed *configGroupFeed) target() string { - if grpFeed.Target != nil { - return *grpFeed.Target - } - if grpFeed.Name != "" { - return grpFeed.Name - } - - return grpFeed.Group -} - -type config struct { - GlobalConfig ConfigMap `yaml:",inline"` - Feeds []configGroupFeed -} - -type feed struct { - name string - target string - url string - minFreq int - config ConfigMap -} - -var feeds = make(map[string]*feed) - -func appTarget(target, app string) string { - if target == "" { - return app - } - - if app == "" { - return target - } - - return target + "/" + app -} - -func buildFeeds(cfg []configGroupFeed, target string) error { - for _, f := range cfg { - target := appTarget(target, f.target()) - switch { - case f.isFeed() && f.isGroup(): - return fmt.Errorf("Entry with Target %s is both a feed and a group", target) - case f.isFeed(): - name := f.Name - if _, ok := feeds[name]; !ok { - return fmt.Errorf("Duplicate feed name '%s'", name) - } - feeds[name] = &feed{ - name: name, - target: target, - url: f.Url, - minFreq: f.MinFreq, - config: f.ConfigMap, - } - case f.isGroup(): - if err := buildFeeds(f.Feeds, target); err != nil { - return err - } - } - } - - return nil -} - -func run() error { - log.Print("Starting up...") - flag.Parse() - - log.Printf("Reading configuration file '%s'", *cfg) - buf, err := ioutil.ReadFile(*cfg) - if err != nil { - return fmt.Errorf("while reading '%s': %w", *cfg, err) - } - - var parsedCfg config - if err := yaml.Unmarshal(buf, &parsedCfg); err != nil { - return fmt.Errorf("while unmarshalling: %w", err) - } - fmt.Printf("--- parsedCfg:\n%+v\n\n", parsedCfg) - - if err := buildFeeds(parsedCfg.Feeds, ""); err != nil { - return fmt.Errorf("while parsing: %w", err) - } - - return nil -} - -func main() { - if err := run(); err != nil { - log.SetOutput(os.Stderr) - log.Print("Error: ", err) - os.Exit(1) - } -} |