feat: status bar added
This commit is contained in:
+46
-4
@@ -78,6 +78,8 @@ type QSO struct {
|
||||
HRDLogUploadStatus string `json:"hrdlog_qso_upload_status,omitempty"`
|
||||
QRZComUploadDate string `json:"qrzcom_qso_upload_date,omitempty"`
|
||||
QRZComUploadStatus string `json:"qrzcom_qso_upload_status,omitempty"`
|
||||
QRZComDownloadDate string `json:"qrzcom_qso_download_date,omitempty"`
|
||||
QRZComDownloadStatus string `json:"qrzcom_qso_download_status,omitempty"`
|
||||
|
||||
// --- Contest ---
|
||||
ContestID string `json:"contest_id,omitempty"`
|
||||
@@ -167,6 +169,7 @@ const columnList = `callsign, qso_date, qso_date_off, band, band_rx, mode, submo
|
||||
clublog_qso_upload_date, clublog_qso_upload_status,
|
||||
hrdlog_qso_upload_date, hrdlog_qso_upload_status,
|
||||
qrzcom_qso_upload_date, qrzcom_qso_upload_status,
|
||||
qrzcom_qso_download_date, qrzcom_qso_download_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,
|
||||
@@ -219,6 +222,7 @@ func (q *QSO) args() []any {
|
||||
q.ClublogUploadDate, q.ClublogUploadStatus,
|
||||
q.HRDLogUploadDate, q.HRDLogUploadStatus,
|
||||
q.QRZComUploadDate, q.QRZComUploadStatus,
|
||||
q.QRZComDownloadDate, q.QRZComDownloadStatus,
|
||||
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,
|
||||
@@ -1099,14 +1103,35 @@ func SlotKey(dxcc int, band, mode string) string {
|
||||
return fmt.Sprintf("%d|%s|%s", dxcc, strings.ToLower(band), strings.ToUpper(mode))
|
||||
}
|
||||
|
||||
// ConfirmedSlots returns the set of confirmed DXCC/band/slot combos. A QSO
|
||||
// counts as confirmed when any received flag (LoTW, paper, eQSL) is "Y".
|
||||
func (r *Repo) ConfirmedSlots(ctx context.Context) (ConfirmedSets, error) {
|
||||
// confirmedCols whitelists the received-status columns ConfirmedSlots may
|
||||
// OR together (guards the dynamic SQL).
|
||||
var confirmedCols = map[string]bool{
|
||||
"lotw_rcvd": true,
|
||||
"qsl_rcvd": true,
|
||||
"eqsl_rcvd": true,
|
||||
"qrzcom_qso_download_status": true,
|
||||
}
|
||||
|
||||
// ConfirmedSlots returns the set of confirmed DXCC/band/slot combos, counting
|
||||
// only the given received-status columns as "confirmed". This lets the caller
|
||||
// scope award-relevant confirmations per service — e.g. LoTW download uses
|
||||
// {lotw_rcvd, qsl_rcvd} (the award-valid sources), QRZ uses
|
||||
// {qrzcom_qso_download_status}.
|
||||
func (r *Repo) ConfirmedSlots(ctx context.Context, cols []string) (ConfirmedSets, error) {
|
||||
sets := ConfirmedSets{DXCC: map[int]bool{}, Band: map[string]bool{}, Slot: map[string]bool{}}
|
||||
var conds []string
|
||||
for _, c := range cols {
|
||||
if confirmedCols[c] {
|
||||
conds = append(conds, c+" = 'Y'")
|
||||
}
|
||||
}
|
||||
if len(conds) == 0 {
|
||||
return sets, nil
|
||||
}
|
||||
rows, err := r.db.QueryContext(ctx, `
|
||||
SELECT COALESCE(dxcc,0), LOWER(COALESCE(band,'')), UPPER(COALESCE(mode,''))
|
||||
FROM qso
|
||||
WHERE lotw_rcvd = 'Y' OR qsl_rcvd = 'Y' OR eqsl_rcvd = 'Y'`)
|
||||
WHERE `+strings.Join(conds, " OR "))
|
||||
if err != nil {
|
||||
return sets, err
|
||||
}
|
||||
@@ -1127,6 +1152,19 @@ func (r *Repo) ConfirmedSlots(ctx context.Context) (ConfirmedSets, error) {
|
||||
return sets, rows.Err()
|
||||
}
|
||||
|
||||
// MarkQRZConfirmed stamps QRZCOM_QSO_DOWNLOAD_STATUS=Y and the date on a QSO
|
||||
// confirmed via a QRZ.com download. date is an ADIF YYYYMMDD string.
|
||||
func (r *Repo) MarkQRZConfirmed(ctx context.Context, id int64, date string) error {
|
||||
_, err := r.db.ExecContext(ctx,
|
||||
`UPDATE qso SET qrzcom_qso_download_status = 'Y', qrzcom_qso_download_date = ?,
|
||||
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = ?`,
|
||||
date, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("mark qrz confirmed %d: %w", id, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkLoTWConfirmed stamps LOTW_QSL_RCVD=Y and the received date on a QSO
|
||||
// after a LoTW confirmation download. date is an ADIF YYYYMMDD string.
|
||||
func (r *Repo) MarkLoTWConfirmed(ctx context.Context, id int64, date string) error {
|
||||
@@ -1173,6 +1211,7 @@ func scanQSO(s scanner) (QSO, error) {
|
||||
clublogDate, clublogStatus sql.NullString
|
||||
hrdlogDate, hrdlogStatus sql.NullString
|
||||
qrzcomDate, qrzcomStatus sql.NullString
|
||||
qrzcomDlDate, qrzcomDlStatus sql.NullString
|
||||
contestID sql.NullString
|
||||
srx, stx sql.NullInt64
|
||||
srxStr, stxStr sql.NullString
|
||||
@@ -1205,6 +1244,7 @@ func scanQSO(s scanner) (QSO, error) {
|
||||
&clublogDate, &clublogStatus,
|
||||
&hrdlogDate, &hrdlogStatus,
|
||||
&qrzcomDate, &qrzcomStatus,
|
||||
&qrzcomDlDate, &qrzcomDlStatus,
|
||||
&contestID, &srx, &stx, &srxStr, &stxStr, &checkField, &precedence, &arrlSect,
|
||||
&propMode, &satName, &satMode, &antAz, &antEl, &antPath,
|
||||
&stCall, &op, &myGrid, &myGridExt, &myCountry, &myState, &myCnty, &myIOTA,
|
||||
@@ -1292,6 +1332,8 @@ func scanQSO(s scanner) (QSO, error) {
|
||||
q.HRDLogUploadStatus = hrdlogStatus.String
|
||||
q.QRZComUploadDate = qrzcomDate.String
|
||||
q.QRZComUploadStatus = qrzcomStatus.String
|
||||
q.QRZComDownloadDate = qrzcomDlDate.String
|
||||
q.QRZComDownloadStatus = qrzcomDlStatus.String
|
||||
q.ContestID = contestID.String
|
||||
if srx.Valid {
|
||||
v := int(srx.Int64)
|
||||
|
||||
Reference in New Issue
Block a user