feat: upload to external services clublog qrz

This commit is contained in:
2026-05-28 22:52:50 +02:00
parent e82e30dd02
commit 5c004f5e2f
26 changed files with 1710 additions and 31 deletions
+36
View File
@@ -76,6 +76,8 @@ type QSO struct {
ClublogUploadStatus string `json:"clublog_qso_upload_status,omitempty"`
HRDLogUploadDate string `json:"hrdlog_qso_upload_date,omitempty"`
HRDLogUploadStatus string `json:"hrdlog_qso_upload_status,omitempty"`
QRZComUploadDate string `json:"qrzcom_qso_upload_date,omitempty"`
QRZComUploadStatus string `json:"qrzcom_qso_upload_status,omitempty"`
// --- Contest ---
ContestID string `json:"contest_id,omitempty"`
@@ -164,6 +166,7 @@ const columnList = `callsign, qso_date, qso_date_off, band, band_rx, mode, submo
eqsl_sent, eqsl_rcvd, eqsl_sent_date, eqsl_rcvd_date,
clublog_qso_upload_date, clublog_qso_upload_status,
hrdlog_qso_upload_date, hrdlog_qso_upload_status,
qrzcom_qso_upload_date, qrzcom_qso_upload_status,
contest_id, srx, stx, srx_string, stx_string, check_field, precedence, arrl_sect,
prop_mode, sat_name, sat_mode, ant_az, ant_el, ant_path,
station_callsign, operator, my_grid, my_gridsquare_ext, my_country, my_state, my_cnty, my_iota,
@@ -215,6 +218,7 @@ func (q *QSO) args() []any {
q.EQSLSent, q.EQSLRcvd, q.EQSLSentDate, q.EQSLRcvdDate,
q.ClublogUploadDate, q.ClublogUploadStatus,
q.HRDLogUploadDate, q.HRDLogUploadStatus,
q.QRZComUploadDate, q.QRZComUploadStatus,
q.ContestID, q.SRX, q.STX, q.SRXString, q.STXString, q.Check, q.Precedence, q.ARRLSect,
q.PropMode, q.SatName, q.SatMode, q.AntAz, q.AntEl, q.AntPath,
q.StationCallsign, q.Operator, q.MyGrid, q.MyGridExt, q.MyCountry, q.MyState, q.MyCounty, q.MyIOTA,
@@ -319,6 +323,34 @@ func (r *Repo) GetByID(ctx context.Context, id int64) (QSO, error) {
return scanQSO(row)
}
// 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
// rewrite — so it's safe to call from the async upload path.
func (r *Repo) MarkQRZUploaded(ctx context.Context, id int64, date string) error {
_, err := r.db.ExecContext(ctx,
`UPDATE qso SET qrzcom_qso_upload_status = 'Y', qrzcom_qso_upload_date = ?,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ?`,
date, id)
if err != nil {
return fmt.Errorf("mark qrz uploaded %d: %w", id, err)
}
return nil
}
// MarkClublogUploaded stamps CLUBLOG_QSO_UPLOAD_STATUS=Y and the upload
// date after a successful Club Log push. date is an ADIF YYYYMMDD string.
func (r *Repo) MarkClublogUploaded(ctx context.Context, id int64, date string) error {
_, err := r.db.ExecContext(ctx,
`UPDATE qso SET clublog_qso_upload_status = 'Y', clublog_qso_upload_date = ?,
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ?`,
date, id)
if err != nil {
return fmt.Errorf("mark clublog 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 {
@@ -1004,6 +1036,7 @@ func scanQSO(s scanner) (QSO, error) {
eqslSentDate, eqslRcvdDate sql.NullString
clublogDate, clublogStatus sql.NullString
hrdlogDate, hrdlogStatus sql.NullString
qrzcomDate, qrzcomStatus sql.NullString
contestID sql.NullString
srx, stx sql.NullInt64
srxStr, stxStr sql.NullString
@@ -1035,6 +1068,7 @@ func scanQSO(s scanner) (QSO, error) {
&eqslSent, &eqslRcvd, &eqslSentDate, &eqslRcvdDate,
&clublogDate, &clublogStatus,
&hrdlogDate, &hrdlogStatus,
&qrzcomDate, &qrzcomStatus,
&contestID, &srx, &stx, &srxStr, &stxStr, &checkField, &precedence, &arrlSect,
&propMode, &satName, &satMode, &antAz, &antEl, &antPath,
&stCall, &op, &myGrid, &myGridExt, &myCountry, &myState, &myCnty, &myIOTA,
@@ -1120,6 +1154,8 @@ func scanQSO(s scanner) (QSO, error) {
q.ClublogUploadStatus = clublogStatus.String
q.HRDLogUploadDate = hrdlogDate.String
q.HRDLogUploadStatus = hrdlogStatus.String
q.QRZComUploadDate = qrzcomDate.String
q.QRZComUploadStatus = qrzcomStatus.String
q.ContestID = contestID.String
if srx.Valid {
v := int(srx.Int64)