110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sync/atomic"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type ButtonColor string
|
|
|
|
const (
|
|
ColorPrimary ButtonColor = "primary"
|
|
ColorSecondary ButtonColor = "secondary"
|
|
ColorSuccess ButtonColor = "success"
|
|
ColorDanger ButtonColor = "danger"
|
|
)
|
|
|
|
type TicketType struct {
|
|
ButtonLabel string `yaml:"button_label"`
|
|
ButtonColor ButtonColor `yaml:"button_color"`
|
|
ButtonEmoji string `yaml:"button_emoji"`
|
|
EmbedColor string `yaml:"embed_color"`
|
|
EmbedTitle string `yaml:"embed_title"`
|
|
EmbedText string `yaml:"embed_text"`
|
|
StaffRole string `yaml:"staff_role"`
|
|
Category string `yaml:"category"`
|
|
}
|
|
|
|
type Panel struct {
|
|
EmbedTitle string `yaml:"embed_title"`
|
|
EmbedDescription string `yaml:"embed_description"`
|
|
EmbedColor string `yaml:"embed_color"`
|
|
Types map[string]TicketType `yaml:"types"`
|
|
}
|
|
|
|
type Bot struct {
|
|
AdminRole string `yaml:"admin_role"`
|
|
LogsChannel string `yaml:"logs_channel"`
|
|
ClaimChannel string `yaml:"claim_channel"`
|
|
ConvocationCategory string `yaml:"convocation_category"`
|
|
ClaimReupMinutes int `yaml:"claim_reup_minutes"`
|
|
AllowedGuilds []string `yaml:"allowed_guilds"` // whitelist; empty = use GUILD_ID env only
|
|
}
|
|
|
|
type PanelWebConfig struct {
|
|
Port int `yaml:"port"`
|
|
BaseURL string `yaml:"base_url"`
|
|
OAuthClientID string `yaml:"oauth_client_id"`
|
|
OAuthClientSecret string `yaml:"oauth_client_secret"`
|
|
SessionTimeoutMinutes int `yaml:"session_timeout_minutes"`
|
|
}
|
|
|
|
type Config struct {
|
|
Bot Bot `yaml:"bot"`
|
|
Panel PanelWebConfig `yaml:"panel"`
|
|
Panels map[string]Panel `yaml:"panels"`
|
|
}
|
|
|
|
func (c *Config) Validate() error {
|
|
if c.Bot.AdminRole == "" {
|
|
return fmt.Errorf("bot.admin_role is required")
|
|
}
|
|
if c.Bot.ClaimReupMinutes <= 0 {
|
|
c.Bot.ClaimReupMinutes = 30
|
|
}
|
|
if c.Panel.Port <= 0 {
|
|
c.Panel.Port = 8080
|
|
}
|
|
if c.Panel.SessionTimeoutMinutes <= 0 {
|
|
c.Panel.SessionTimeoutMinutes = 30
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Load(path string) (*Config, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read config: %w", err)
|
|
}
|
|
var cfg Config
|
|
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
|
return nil, fmt.Errorf("parse config: %w", err)
|
|
}
|
|
if err := cfg.Validate(); err != nil {
|
|
return nil, err
|
|
}
|
|
return &cfg, nil
|
|
}
|
|
|
|
// Provider holds the current config and allows atomic swaps.
|
|
type Provider struct {
|
|
ptr atomic.Pointer[Config]
|
|
}
|
|
|
|
func NewProvider(cfg *Config) *Provider {
|
|
p := &Provider{}
|
|
p.ptr.Store(cfg)
|
|
return p
|
|
}
|
|
|
|
func (p *Provider) Get() *Config {
|
|
return p.ptr.Load()
|
|
}
|
|
|
|
func (p *Provider) Swap(cfg *Config) {
|
|
p.ptr.Store(cfg)
|
|
}
|