fix: Added LOTW badge for Lotw users colored depending on their last upload
This commit is contained in:
@@ -41,6 +41,7 @@ import (
|
||||
"hamlog/internal/netctl"
|
||||
"hamlog/internal/operating"
|
||||
"hamlog/internal/pota"
|
||||
"hamlog/internal/lotwusers"
|
||||
"hamlog/internal/powergenius"
|
||||
"hamlog/internal/profile"
|
||||
"hamlog/internal/qslcard"
|
||||
@@ -422,6 +423,7 @@ type App struct {
|
||||
audioMgr *audio.Manager
|
||||
qsoRec *audio.Recorder // continuous QSO recorder (rolling pre-roll)
|
||||
solar *solar.Manager // live space-weather (SFI/SSN/A/K) for the header + QSO stamping
|
||||
lotwUsers *lotwusers.Manager // LoTW user-activity list (badge next to the callsign)
|
||||
|
||||
// NET Control: persistent net definitions/rosters (global JSON) + the live
|
||||
// session (in-memory only — active stations currently in QSO).
|
||||
@@ -768,6 +770,24 @@ func (a *App) startup(ctx context.Context) {
|
||||
// cty.dat lacks (DXpeditions). Loaded from cache if present; downloaded on
|
||||
// demand. Resolution applied only when the user enables it.
|
||||
a.clublog = clublog.NewManager(clublogAppAPIKey, dataDir)
|
||||
|
||||
// LoTW user-activity list (who's a LoTW user + last upload). Loads the cached
|
||||
// CSV if present, and auto-downloads in the background when it's missing or
|
||||
// older than a week (the ARRL list changes daily). Manual refresh is in
|
||||
// Settings → LoTW.
|
||||
a.lotwUsers = lotwusers.NewManager(dataDir)
|
||||
go func() {
|
||||
if a.lotwUsers.Count() == 0 || time.Since(a.lotwUsers.Updated()) > 7*24*time.Hour {
|
||||
if n, err := a.lotwUsers.Download(context.Background()); err == nil {
|
||||
applog.Printf("lotwusers: auto-downloaded %d LoTW users", n)
|
||||
if a.ctx != nil {
|
||||
wruntime.EventsEmit(a.ctx, "lotwusers:updated")
|
||||
}
|
||||
} else {
|
||||
applog.Printf("lotwusers: auto-download failed: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
if err := a.clublog.EnsureLoaded(); err == nil {
|
||||
d, n := a.clublog.Info()
|
||||
@@ -1734,6 +1754,42 @@ func (a *App) RefreshSolar() {
|
||||
}
|
||||
}
|
||||
|
||||
// LoTWUserInfo reports whether a callsign is a LoTW user and how recently it
|
||||
// uploaded — drives the colour-coded LoTW badge in the entry strip.
|
||||
func (a *App) LoTWUserInfo(callsign string) lotwusers.Info {
|
||||
if a.lotwUsers == nil {
|
||||
return lotwusers.Info{DaysAgo: -1}
|
||||
}
|
||||
return a.lotwUsers.Lookup(callsign)
|
||||
}
|
||||
|
||||
// LoTWUsersStatus is the loaded-list summary for Settings (count + last refresh).
|
||||
type LoTWUsersStatus struct {
|
||||
Count int `json:"count"`
|
||||
Updated string `json:"updated,omitempty"` // RFC3339, empty if never
|
||||
}
|
||||
|
||||
// GetLoTWUsersStatus returns how many LoTW callsigns are loaded and when.
|
||||
func (a *App) GetLoTWUsersStatus() LoTWUsersStatus {
|
||||
if a.lotwUsers == nil {
|
||||
return LoTWUsersStatus{}
|
||||
}
|
||||
st := LoTWUsersStatus{Count: a.lotwUsers.Count()}
|
||||
if u := a.lotwUsers.Updated(); !u.IsZero() {
|
||||
st.Updated = u.UTC().Format(time.RFC3339)
|
||||
}
|
||||
return st
|
||||
}
|
||||
|
||||
// DownloadLoTWUsers fetches ARRL's LoTW user-activity list and caches it.
|
||||
// Returns the number of callsigns loaded.
|
||||
func (a *App) DownloadLoTWUsers() (int, error) {
|
||||
if a.lotwUsers == nil {
|
||||
return 0, fmt.Errorf("not initialized")
|
||||
}
|
||||
return a.lotwUsers.Download(a.ctx)
|
||||
}
|
||||
|
||||
// StationInfoComputed bundles the data we resolve live from the
|
||||
// profile's callsign + grid: country, ARRL DXCC#, CQ zone, ITU zone,
|
||||
// lat/lon. Used by the Settings UI to show the "what will be stamped on
|
||||
@@ -5572,7 +5628,20 @@ func (a *App) applyClublogException(q *qso.QSO, force bool) bool {
|
||||
}
|
||||
e, ok := a.clublog.Resolve(q.Callsign, date)
|
||||
if !ok {
|
||||
return false
|
||||
// No exception COVERS this QSO's date. If the call nonetheless HAS a
|
||||
// date-ranged exception (e.g. G1T = Scotland only from 2024-02-21), then
|
||||
// cty.dat's date-blind "=G1T → Scotland" override is WRONG for an older
|
||||
// QSO — resolve it by ClubLog's date-aware PREFIX table instead (G1 →
|
||||
// England for a 2012 contact). Ordinary calls (no exception) are left to
|
||||
// cty.dat.
|
||||
if a.clublog.HasException(q.Callsign) {
|
||||
if pe, pok := a.clublog.ResolvePrefix(q.Callsign, date); pok {
|
||||
e, ok = pe, true
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
q.Country = titleEntity(e.Entity)
|
||||
if e.Cont != "" {
|
||||
|
||||
Reference in New Issue
Block a user