package jobconfig import ( "fmt" "os" "strings" "github.com/BurntSushi/toml" ) type File struct { Global GlobalConfig `toml:"global"` Playlists []PlaylistEntry `toml:"playlist"` } type GlobalConfig struct { Monitor *bool `toml:"monitor"` MonitorOnce *bool `toml:"monitor_once"` MonitorTransfer *bool `toml:"monitor_transfer"` MonitorInterval string `toml:"monitor_interval"` SyncMode string `toml:"sync_mode"` IncludeLiked *bool `toml:"include_liked"` DryRun *bool `toml:"dry_run"` PublicPlaylists *bool `toml:"public_playlists"` Concurrency *int `toml:"concurrency"` ReportPath string `toml:"report"` } type PlaylistEntry struct { URL string `toml:"url"` SyncMode string `toml:"sync_mode"` TargetPlaylistID int64 `toml:"target_playlist_id"` Enabled *bool `toml:"enabled"` } func Load(path string) (File, error) { var cfg File if strings.TrimSpace(path) == "" { return cfg, fmt.Errorf("empty config path") } b, err := os.ReadFile(path) if err != nil { return cfg, err } if err := toml.Unmarshal(b, &cfg); err != nil { return cfg, fmt.Errorf("parse toml config: %w", err) } for i, p := range cfg.Playlists { if strings.TrimSpace(p.URL) == "" { return cfg, fmt.Errorf("playlist entry %d missing url", i+1) } mode := strings.ToLower(strings.TrimSpace(p.SyncMode)) if mode != "" && mode != "append" && mode != "mirror" { return cfg, fmt.Errorf("playlist entry %d has invalid sync_mode %q", i+1, p.SyncMode) } if p.TargetPlaylistID < 0 { return cfg, fmt.Errorf("playlist entry %d has invalid target_playlist_id %d", i+1, p.TargetPlaylistID) } } if mode := strings.ToLower(strings.TrimSpace(cfg.Global.SyncMode)); mode != "" && mode != "append" && mode != "mirror" { return cfg, fmt.Errorf("invalid global sync_mode %q", cfg.Global.SyncMode) } return cfg, nil } func (p PlaylistEntry) IsEnabled() bool { if p.Enabled == nil { return true } return *p.Enabled }