package checker import ( "context" "strings" "sync" "time" sdk "git.happydns.org/checker-sdk-go/checker" "golang.org/x/net/publicsuffix" ) // Collect fans out the registered sources concurrently and folds their // results into a single observation. Adding a new source means // implementing the Source interface in its own file and calling // Register(...) from init(); Collect needs no changes. func (p *blacklistProvider) Collect(ctx context.Context, opts sdk.CheckerOptions) (any, error) { domain := normalizeDomain(stringOpt(opts, "domain_name")) if domain == "" { // Standalone /check form posts "domain"; happyDomain auto-fills // "domain_name". Accept both so the path stays uniform. domain = normalizeDomain(stringOpt(opts, "domain")) } registered, _ := publicsuffix.EffectiveTLDPlusOne(domain) if registered == "" { registered = domain } data := &BlacklistData{ Domain: domain, RegisteredDomain: registered, CollectedAt: time.Now(), } sources := Sources() per := make([][]SourceResult, len(sources)) var wg sync.WaitGroup for i, s := range sources { wg.Add(1) go func(i int, s Source) { defer wg.Done() per[i] = s.Query(ctx, domain, registered, opts) }(i, s) } wg.Wait() for _, batch := range per { data.Results = append(data.Results, batch...) } return data, nil } func normalizeDomain(s string) string { return strings.ToLower(strings.TrimSuffix(strings.TrimSpace(s), ".")) }