feat: upload qrz.com clublog and lotw manually

This commit is contained in:
2026-05-29 00:16:59 +02:00
parent edda183c16
commit 33a7b6c4ac
12 changed files with 1113 additions and 41 deletions
+58
View File
@@ -323,6 +323,51 @@ func (r *Repo) GetByID(ctx context.Context, id int64) (QSO, error) {
return scanQSO(row)
}
// UploadRow is a lightweight QSO projection for the QSL Manager grid.
type UploadRow struct {
ID int64 `json:"id"`
QSODate string `json:"qso_date"` // ISO UTC; the UI formats it
Callsign string `json:"callsign"`
Band string `json:"band"`
Mode string `json:"mode"`
Country string `json:"country"`
Status string `json:"status"` // the matched per-service sent status
}
// uploadStatusCols whitelists the per-service sent-status columns the QSL
// Manager may filter on (guards the dynamic column name in the query).
var uploadStatusCols = map[string]bool{
"lotw_sent": true,
"qrzcom_qso_upload_status": true,
"clublog_qso_upload_status": true,
}
// ListForUpload returns QSOs whose per-service sent-status column equals
// value ("" matches blank/NULL). Used by the QSL Manager's "Select required".
func (r *Repo) ListForUpload(ctx context.Context, column, value string) ([]UploadRow, error) {
if !uploadStatusCols[column] {
return nil, fmt.Errorf("invalid upload column %q", column)
}
rows, err := r.db.QueryContext(ctx,
`SELECT id, qso_date, callsign, COALESCE(band,''), COALESCE(mode,''),
COALESCE(country,''), COALESCE(`+column+`,'')
FROM qso WHERE COALESCE(`+column+`,'') = ?
ORDER BY qso_date DESC`, value)
if err != nil {
return nil, fmt.Errorf("list for upload: %w", err)
}
defer rows.Close()
var out []UploadRow
for rows.Next() {
var u UploadRow
if err := rows.Scan(&u.ID, &u.QSODate, &u.Callsign, &u.Band, &u.Mode, &u.Country, &u.Status); err != nil {
return nil, err
}
out = append(out, u)
}
return out, rows.Err()
}
// MarkQRZUploaded stamps QRZCOM_QSO_UPLOAD_STATUS=Y and the upload date on
// a QSO after a successful push to the QRZ.com logbook. date is an ADIF
// YYYYMMDD string. Only the two QRZ columns are touched — no full-row
@@ -351,6 +396,19 @@ func (r *Repo) MarkClublogUploaded(ctx context.Context, id int64, date string) e
return nil
}
// MarkLoTWUploaded stamps LOTW_QSL_SENT=Y and the sent date after a
// successful TQSL upload. date is an ADIF YYYYMMDD string.
func (r *Repo) MarkLoTWUploaded(ctx context.Context, id int64, date string) error {
_, err := r.db.ExecContext(ctx,
`UPDATE qso SET lotw_sent = 'Y', lotw_sent_date = ?,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ?`,
date, id)
if err != nil {
return fmt.Errorf("mark lotw uploaded %d: %w", id, err)
}
return nil
}
// Update overwrites all editable fields of an existing QSO. updated_at is bumped.
func (r *Repo) Update(ctx context.Context, q QSO) error {
if q.ID == 0 {