diff --git a/app.go b/app.go index 8e27bd6..5823264 100644 --- a/app.go +++ b/app.go @@ -9575,11 +9575,14 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe // QSO date. sinceDate is "YYYY-MM-DD". sinceDate := resolveSince(keyExtQRZLastDownload) emit(fmt.Sprintf("Window: since=%q → resolved date=%q (key %s%s)", since, sinceDate, a.profileScope(), keyExtQRZLastDownload)) - if sinceDate != "" { - emit("Fetching QRZ.com logbook (records modified since " + sinceDate + ")…") - } else { - emit("Fetching QRZ.com logbook (full — no since date)…") - } + // An automatic run ("last") and an operator-chosen date do not mean the + // same thing, so they ask QRZ two different questions: + // • "last" → MODSINCE: everything TOUCHED since the last run, + // which is what catches a 2015 QSO confirmed yesterday. + // • a typed date → BETWEEN: the QSOs MADE from that date to today. The + // operator asked for a period of operating, not for + // whatever QRZ happened to edit in that period. + autoWindow := strings.EqualFold(strings.TrimSpace(since), "last") // Ask QRZ for the WINDOW rather than the whole logbook. "ALL" made the // server serialise every QSO — 56 MB for a 117k-record log — which it // truncates mid-record, so the parse died two thirds of the way through @@ -9595,13 +9598,26 @@ func (a *App) runDownloadConfirmations(svc extsvc.Service, cfg extsvc.ExternalSe // // It stays an optimisation, never a requirement: if QRZ refuses it, fall // back to ALL rather than leaving the operator with no download at all. + // + // serverWindowed is set only for MODSINCE, because it alone returns QSOs + // OLDER than the date — the client-side date filter would drop exactly + // those. Under BETWEEN the filter agrees with the server and stays on as a + // backstop. fetchOpt, serverWindowed := "ALL", false - if sinceDate != "" { + switch { + case sinceDate == "": + emit("Fetching QRZ.com logbook (full — no since date)…") + case autoWindow: fetchOpt, serverWindowed = "MODSINCE:"+sinceDate, true + emit("Fetching QRZ.com logbook (records modified since " + sinceDate + ")…") + default: + today := time.Now().UTC().Format("2006-01-02") + fetchOpt = "BETWEEN:" + sinceDate + "+" + today + emit("Fetching QRZ.com logbook (QSOs from " + sinceDate + " to " + today + ")…") } fr, err := extsvc.FetchQRZ(ctx, nil, cfg.QRZ.APIKey, fetchOpt) - if err != nil && serverWindowed { - emit("QRZ.com refused MODSINCE (" + err.Error() + ") — fetching the full logbook instead…") + if err != nil && fetchOpt != "ALL" { + emit("QRZ.com refused " + fetchOpt + " (" + err.Error() + ") — fetching the full logbook instead…") fetchOpt, serverWindowed = "ALL", false fr, err = extsvc.FetchQRZ(ctx, nil, cfg.QRZ.APIKey, fetchOpt) }