package config import ( "fmt" "os" "gopkg.in/yaml.v3" ) // Config represents the application configuration type Config struct { WikiIndex string `yaml:"wiki_index"` BlogIndex string `yaml:"blog_index"` RepoAnnouncement string `yaml:"repo_announcement"` // naddr for kind 30617 repo announcement Relays struct { Primary string `yaml:"primary"` Fallback string `yaml:"fallback"` AdditionalFallback string `yaml:"additional_fallback"` } `yaml:"relays"` LinkBaseURL string `yaml:"link_base_url"` Cache struct { RefreshIntervalMinutes int `yaml:"refresh_interval_minutes"` } `yaml:"cache"` Feed struct { Relay string `yaml:"relay"` PollIntervalMinutes int `yaml:"poll_interval_minutes"` MaxEvents int `yaml:"max_events"` } `yaml:"feed"` Server struct { Port int `yaml:"port"` EnableCompression bool `yaml:"enable_compression"` } `yaml:"server"` SEO struct { SiteName string `yaml:"site_name"` SiteURL string `yaml:"site_url"` DefaultImage string `yaml:"default_image"` } `yaml:"seo"` WikiKinds []int `yaml:"wiki_kinds"` // Supported wiki kinds (default: 30818) BlogKinds []int `yaml:"blog_kinds"` // Supported blog kinds (default: 30041) ArticleKinds []int `yaml:"article_kinds"` // Supported article kinds (deprecated, use wiki_kinds and blog_kinds) IndexKind int `yaml:"index_kind"` // Index event kind (default: 30040) IssueKind int `yaml:"issue_kind"` // Issue event kind (default: 1621) RepoAnnouncementKind int `yaml:"repo_announcement_kind"` // Repo announcement kind (default: 30617) FeedKind int `yaml:"feed_kind"` // Feed event kind (default: 1) } // LoadConfig loads configuration from a YAML file func LoadConfig(path string) (*Config, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } var config Config if err := yaml.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } // Set defaults if config.Relays.Primary == "" { config.Relays.Primary = "wss://theforest.nostr1.com" } if config.Relays.Fallback == "" { config.Relays.Fallback = "wss://nostr.land" } if config.Relays.AdditionalFallback == "" { config.Relays.AdditionalFallback = "wss://thecitadel.nostr1.com" } if config.LinkBaseURL == "" { config.LinkBaseURL = "https://alexandria.gitcitadel.eu" } if config.Cache.RefreshIntervalMinutes == 0 { config.Cache.RefreshIntervalMinutes = 30 } if config.Feed.Relay == "" { config.Feed.Relay = "wss://theforest.nostr1.com" } if config.Feed.PollIntervalMinutes == 0 { config.Feed.PollIntervalMinutes = 5 } if config.Feed.MaxEvents == 0 { config.Feed.MaxEvents = 30 } if config.Server.Port == 0 { config.Server.Port = 8080 } if config.SEO.SiteName == "" { config.SEO.SiteName = "GitCitadel" } if config.SEO.SiteURL == "" { config.SEO.SiteURL = "https://gitcitadel.com" } if config.SEO.DefaultImage == "" { config.SEO.DefaultImage = "/static/GitCitadel_Graphic_Landscape.png" } // Backward compatibility: if ArticleKinds is set, use it to populate WikiKinds and BlogKinds if len(config.ArticleKinds) > 0 { config.WikiKinds = []int{} config.BlogKinds = []int{} for _, kind := range config.ArticleKinds { switch kind { case 30818: config.WikiKinds = append(config.WikiKinds, kind) case 30041: config.BlogKinds = append(config.BlogKinds, kind) } } } // Set default wiki kind if not specified if len(config.WikiKinds) == 0 { config.WikiKinds = []int{30818} // Default: wiki (30818) } // Set default blog kind if not specified if len(config.BlogKinds) == 0 { config.BlogKinds = []int{30041} // Default: blog (30041) } // Set default event kinds if not specified if config.IndexKind == 0 { config.IndexKind = 30040 // Default: index (30040) } if config.IssueKind == 0 { config.IssueKind = 1621 // Default: issue (1621) } if config.RepoAnnouncementKind == 0 { config.RepoAnnouncementKind = 30617 // Default: repo announcement (30617) } if config.FeedKind == 0 { config.FeedKind = 1 // Default: feed (1) } // Validate required fields if config.WikiIndex == "" { return nil, fmt.Errorf("wiki_index is required") } return &config, nil } // Validate validates the configuration func (c *Config) Validate() error { if c.WikiIndex == "" { return fmt.Errorf("wiki_index is required") } if c.Relays.Primary == "" { return fmt.Errorf("relays.primary is required") } return nil }