feat(hamlog): the settings panel, the key check, and a row-colour channel
HAMLOG.online is now reachable: Settings → External services → HAMLOG.ONLINE takes the API key, the auto-upload switch and the timing, exactly like the six services beside it, and a link opens the page where the key is issued. The button next to it checks the KEY, not the connection. HAMLOG answers KEYSTATUS with the callsign the key belongs to — something no other service here offers — so the result reads "Key is valid — account F4BPO" rather than a green tick. A key pasted from a club account or a second station is visible at once, which is precisely the mistake a tick would have hidden. No on-close timing, for the same reason as Cloudlog: there is no per-QSO upload column to select a backlog from at shutdown, so the option would have done nothing. Immediate or delayed, and a stored on_close falls back to immediate rather than silently uploading nothing. The appearance rules gain a HAMLOG.online channel too, so a row can be coloured "confirmed" on that alone. It reads the ADIF extras — the standard names a field for hamlog.EU and none for hamlog.ONLINE — using the same keys the award engine reads, so the two can never disagree about what a confirmation is. "To send" skips it: a QSO is either uploaded or not, there is no card to be owed.
This commit is contained in:
@@ -382,6 +382,10 @@ const (
|
||||
keyExtCloudlogAutoUpload = "extsvc.cloudlog.auto_upload"
|
||||
keyExtCloudlogUploadMode = "extsvc.cloudlog.upload_mode"
|
||||
|
||||
keyExtHamlogAPIKey = "extsvc.hamlog.api_key"
|
||||
keyExtHamlogAutoUpload = "extsvc.hamlog.auto_upload"
|
||||
keyExtHamlogUploadMode = "extsvc.hamlog.upload_mode"
|
||||
|
||||
keyExtPotaToken = "extsvc.pota.token" // pota.app session token for hunter-log sync
|
||||
|
||||
keyExtLoTWTQSLPath = "extsvc.lotw.tqsl_path"
|
||||
@@ -10701,7 +10705,8 @@ func (a *App) loadExternalServices() extsvc.ExternalServices {
|
||||
keyExtHRDLogCallsign, keyExtHRDLogCode, keyExtHRDLogAutoUpload, keyExtHRDLogUploadMode, keyExtHRDLogOnAir,
|
||||
keyExtEQSLUsername, keyExtEQSLPassword, keyExtEQSLQTHNick, keyExtEQSLAutoUpload, keyExtEQSLUploadMode,
|
||||
keyExtCloudlogURL, keyExtCloudlogAPIKey, keyExtCloudlogStationID,
|
||||
keyExtCloudlogAutoUpload, keyExtCloudlogUploadMode, keyExtDeleteRemote)
|
||||
keyExtCloudlogAutoUpload, keyExtCloudlogUploadMode, keyExtDeleteRemote,
|
||||
keyExtHamlogAPIKey, keyExtHamlogAutoUpload, keyExtHamlogUploadMode)
|
||||
if err != nil {
|
||||
return out
|
||||
}
|
||||
@@ -10780,6 +10785,11 @@ func (a *App) loadExternalServices() extsvc.ExternalServices {
|
||||
AutoUpload: m[keyExtCloudlogAutoUpload] == "1",
|
||||
UploadMode: extsvc.UploadMode(m[keyExtCloudlogUploadMode]),
|
||||
}
|
||||
out.Hamlog = extsvc.ServiceConfig{
|
||||
APIKey: m[keyExtHamlogAPIKey],
|
||||
AutoUpload: m[keyExtHamlogAutoUpload] == "1",
|
||||
UploadMode: extsvc.UploadMode(m[keyExtHamlogUploadMode]),
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -10848,6 +10858,16 @@ func (a *App) SaveExternalServices(cfg extsvc.ExternalServices) error {
|
||||
if cfg.Cloudlog.AutoUpload {
|
||||
clgAuto = "1"
|
||||
}
|
||||
// Same reasoning as Cloudlog: HAMLOG has no per-QSO upload-status column to
|
||||
// select on, so an on-close sweep would have nothing to sweep.
|
||||
hamMode := modeOf(cfg.Hamlog.UploadMode)
|
||||
if hamMode == string(extsvc.ModeOnClose) {
|
||||
hamMode = string(extsvc.ModeImmediate)
|
||||
}
|
||||
hamAuto := "0"
|
||||
if cfg.Hamlog.AutoUpload {
|
||||
hamAuto = "1"
|
||||
}
|
||||
delRemote := "0"
|
||||
if cfg.DeleteRemote {
|
||||
delRemote = "1"
|
||||
@@ -10895,6 +10915,10 @@ func (a *App) SaveExternalServices(cfg extsvc.ExternalServices) error {
|
||||
keyExtCloudlogStationID: strings.TrimSpace(cfg.Cloudlog.StationID),
|
||||
keyExtCloudlogAutoUpload: clgAuto,
|
||||
keyExtCloudlogUploadMode: clgMode,
|
||||
|
||||
keyExtHamlogAPIKey: strings.TrimSpace(cfg.Hamlog.APIKey),
|
||||
keyExtHamlogAutoUpload: hamAuto,
|
||||
keyExtHamlogUploadMode: hamMode,
|
||||
} {
|
||||
if err := a.settings.Set(a.ctx, scope+k, v); err != nil {
|
||||
return err
|
||||
@@ -20350,3 +20374,16 @@ func (a *App) countryFor(call string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// CheckHamlogKey validates a HAMLOG.online API key and returns the callsign it
|
||||
// belongs to.
|
||||
//
|
||||
// Its own binding rather than part of a save: the answer names the ACCOUNT, so
|
||||
// an operator who pasted a club's key, or one that expired last month, learns it
|
||||
// while looking at the field they just filled in — not from QSOs that quietly
|
||||
// never arrive.
|
||||
func (a *App) CheckHamlogKey(key string) (string, error) {
|
||||
ctx, cancel := context.WithTimeout(a.ctx, 20*time.Second)
|
||||
defer cancel()
|
||||
return extsvc.CheckHamlogKey(ctx, nil, key)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user