Subscribe and post RSS feeds to Bluesky
rss bluesky
at main 2.6 kB view raw
1package config 2 3import ( 4 "fmt" 5 "os" 6 "strings" 7 "time" 8 9 "gopkg.in/yaml.v3" 10) 11 12// Config represents the application configuration 13type Config struct { 14 Accounts []Account `yaml:"accounts"` 15 Interval time.Duration `yaml:"interval,omitempty"` 16 Storage string `yaml:"storage,omitempty"` 17} 18 19// Account represents a Bluesky account with its associated feeds 20type Account struct { 21 Handle string `yaml:"handle"` 22 Password string `yaml:"password,omitempty"` 23 PDS string `yaml:"pds,omitempty"` 24 Feeds []string `yaml:"feeds"` 25 Storage string `yaml:"storage,omitempty"` // Optional per-account storage file 26} 27 28// LoadFromFile loads configuration from a YAML file 29func LoadFromFile(path string) (*Config, error) { 30 data, err := os.ReadFile(path) 31 if err != nil { 32 return nil, fmt.Errorf("failed to read config file: %w", err) 33 } 34 35 var cfg Config 36 if err := yaml.Unmarshal(data, &cfg); err != nil { 37 return nil, fmt.Errorf("failed to parse config file: %w", err) 38 } 39 40 if err := cfg.Validate(); err != nil { 41 return nil, fmt.Errorf("invalid configuration: %w", err) 42 } 43 44 // Process environment variables in passwords 45 for i := range cfg.Accounts { 46 cfg.Accounts[i].Password = expandEnvVar(cfg.Accounts[i].Password) 47 } 48 49 // Set defaults 50 if cfg.Interval == 0 { 51 cfg.Interval = 15 * time.Minute 52 } 53 if cfg.Storage == "" { 54 cfg.Storage = "posted_items.txt" 55 } 56 57 return &cfg, nil 58} 59 60// Validate checks if the configuration is valid 61func (c *Config) Validate() error { 62 if len(c.Accounts) == 0 { 63 return fmt.Errorf("at least one account is required") 64 } 65 66 for i, account := range c.Accounts { 67 if account.Handle == "" { 68 return fmt.Errorf("account %d: handle is required", i) 69 } 70 if len(account.Feeds) == 0 { 71 return fmt.Errorf("account %d (%s): at least one feed is required", i, account.Handle) 72 } 73 if account.Password == "" { 74 return fmt.Errorf("account %d (%s): password is required", i, account.Handle) 75 } 76 } 77 78 return nil 79} 80 81// expandEnvVar expands environment variable references in the format ${VAR_NAME} or $VAR_NAME 82func expandEnvVar(value string) string { 83 if value == "" { 84 return value 85 } 86 87 // Handle ${VAR_NAME} format 88 if strings.HasPrefix(value, "${") && strings.HasSuffix(value, "}") { 89 varName := value[2 : len(value)-1] 90 if envVal := os.Getenv(varName); envVal != "" { 91 return envVal 92 } 93 return value 94 } 95 96 // Handle $VAR_NAME format 97 if strings.HasPrefix(value, "$") { 98 varName := value[1:] 99 if envVal := os.Getenv(varName); envVal != "" { 100 return envVal 101 } 102 return value 103 } 104 105 return value 106}