@@ 0,0 1,167 @@
+--
+-- Copyright (c) 2023 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+--
+-- Permission is hereby granted, free of charge, to any person obtaining a copy
+-- of this software and associated documentation files (the "Software"), to deal
+-- in the Software without restriction, including without limitation the rights
+-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+-- copies of the Software, and to permit persons to whom the Software is
+-- furnished to do so, subject to the following conditions:
+--
+-- The above copyright notice and this permission notice shall be included in
+-- all copies or substantial portions of the Software.
+--
+-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-- SOFTWARE.
+--
+
+-- Rules & info at http://www.k1usn.com/sst.html
+
+local allowed_bands = {
+ [160000] = true,
+ [80000] = true,
+ [40000] = true,
+ [20000] = true,
+ [15000] = true,
+ [10000] = true,
+}
+
+local function hash(qso)
+ return string.format("%s-%u", qso.rx.station_call, qso.rx.band)
+end
+
+local function getmult(qso)
+ if qso.rx.dxcc == 1 or qso.rx.dxcc == 291 then
+ return string.format("ST:%s", qso.rx.state)
+ else
+ return string.format("DX:%u", qso.rx.dxcc)
+ end
+end
+
+local function export_qso(qso, qs, mults)
+ local key = hash(qso)
+ local mult = getmult(qso)
+
+ qs[key] = qso
+ mults[mult] = true
+end
+
+local function export(outfile)
+ local days = {}
+ local mults = {}
+ local qs = {}
+
+ for qso in hlog.index.history(true) do
+ if qso.additional['contest-id'] == 'K1USN-SST' then
+ local day = string.format('%04u-%02u-%02u', qso.start_time.year,
+ qso.start_time.month, qso.start_time.day)
+
+ if mults[day] == nil then
+ mults[day] = {}
+ end
+ if qs[day] == nil then
+ qs[day] = {}
+ end
+
+ export_qso(qso, qs[day], mults[day])
+ end
+ end
+
+ for _, day in ipairs(hlog.utils.sorted_keys(qs)) do
+ local m = mults[day]
+ local q = qs[day]
+
+ local nm = hlog.utils.count_items(m)
+ local nq = hlog.utils.count_items(q)
+
+ print(string.format("K1USN SST %s: %2u Qs * %2u Mults = %u",
+ day, nq, nm, nq * nm))
+ end
+end
+
+local function startup_fill_template(template)
+ print("K1USN SST contest script")
+
+ local state
+ local name
+
+ repeat
+ print()
+ print("Enter name used in contest (e.g., Jeff):")
+
+ name = io.stdin:read()
+ if name == "" then
+ print("Name cannot be empty.")
+ next()
+ else
+ name = name:upper()
+ end
+ until name ~= nil
+
+ repeat
+ print()
+ print("Enter state abbreviation (e.g., MA):")
+
+ state = io.stdin:read()
+ state = state:upper()
+ until state ~= nil
+
+ local exch = string.format("%s %s", name, state)
+
+ print("Using exchange: " .. exch)
+ template.tx.state = state -- FIXME: US/CA only
+ template.additional['contest-id'] = 'K1USN-SST'
+ template.additional['contest-tx'] = exch
+
+ contest.lcd(exch)
+end
+
+local function field_changed(qso, fields, field)
+ local value = fields[field]
+
+ if field == "rx.station_call" then
+ qso.rx.station_call = value
+ elseif field == "rx.name" then
+ qso.rx.name = value
+
+ qso.additional['contest-rx'] = string.format("%s %s", qso.rx.name:upper(), qso.rx.state)
+ elseif field == "rx.state" then
+ value = value:upper()
+ if value ~= "DX" then
+ qso.rx.state = value
+ end
+
+ qso.additional['contest-rx'] = string.format("%s %s", qso.rx.name:upper(), qso.rx.state)
+ elseif field == "comment" then
+ qso.comment = value
+ else
+ error(string.format("Unknown field '%s' encountered", field))
+ end
+end
+
+return {
+ labels = {
+ { 0, 0, "St. Call" },
+ { 0, 11, "Name" },
+ { 0, 25, "St" },
+ { 0, 28, "Comment" },
+ },
+
+ fields = {
+ { 1, 0, 10, "rx.station_call", },
+ { 1, 11, 13, "rx.name", },
+ { 1, 25, 2, "rx.state", },
+ { 1, 28, 24, "comment", },
+ },
+
+ events = {
+ export = export,
+ startup = startup_fill_template,
+ field_changed = field_changed,
+ },
+}