Add support for POTA hunters

POTA references in non-POTA logs are supported by the canonical FLE
app. This patch enables that functionality in FLEcli

Branch: support-pota-hunters
Eric Codes 5 months ago
parent c5846fb1f4
commit fdb4d811ce
No known key found for this signature in database
GPG Key ID: 44D24E841F816A7B

@ -0,0 +1 @@
use flake

1
.gitignore vendored

@ -18,3 +18,4 @@ coverage.txt
# Dependency directories (remove the comment below to include it) # Dependency directories (remove the comment below to include it)
# vendor/ # vendor/
/.direnv/

@ -0,0 +1,44 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1718530797,
"narHash": "sha256-pup6cYwtgvzDpvpSCFh1TEUjw2zkNpk8iolbKnyFmmU=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b60ebf54c15553b393d144357375ea956f89e9a9",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-24-05": {
"locked": {
"lastModified": 1718437845,
"narHash": "sha256-ZT7Oc1g4I4pHVGGjQFnewFVDRLH5cIZhEzODLz9YXeY=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "752c634c09ceb50c45e751f8791cb45cb3d46c9e",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"nixpkgs-24-05": "nixpkgs-24-05"
}
}
},
"root": "root",
"version": 7
}

@ -0,0 +1,30 @@
{
description = "A very basic flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
nixpkgs-24-05.url = "github:nixos/nixpkgs?ref=nixos-24.05";
};
outputs = { self, nixpkgs, nixpkgs-24-05 }:
let
pkgs = import nixpkgs {
system = "x86_64-linux";
};
pkgs-24-05 = import nixpkgs-24-05 {
system = "x86_64-linux";
};
in {
devShell.x86_64-linux = pkgs.mkShell {
buildInputs = with pkgs; [
go
gopls
golangci-lint
bats
pkgs-24-05.goreleaser
];
};
};
}

