rss email digests over ssh because you're a cool kid
herald.dunkirk.sh
go
rss
rss-reader
ssh
charm
1// Package config handles Herald configuration parsing and validation.
2package config
3
4import (
5 "regexp"
6 "strconv"
7 "strings"
8)
9
10type FeedEntry struct {
11 URL string
12 Name string
13}
14
15type ParsedConfig struct {
16 Email string
17 CronExpr string
18 Digest bool
19 Inline bool
20 Feeds []FeedEntry
21}
22
23var feedLineRegex = regexp.MustCompile(`^=>\s+(\S+)(?:\s+"([^"]*)")?$`)
24
25func Parse(text string) (*ParsedConfig, error) {
26 cfg := &ParsedConfig{
27 Digest: true,
28 Inline: false,
29 Feeds: []FeedEntry{},
30 }
31
32 lines := strings.Split(text, "\n")
33 for _, line := range lines {
34 line = strings.TrimSpace(line)
35 if line == "" || strings.HasPrefix(line, "#") {
36 continue
37 }
38
39 if strings.HasPrefix(line, "=:") {
40 if err := parseDirective(cfg, line); err != nil {
41 return nil, err
42 }
43 } else if strings.HasPrefix(line, "=>") {
44 if err := parseFeed(cfg, line); err != nil {
45 return nil, err
46 }
47 }
48 }
49
50 return cfg, nil
51}
52
53func parseDirective(cfg *ParsedConfig, line string) error {
54 content := strings.TrimPrefix(line, "=:")
55 content = strings.TrimSpace(content)
56
57 parts := strings.SplitN(content, " ", 2)
58 if len(parts) < 2 {
59 return nil
60 }
61
62 key := strings.ToLower(parts[0])
63 value := strings.TrimSpace(parts[1])
64
65 switch key {
66 case "email":
67 cfg.Email = value
68 case "cron":
69 cfg.CronExpr = value
70 case "digest":
71 cfg.Digest = parseBool(value, true)
72 case "inline":
73 cfg.Inline = parseBool(value, false)
74 }
75
76 return nil
77}
78
79func parseFeed(cfg *ParsedConfig, line string) error {
80 matches := feedLineRegex.FindStringSubmatch(line)
81 if matches == nil {
82 return nil
83 }
84
85 entry := FeedEntry{
86 URL: matches[1],
87 Name: matches[2],
88 }
89 cfg.Feeds = append(cfg.Feeds, entry)
90
91 return nil
92}
93
94func parseBool(s string, defaultVal bool) bool {
95 b, err := strconv.ParseBool(s)
96 if err != nil {
97 return defaultVal
98 }
99 return b
100}