This commit is contained in:
2026-06-06 11:59:32 +02:00
parent 176cc0e62b
commit f91f9ff3b8
13 changed files with 866 additions and 90 deletions
+33
View File
@@ -3,6 +3,7 @@ package awardref
import (
"context"
"encoding/csv"
"encoding/json"
"fmt"
"io"
"net/http"
@@ -24,6 +25,38 @@ var Importers = map[string]Importer{
"POTA": {AwardCode: "POTA", URL: "https://pota.app/all_parks.csv", Fetch: parsePOTA},
"SOTA": {AwardCode: "SOTA", URL: "https://www.sotadata.org.uk/summitslist.csv", Fetch: parseSOTA},
"WWFF": {AwardCode: "WWFF", URL: "https://wwff.co/wwff-data/wwff_directory.csv", Fetch: parseWWFF},
"IOTA": {AwardCode: "IOTA", URL: "https://www.iota-world.org/islands-on-the-air/downloads/download-file.html?path=groups.json", Fetch: parseIOTA},
}
// parseIOTA reads iota-world.org's groups.json (refreshed daily): an array of
// {refno, name, dxcc_num, grp_region}. The reference is the IOTA number
// (EU-005); the DXCC number lets the per-QSO picker filter by entity.
func parseIOTA(_ context.Context, body io.Reader) ([]Ref, error) {
var groups []struct {
RefNo string `json:"refno"`
Name string `json:"name"`
DXCC string `json:"dxcc_num"`
Region string `json:"grp_region"`
}
if err := json.NewDecoder(body).Decode(&groups); err != nil {
return nil, fmt.Errorf("parse IOTA json: %w", err)
}
out := make([]Ref, 0, len(groups))
for _, g := range groups {
ref := strings.ToUpper(strings.TrimSpace(g.RefNo))
if ref == "" {
continue
}
dxcc, _ := strconv.Atoi(strings.TrimSpace(g.DXCC))
grp := strings.TrimSpace(g.Region)
if grp == "" { // fall back to the continent prefix (AF/EU/NA/…)
if i := strings.IndexByte(ref, '-'); i > 0 {
grp = ref[:i]
}
}
out = append(out, Ref{Code: ref, Name: strings.TrimSpace(g.Name), DXCC: dxcc, Group: grp})
}
return out, nil
}
// CanUpdate reports whether an award has an online reference list.