fix: Added LOTW badge for Lotw users colored depending on their last upload

This commit is contained in:
2026-07-09 19:32:32 +02:00
parent f3bf0b2f5c
commit 16e780c2df
13 changed files with 465 additions and 6 deletions
+17
View File
@@ -202,6 +202,23 @@ func (db *DB) Resolve(call string, date time.Time) (Exception, bool) {
return Exception{}, false
}
// HasException reports whether the callsign has ANY full-call exception (at any
// date). Used to tell a genuinely date-sensitive call (G1T: Scotland only from
// 2024) — where cty.dat's date-blind exact-call override is wrong for older
// QSOs — from an ordinary call cty.dat handles fine.
func (db *DB) HasException(call string) bool {
if db == nil {
return false
}
c := strings.ToUpper(strings.TrimSpace(call))
for _, key := range candidates(c) {
if len(db.exceptions[key]) > 0 {
return true
}
}
return false
}
// candidates yields the call and a version with one trailing affix removed.
func candidates(c string) []string {
out := []string{c}
+50
View File
@@ -0,0 +1,50 @@
package clublog
import (
"testing"
"time"
)
func d(s string) time.Time {
t, _ := time.Parse("2006-01-02", s)
return t
}
// G1T is a contest call: Scotland ONLY from 2024-02-21; before that it's England
// by prefix. cty.dat's date-blind "=G1T → Scotland" override is wrong for a 2012
// QSO — the date-aware ClubLog cascade must give England then, Scotland now.
func TestG1TDatedException(t *testing.T) {
db := &DB{
exceptions: map[string][]Exception{
"G1T": {{Call: "G1T", Entity: "Scotland", ADIF: 279, Start: d("2024-02-21")}},
},
prefixes: map[string][]Exception{
"G": {{Entity: "England", ADIF: 223}},
},
}
// 2012 QSO: exception doesn't cover it, but the call HAS an exception →
// caller should use the prefix (England).
if _, ok := db.Resolve("G1T", d("2012-07-29")); ok {
t.Fatalf("2012: exception should NOT cover a pre-2024 date")
}
if !db.HasException("G1T") {
t.Fatalf("HasException(G1T) should be true")
}
pe, pok := db.ResolvePrefix("G1T", d("2012-07-29"))
if !pok || pe.Entity != "England" {
t.Fatalf("2012 prefix: got %q ok=%v, want England", pe.Entity, pok)
}
// 2025 QSO: the exception covers it → Scotland.
e, ok := db.Resolve("G1T", d("2025-01-01"))
if !ok || e.Entity != "Scotland" {
t.Fatalf("2025: got %q ok=%v, want Scotland", e.Entity, ok)
}
// An ordinary call with no exception → HasException false (caller leaves it
// to cty.dat).
if db.HasException("G4ABC") {
t.Fatalf("HasException(G4ABC) should be false")
}
}
+16
View File
@@ -125,3 +125,19 @@ func (m *Manager) Resolve(call string, date time.Time) (Exception, bool) {
}
return db.Resolve(call, date)
}
// ResolvePrefix resolves a call by ClubLog's date-ranged PREFIX table.
func (m *Manager) ResolvePrefix(call string, date time.Time) (Exception, bool) {
m.mu.RLock()
db := m.db
m.mu.RUnlock()
return db.ResolvePrefix(call, date)
}
// HasException reports whether the call has any full-call exception (any date).
func (m *Manager) HasException(call string) bool {
m.mu.RLock()
db := m.db
m.mu.RUnlock()
return db.HasException(call)
}