You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
5.1 KiB
144 lines
5.1 KiB
package config |
|
|
|
import ( |
|
"fmt" |
|
"os" |
|
"strings" |
|
|
|
"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 { |
|
Feeds string `yaml:"feeds"` // Single relay for feeds |
|
Profiles string `yaml:"profiles"` // Comma-separated list of relays for profiles and deletion events |
|
ContactForm string `yaml:"contactform"` // Comma-separated list of relays for contact form |
|
} `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"` |
|
} |
|
|
|
// LoadConfig loads configuration from a YAML file |
|
// If the file doesn't exist, returns a config with all defaults |
|
func LoadConfig(path string) (*Config, error) { |
|
data, err := os.ReadFile(path) |
|
if err != nil { |
|
if os.IsNotExist(err) { |
|
// File doesn't exist, return config with all defaults |
|
config := &Config{} |
|
setDefaults(config) |
|
return config, 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) |
|
} |
|
|
|
setDefaults(&config) |
|
return &config, nil |
|
} |
|
|
|
// setDefaults applies default values to a config struct |
|
func setDefaults(config *Config) { |
|
if config.WikiIndex == "" { |
|
config.WikiIndex = "naddr1qvzqqqr4tqpzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqyd8wumn8ghj7argv4nx7un9wd6zumn0wd68yvfwvdhk6qgmwaehxw309a6xsetrd96xzer9dshxummnw3erztnrdakszyrhwden5te0dehhxarj9ekxzmnyqyg8wumn8ghj7mn0wd68ytnhd9hx2qghwaehxw309ahx7um5wgh8xmmkvf5hgtngdaehgqg3waehxw309ahx7um5wgerztnrdaksz9thwden5te0v9nkwu3wdehhxarj9ekxzmnyqyv8wumn8ghj7un9d3shjtnwdaehw6r9wfjjucm0d5q3gamnwvaz7tmjv4kxz7fwv3sk6atn9e5k7qgewaehxw309an8yet9d3shjtnndamxy6t59e5x7um5qqhxw6t5vd5hgctyv4kz6urjda4x2cm594jx7cm4d4jkuarpw35k7m3dvfuj6um5v4kxccfdwcknzhekhth" |
|
} |
|
if config.BlogIndex == "" { |
|
config.BlogIndex = "naddr1qvzqqqr4tqpzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqyd8wumn8ghj7argv4nx7un9wd6zumn0wd68yvfwvdhk6qgmwaehxw309a6xsetrd96xzer9dshxummnw3erztnrdakszyrhwden5te0dehhxarj9ekxzmnyqyg8wumn8ghj7mn0wd68ytnhd9hx2qghwaehxw309ahx7um5wgh8xmmkvf5hgtngdaehgqg3waehxw309ahx7um5wgerztnrdaksz9thwden5te0v9nkwu3wdehhxarj9ekxzmnyqyv8wumn8ghj7un9d3shjtnwdaehw6r9wfjjucm0d5q3gamnwvaz7tmjv4kxz7fwv3sk6atn9e5k7qgewaehxw309an8yet9d3shjtnndamxy6t59e5x7um5qqshg6r994nkjarrd96xzer9dskkymr0vukky7fdwd6x2mrvvykhvtf3q3js44" |
|
} |
|
if config.Relays.Feeds == "" { |
|
config.Relays.Feeds = "wss://theforest.nostr1.com" |
|
} |
|
if config.Relays.Profiles == "" { |
|
config.Relays.Profiles = "wss://theforest.nostr1.com,wss://nostr.land,wss://thecitadel.nostr1.com" |
|
} |
|
if config.Relays.ContactForm == "" { |
|
config.Relays.ContactForm = "wss://thecitadel.nostr1.com,wss://relay.damus.io,wss://freelay.sovbit.host,wss://relay.primal.net" |
|
} |
|
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 = config.Relays.Feeds |
|
} |
|
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" |
|
} |
|
} |
|
|
|
// parseRelayList parses a comma-separated relay string into a slice |
|
func parseRelayList(relayStr string) []string { |
|
if relayStr == "" { |
|
return []string{} |
|
} |
|
relays := strings.Split(relayStr, ",") |
|
result := make([]string, 0, len(relays)) |
|
for _, relay := range relays { |
|
relay = strings.TrimSpace(relay) |
|
// Remove quotes if present |
|
relay = strings.Trim(relay, "\"'") |
|
if relay != "" { |
|
result = append(result, relay) |
|
} |
|
} |
|
return result |
|
} |
|
|
|
// GetProfilesRelays parses the comma-separated profiles relay string into a slice |
|
func (c *Config) GetProfilesRelays() []string { |
|
return parseRelayList(c.Relays.Profiles) |
|
} |
|
|
|
// GetContactFormRelays parses the comma-separated contact form relay string into a slice |
|
func (c *Config) GetContactFormRelays() []string { |
|
return parseRelayList(c.Relays.ContactForm) |
|
} |
|
|
|
// Validate validates the configuration |
|
func (c *Config) Validate() error { |
|
if c.Relays.Feeds == "" { |
|
return fmt.Errorf("relays.feeds is required") |
|
} |
|
return nil |
|
}
|
|
|