@ -53,15 +53,15 @@ func buildAdif(fullLog []LogLine, adifParams AdifParams) (adifList []string) {
} }
adifLine.WriteString(adifElement("RST_SENT", logLine.RSTsent)) adifLine.WriteString(adifElement("RST_SENT", logLine.RSTsent))
adifLine.WriteString(adifElement("RST_RCVD", logLine.RSTrcvd)) adifLine.WriteString(adifElement("RST_RCVD", logLine.RSTrcvd))
if logLine.GridLoc != "" {
adifLine.WriteString(adifElement("GRIDSQUARE", logLine.GridLoc))
}
if logLine.Comment != "" { if logLine.Comment != "" {
adifLine.WriteString(adifElement("COMMENT", logLine.Comment)) adifLine.WriteString(adifElement("COMMENT", logLine.Comment))
} }
if logLine.OMname != "" { if logLine.OMname != "" {
adifLine.WriteString(adifElement("NAME", logLine.OMname)) adifLine.WriteString(adifElement("NAME", logLine.OMname))
} }
if logLine.GridLoc != "" {
adifLine.WriteString(adifElement("GRIDSQUARE", logLine.GridLoc))
}
if logLine.QSLmsg != "" { if logLine.QSLmsg != "" {
adifLine.WriteString(adifElement("QSLMSG", logLine.QSLmsg)) adifLine.WriteString(adifElement("QSLMSG", logLine.QSLmsg))
} }
@ -76,11 +76,13 @@ func buildAdif(fullLog []LogLine, adifParams AdifParams) (adifList []string) {
if adifParams.IsPOTA { if adifParams.IsPOTA {
adifLine.WriteString(adifElement("MY_SIG", "POTA")) adifLine.WriteString(adifElement("MY_SIG", "POTA"))
adifLine.WriteString(adifElement("MY_SIG_INFO", logLine.MyPOTA)) adifLine.WriteString(adifElement("MY_SIG_INFO", logLine.MyPOTA))
if logLine.POTA != "" {
adifLine.WriteString(adifElement("SIG", "POTA"))
adifLine.WriteString(adifElement("SIG_INFO", logLine.POTA))
}
} }
if logLine.POTA != "" {
adifLine.WriteString(adifElement("SIG", "POTA"))
adifLine.WriteString(adifElement("SIG_INFO", logLine.POTA))
}
if adifParams.IsSOTA { if adifParams.IsSOTA {
adifLine.WriteString(adifElement("MY_SOTA_REF", logLine.MySOTA)) adifLine.WriteString(adifElement("MY_SOTA_REF", logLine.MySOTA))
if logLine.SOTA != "" { if logLine.SOTA != "" {

@ -124,6 +124,22 @@ func Test_buildAdif(t *testing.T) {
"<STATION_CALLSIGN:8>ON4KJM/P <CALL:5>ON4LY <QSO_DATE:8>20200524 <TIME_ON:4>1312 <BAND:3>20m <MODE:2>CW <RST_SENT:3>559 <RST_RCVD:3>599 <MY_SIG:4>POTA <MY_SIG_INFO:8>ON-00259 <SIG:4>POTA <SIG_INFO:8>DL-00001 <OPERATOR:6>ON4KJM <MY_GRIDSQUARE:6>JO40eu <MY_LAT:10>15.1234567 <MY_LON:12>-123.1234567 <EOR>", "<STATION_CALLSIGN:8>ON4KJM/P <CALL:5>ON4LY <QSO_DATE:8>20200524 <TIME_ON:4>1312 <BAND:3>20m <MODE:2>CW <RST_SENT:3>559 <RST_RCVD:3>599 <MY_SIG:4>POTA <MY_SIG_INFO:8>ON-00259 <SIG:4>POTA <SIG_INFO:8>DL-00001 <OPERATOR:6>ON4KJM <MY_GRIDSQUARE:6>JO40eu <MY_LAT:10>15.1234567 <MY_LON:12>-123.1234567 <EOR>",
} }
sampleFilledLogPOTAHunter := []LogLine{
{MyCall: "ON4KJM/P", Call: "S57LC", Date: "2020-05-24", MyGrid: "JO40eu", Time: "1310", Band: "20m", Frequency: "14.045", Mode: "CW", RSTsent: "599", RSTrcvd: "599", GridLoc: "JO50", Operator: "ON4KJM", Nickname: "ON-00259-1"},
{MyCall: "ON4KJM/P", Call: "ON4LY", Date: "2020-05-24", MyGrid: "JO40eu", Time: "1312", Band: "20m", Mode: "CW", RSTsent: "559", RSTrcvd: "599", Operator: "ON4KJM", POTA: "DL-00001"},
{MyCall: "ON4KJM/P", Call: "ON4LY", Date: "2020-05-24", MyGrid: "JO40eu", Time: "1312", Band: "20m", Mode: "CW", RSTsent: "559", RSTrcvd: "599", Operator: "ON4KJM", POTA: "DL-00001", MyLat: "15.1234567", MyLon: "-123.1234567"},
}
expectedOutputPOTAHunter := []string{
"ADIF Export for Fast Log Entry by DF3CB",
"<PROGRAMID:3>FLE",
"<ADIF_VER:5>3.1.0",
"<EOH>",
"<STATION_CALLSIGN:8>ON4KJM/P <CALL:5>S57LC <QSO_DATE:8>20200524 <TIME_ON:4>1310 <BAND:3>20m <MODE:2>CW <FREQ:6>14.045 <RST_SENT:3>599 <RST_RCVD:3>599 <GRIDSQUARE:4>JO50 <OPERATOR:6>ON4KJM <MY_GRIDSQUARE:6>JO40eu <APP_EQSL_QTH_NICKNAME:10>ON-00259-1 <EOR>",
"<STATION_CALLSIGN:8>ON4KJM/P <CALL:5>ON4LY <QSO_DATE:8>20200524 <TIME_ON:4>1312 <BAND:3>20m <MODE:2>CW <RST_SENT:3>559 <RST_RCVD:3>599 <SIG:4>POTA <SIG_INFO:8>DL-00001 <OPERATOR:6>ON4KJM <MY_GRIDSQUARE:6>JO40eu <EOR>",
"<STATION_CALLSIGN:8>ON4KJM/P <CALL:5>ON4LY <QSO_DATE:8>20200524 <TIME_ON:4>1312 <BAND:3>20m <MODE:2>CW <RST_SENT:3>559 <RST_RCVD:3>599 <SIG:4>POTA <SIG_INFO:8>DL-00001 <OPERATOR:6>ON4KJM <MY_GRIDSQUARE:6>JO40eu <MY_LAT:10>15.1234567 <MY_LON:12>-123.1234567 <EOR>",
}
type args struct { type args struct {
fullLog []LogLine fullLog []LogLine
adifParams AdifParams adifParams AdifParams
@ -172,6 +188,14 @@ func Test_buildAdif(t *testing.T) {
}, },
expectedOutputPOTA2, expectedOutputPOTA2,
}, },
{
"Happy case-POTA Hunter",
args{
fullLog: sampleFilledLogPOTAHunter,
adifParams: AdifParams{IsPOTA: false},
},
expectedOutputPOTAHunter,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

@ -59,5 +59,5 @@ func getBraketedData(inputLine string, braketType BraketType) (braketedData, cle
braketedData = inputLine[posFirstAdjusted:posLast] braketedData = inputLine[posFirstAdjusted:posLast]
cleanedLine = strings.Replace(inputLine, a+braketedData+b, "", 1) cleanedLine = strings.Replace(inputLine, a+braketedData+b, "", 1)
return braketedData, cleanedLine return strings.TrimSpace(braketedData), cleanedLine
} }

@ -17,6 +17,12 @@
output=$(test/docker-FLEcli.sh load -i test/data/ON4KJM@ONFF-025920200524.txt) output=$(test/docker-FLEcli.sh load -i test/data/ON4KJM@ONFF-025920200524.txt)
} }
@test "Is the generated ADIF from a POTA hunter equivalent to the canonical one?" {
mkdir -p test/output/temp
output=$(test/docker-FLEcli.sh adif -o -i test/data/sample_pota_hunter.txt test/output/temp/sample_pota_hunter.adif)
diff test/output/temp/sample_pota_hunter.adif test/output/POTA/sample_pota_hunter.adif --strip-trailing-cr
}
@test "Is the generated SOTA csv equivalent to the canonical one?" { @test "Is the generated SOTA csv equivalent to the canonical one?" {
mkdir -p test/output/temp mkdir -p test/output/temp
output=$(test/docker-FLEcli.sh csv -o -i test/FLE-sample/sota_wwff.txt test/output/temp/sota_wwff.csv) output=$(test/docker-FLEcli.sh csv -o -i test/FLE-sample/sota_wwff.txt test/output/temp/sota_wwff.csv)
@ -41,4 +47,4 @@
@test "Processing a big FLE file" { @test "Processing a big FLE file" {
run test/docker-FLEcli.sh csv -o -i test/data/fle-6-bigFile.txt test/output/temp/fle-6-bigFile.csv run test/docker-FLEcli.sh csv -o -i test/data/fle-6-bigFile.txt test/output/temp/fle-6-bigFile.csv
} }

@ -0,0 +1,51 @@
# Header
mycall kc3yqi
mygrid FM19je
2024-05-10
20m SSB
0000 14.26 cu2yk 59 57 #HM77DT
2137 14.273 kc0qna pota us-2481 55 55 #EN24pk
20m
2024-06-05 14.317 SSB 0220 kp4pr @Jose #FK68xk
2024-06-05 14.270 SSB 0234 lz2vu @Juli #KN33gs
SSB
# 20m General is >= 14.225 <= 14.347
2024-06-07
0448 14.250 dl5pia 57 59 @Petra < Mother of Pia > #JN48kn
0448 14.250 dl7pia 57 59 @Pia < Daughter of Petra > #JN48kn
40m SSB
7.266 SSB
2024-06-12 0045 kd4ge 57 57 @Darryl #EM93dk
7.216 SSB
2024-06-12 0129 ko4nll 55 55
20m SSB
2024-06-13 0301 14.225 r5aj 59 59 @Valery < Moscow, will upload to youtube > #KO95iu
2024-06-13 0225 14.280 lz2vu 59 59 < Bulgaria 1kW > @Juli #KN22dq
40m SSB
2024-06-15 2257 7.225 k4oki 55 55 @Ryan US-6907
20m SSB
14.225
2024-06-18 2348 14.308 KI5YOO 57 57 US-0307 < D'Arbonne National Wildlife Refuge > #EM32vp @Mark
2024-06-18 2350 14.333 WI0O 57 57 US-11701 < Wood-Rill SNA State Sanctuary > #EN34fx @Sean
2024-06-18 2350 14.333 WI0O 57 57 US-9387 < Luce Line State Trail > #EN34gx @Sean
2024-06-19 0003 14.336 N4SAX 59 59 US-1873 < Fred Gannon Rocky Bayou State Park > #EM60sl @Randall #EM60sl
40m SSB
2024-06-19 0008 7.248 KD2ZWM 56 55 US-0064 < Shenandoah National Park > #FM08vv @Brady
2024-06-19 0012 7.267 KO4ZRX 55 57 US-1790 @Ronny < Trail of Tears State Park > #EM57gk
2024-06-19 0012 7.267 KO4ZRX 55 57 US-3791 @Ronny < Trail of Tears Trail > #EM57gk

@ -1,4 +1,4 @@
#!/bin/bash #!/usr/bin/env bash
CURRENT_UID=$(id -u):$(id -g) CURRENT_UID=$(id -u):$(id -g)
docker run --rm -t --user ${CURRENT_UID} -v "$(pwd)":/FLEcli_data on4kjm/flecli:latest "$@" docker run --rm -t --user ${CURRENT_UID} -v "$(pwd)":/FLEcli_data on4kjm/flecli:latest "$@"

@ -0,0 +1,22 @@
ADIF Export for Fast Log Entry by DF3CB
<PROGRAMID:3>FLE
<ADIF_VER:5>3.1.0
<EOH>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>CU2YK <QSO_DATE:8>20240510 <TIME_ON:4>0000 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.260 <RST_SENT:2>59 <RST_RCVD:2>57 <GRIDSQUARE:6>HM77dt <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>KC0QNA <QSO_DATE:8>20240510 <TIME_ON:4>2137 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.273 <RST_SENT:2>55 <RST_RCVD:2>55 <GRIDSQUARE:6>EN24pk <SIG:4>POTA <SIG_INFO:7>US-2481 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>KP4PR <QSO_DATE:8>20240605 <TIME_ON:4>0220 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.317 <RST_SENT:2>59 <RST_RCVD:2>59 <GRIDSQUARE:6>FK68xk <NAME:4>Jose <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>LZ2VU <QSO_DATE:8>20240605 <TIME_ON:4>0234 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.270 <RST_SENT:2>59 <RST_RCVD:2>59 <GRIDSQUARE:6>KN33gs <NAME:4>Juli <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>DL5PIA <QSO_DATE:8>20240607 <TIME_ON:4>0448 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.250 <RST_SENT:2>57 <RST_RCVD:2>59 <GRIDSQUARE:6>JN48kn <COMMENT:13>Mother of Pia <NAME:5>Petra <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>DL7PIA <QSO_DATE:8>20240607 <TIME_ON:4>0448 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.250 <RST_SENT:2>57 <RST_RCVD:2>59 <GRIDSQUARE:6>JN48kn <COMMENT:17>Daughter of Petra <NAME:3>Pia <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>KD4GE <QSO_DATE:8>20240612 <TIME_ON:4>0045 <BAND:3>40m <MODE:3>SSB <FREQ:5>7.266 <RST_SENT:2>57 <RST_RCVD:2>57 <GRIDSQUARE:6>EM93dk <NAME:6>Darryl <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>KO4NLL <QSO_DATE:8>20240612 <TIME_ON:4>0129 <BAND:3>40m <MODE:3>SSB <FREQ:5>7.216 <RST_SENT:2>55 <RST_RCVD:2>55 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:4>R5AJ <QSO_DATE:8>20240613 <TIME_ON:4>0301 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.225 <RST_SENT:2>59 <RST_RCVD:2>59 <GRIDSQUARE:6>KO95iu <COMMENT:30>Moscow, will upload to youtube <NAME:6>Valery <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>LZ2VU <QSO_DATE:8>20240613 <TIME_ON:4>0225 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.280 <RST_SENT:2>59 <RST_RCVD:2>59 <GRIDSQUARE:6>KN22dq <COMMENT:12>Bulgaria 1kW <NAME:4>Juli <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>K4OKI <QSO_DATE:8>20240615 <TIME_ON:4>2257 <BAND:3>40m <MODE:3>SSB <FREQ:5>7.225 <RST_SENT:2>55 <RST_RCVD:2>55 <NAME:4>Ryan <SIG:4>POTA <SIG_INFO:7>US-6907 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>KI5YOO <QSO_DATE:8>20240618 <TIME_ON:4>2348 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.308 <RST_SENT:2>57 <RST_RCVD:2>57 <GRIDSQUARE:6>EM32vp <COMMENT:34>D'Arbonne National Wildlife Refuge <NAME:4>Mark <SIG:4>POTA <SIG_INFO:7>US-0307 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:4>WI0O <QSO_DATE:8>20240618 <TIME_ON:4>2350 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.333 <RST_SENT:2>57 <RST_RCVD:2>57 <GRIDSQUARE:6>EN34fx <COMMENT:29>Wood-Rill SNA State Sanctuary <NAME:4>Sean <SIG:4>POTA <SIG_INFO:8>US-11701 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:4>WI0O <QSO_DATE:8>20240618 <TIME_ON:4>2350 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.333 <RST_SENT:2>57 <RST_RCVD:2>57 <GRIDSQUARE:6>EN34gx <COMMENT:21>Luce Line State Trail <NAME:4>Sean <SIG:4>POTA <SIG_INFO:7>US-9387 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:5>N4SAX <QSO_DATE:8>20240619 <TIME_ON:4>0003 <BAND:3>20m <MODE:3>SSB <FREQ:6>14.336 <RST_SENT:2>59 <RST_RCVD:2>59 <GRIDSQUARE:6>EM60sl <COMMENT:34>Fred Gannon Rocky Bayou State Park <NAME:7>Randall <SIG:4>POTA <SIG_INFO:7>US-1873 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>KD2ZWM <QSO_DATE:8>20240619 <TIME_ON:4>0008 <BAND:3>40m <MODE:3>SSB <FREQ:5>7.248 <RST_SENT:2>56 <RST_RCVD:2>55 <GRIDSQUARE:6>FM08vv <COMMENT:24>Shenandoah National Park <NAME:5>Brady <SIG:4>POTA <SIG_INFO:7>US-0064 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>KO4ZRX <QSO_DATE:8>20240619 <TIME_ON:4>0012 <BAND:3>40m <MODE:3>SSB <FREQ:5>7.267 <RST_SENT:2>55 <RST_RCVD:2>57 <GRIDSQUARE:6>EM57gk <COMMENT:25>Trail of Tears State Park <NAME:5>Ronny <SIG:4>POTA <SIG_INFO:7>US-1790 <MY_GRIDSQUARE:6>FM19je <EOR>
<STATION_CALLSIGN:6>KC3YQI <CALL:6>KO4ZRX <QSO_DATE:8>20240619 <TIME_ON:4>0012 <BAND:3>40m <MODE:3>SSB <FREQ:5>7.267 <RST_SENT:2>55 <RST_RCVD:2>57 <GRIDSQUARE:6>EM57gk <COMMENT:20>Trail of Tears Trail <NAME:5>Ronny <SIG:4>POTA <SIG_INFO:7>US-3791 <MY_GRIDSQUARE:6>FM19je <EOR>
Loading…
Cancel
Save