Skip to content

Commit ccdf36d

Browse files
committed
Output of /spots modified to provide - at the very least - the same data as int2001/DXClusterAPI.
1 parent 6ef9f96 commit ccdf36d

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

internal/spot/spot.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package spot
22

33
import (
4+
"encoding/json"
5+
"fmt"
46
"time"
57

68
"github.com/user00265/dxclustergoapi/internal/dxcc"
@@ -35,6 +37,75 @@ type Spot struct {
3537
} `json:"additional_data,omitempty"`
3638
}
3739

40+
// MarshalJSON customizes the JSON output to match the expected API format
41+
func (s Spot) MarshalJSON() ([]byte, error) {
42+
// Helper to build the flattened DXCC+LoTW object
43+
type FlatInfo struct {
44+
Cont string `json:"cont,omitempty"`
45+
Entity string `json:"entity,omitempty"`
46+
Flag string `json:"flag,omitempty"`
47+
DXCCID interface{} `json:"dxcc_id,omitempty"` // string in output
48+
LoTWUser interface{} `json:"lotw_user"` // "2" or false
49+
Lat interface{} `json:"lat,omitempty"` // string in output
50+
Lng interface{} `json:"lng,omitempty"` // string in output
51+
}
52+
53+
buildFlatInfo := func(info Info) *FlatInfo {
54+
flat := &FlatInfo{}
55+
if info.DXCC != nil {
56+
flat.Cont = info.DXCC.Cont
57+
flat.Entity = info.DXCC.Entity
58+
flat.Flag = info.DXCC.Flag
59+
// Convert numbers to strings to match expected format
60+
if info.DXCC.DXCCID != 0 {
61+
flat.DXCCID = fmt.Sprintf("%d", info.DXCC.DXCCID)
62+
}
63+
if info.DXCC.Latitude != 0 {
64+
flat.Lat = fmt.Sprintf("%.1f", info.DXCC.Latitude)
65+
}
66+
if info.DXCC.Longitude != 0 {
67+
flat.Lng = fmt.Sprintf("%.1f", info.DXCC.Longitude)
68+
}
69+
}
70+
// LoTW user: "2" if user, false if not
71+
if info.IsLoTWUser && info.LoTW != nil {
72+
flat.LoTWUser = "2" // Indicates LoTW user with upload
73+
} else {
74+
flat.LoTWUser = false
75+
}
76+
return flat
77+
}
78+
79+
// Build the output structure - simple keys first, then objects
80+
output := struct {
81+
Spotter string `json:"spotter"`
82+
Spotted string `json:"spotted"`
83+
Frequency float64 `json:"frequency"`
84+
Band string `json:"band"`
85+
Message string `json:"message"`
86+
When time.Time `json:"when"`
87+
Source string `json:"source,omitempty"` // Extra: helpful for debugging
88+
PotaRef string `json:"pota_ref,omitempty"` // Extra: POTA reference (only for POTA spots)
89+
PotaMode string `json:"pota_mode,omitempty"` // Extra: POTA mode (only for POTA spots)
90+
DXCCSpotter *FlatInfo `json:"dxcc_spotter,omitempty"`
91+
DXCCSpotted *FlatInfo `json:"dxcc_spotted,omitempty"`
92+
}{
93+
Spotter: s.Spotter,
94+
Spotted: s.Spotted,
95+
Frequency: s.Frequency,
96+
Band: s.Band,
97+
Message: s.Message,
98+
When: s.When,
99+
Source: s.Source,
100+
PotaRef: s.AdditionalData.PotaRef,
101+
PotaMode: s.AdditionalData.PotaMode,
102+
DXCCSpotter: buildFlatInfo(s.SpotterInfo),
103+
DXCCSpotted: buildFlatInfo(s.SpottedInfo),
104+
}
105+
106+
return json.Marshal(output)
107+
}
108+
38109
// BandFromName converts a frequency to a ham radio band string.
39110
// Accepts frequency in Hz, kHz, or MHz and automatically detects the unit.
40111
// This function mirrors the qrg2band from the Node.js original.

0 commit comments

Comments
 (0)