up
This commit is contained in:
+67
-1
@@ -414,7 +414,73 @@ func MatchQSO(d Def, metas []RefMeta, q *qso.QSO) []string {
|
||||
}
|
||||
}
|
||||
rl := NewRefList(metas)
|
||||
return candidates(&d, re, q, rl, len(metas) > 0)
|
||||
found := candidates(&d, re, q, rl, len(metas) > 0)
|
||||
// Merge operator-assigned references (manual override). These let the
|
||||
// operator tag a QSO for an award whose field/description matching can't
|
||||
// auto-detect the reference — e.g. WAPC scans the ADDRESS field for a
|
||||
// province NAME, so a contact whose address doesn't spell it out needs the
|
||||
// province picked by hand. For a predefined award the override is still
|
||||
// validated against its reference list.
|
||||
if man := manualRefs(q, d.Code); len(man) > 0 {
|
||||
found = mergeManual(found, man, rl, len(metas) > 0 && !d.Dynamic)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
// ManualRefsKey is the ADIF extras key under which OpsLog stores per-QSO,
|
||||
// operator-assigned award references as "CODE@REF;CODE@REF" (REF may be a
|
||||
// comma list). Honoured by MatchQSO regardless of how the award matches.
|
||||
const ManualRefsKey = "APP_OPSLOG_AWARDREFS"
|
||||
|
||||
// manualRefs returns the reference codes the operator assigned to award `code`
|
||||
// on this QSO (from the ManualRefsKey extra).
|
||||
func manualRefs(q *qso.QSO, code string) []string {
|
||||
if q == nil || q.Extras == nil {
|
||||
return nil
|
||||
}
|
||||
raw := strings.TrimSpace(q.Extras[ManualRefsKey])
|
||||
if raw == "" {
|
||||
return nil
|
||||
}
|
||||
code = strings.ToUpper(strings.TrimSpace(code))
|
||||
var out []string
|
||||
for _, entry := range strings.Split(raw, ";") {
|
||||
entry = strings.TrimSpace(entry)
|
||||
at := strings.IndexByte(entry, '@')
|
||||
if at <= 0 || !strings.EqualFold(strings.TrimSpace(entry[:at]), code) {
|
||||
continue
|
||||
}
|
||||
for _, r := range strings.FieldsFunc(entry[at+1:], func(r rune) bool { return r == ',' }) {
|
||||
if r = strings.TrimSpace(r); r != "" {
|
||||
out = append(out, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// mergeManual appends operator-assigned codes to the auto-found set, deduped.
|
||||
// When the award is predefined, only references present and valid in its list
|
||||
// are kept (so a typo can't invent a reference).
|
||||
func mergeManual(found, manual []string, rl refList, predefined bool) []string {
|
||||
seen := map[string]struct{}{}
|
||||
for _, c := range found {
|
||||
seen[normalizeRef(c)] = struct{}{}
|
||||
}
|
||||
for _, c := range manual {
|
||||
c = normalizeRef(c)
|
||||
if _, dup := seen[c]; dup {
|
||||
continue
|
||||
}
|
||||
if predefined {
|
||||
if m, ok := rl.byCode[c]; !ok || !m.Valid {
|
||||
continue
|
||||
}
|
||||
}
|
||||
seen[c] = struct{}{}
|
||||
found = append(found, c)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
// Confirmed reports whether a QSO satisfies any of the given confirmation
|
||||
|
||||
Reference in New Issue
Block a user