not1mm 23.12.24__py3-none-any.whl → 24.1.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- not1mm/__main__.py +33 -27
- not1mm/data/new_contest.ui +10 -0
- not1mm/lib/version.py +1 -1
- not1mm/plugins/phone_weekly_test.py +372 -0
- not1mm/plugins/stew_perry_topband.py +324 -0
- not1mm/weee.py +10 -0
- {not1mm-23.12.24.dist-info → not1mm-24.1.16.dist-info}/METADATA +5 -9
- {not1mm-23.12.24.dist-info → not1mm-24.1.16.dist-info}/RECORD +12 -9
- {not1mm-23.12.24.dist-info → not1mm-24.1.16.dist-info}/LICENSE +0 -0
- {not1mm-23.12.24.dist-info → not1mm-24.1.16.dist-info}/WHEEL +0 -0
- {not1mm-23.12.24.dist-info → not1mm-24.1.16.dist-info}/entry_points.txt +0 -0
- {not1mm-23.12.24.dist-info → not1mm-24.1.16.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -846,34 +846,40 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
846
846
|
self.pref.get("contest")
|
847
847
|
)
|
848
848
|
if self.contest_settings:
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
self.contest.init_contest(self)
|
855
|
-
self.hide_band_mode(self.contest_settings.get("ModeCategory", ""))
|
856
|
-
logger.debug("%s", f"{self.contest_settings}")
|
857
|
-
if self.contest_settings.get("ModeCategory", "") == "CW":
|
858
|
-
self.setmode("CW")
|
859
|
-
self.radio_state["mode"] = "CW"
|
860
|
-
if self.rig_control:
|
861
|
-
if self.rig_control.online:
|
862
|
-
self.rig_control.set_mode("CW")
|
863
|
-
band = getband(str(self.radio_state.get("vfoa", "0.0")))
|
864
|
-
self.set_band_indicator(band)
|
865
|
-
self.set_window_title()
|
866
|
-
if self.contest_settings.get("ModeCategory", "") == "SSB":
|
867
|
-
self.setmode("SSB")
|
868
|
-
if int(self.radio_state.get("vfoa", 0)) > 10000000:
|
869
|
-
self.radio_state["mode"] = "USB"
|
870
|
-
else:
|
871
|
-
self.radio_state["mode"] = "LSB"
|
872
|
-
band = getband(str(self.radio_state.get("vfoa", "0.0")))
|
873
|
-
self.set_band_indicator(band)
|
849
|
+
try:
|
850
|
+
self.database.current_contest = self.pref.get("contest")
|
851
|
+
if self.contest_settings.get("ContestName"):
|
852
|
+
self.contest = doimp(self.contest_settings.get("ContestName"))
|
853
|
+
logger.debug("Loaded Contest Name = %s", self.contest.name)
|
874
854
|
self.set_window_title()
|
875
|
-
|
876
|
-
|
855
|
+
self.contest.init_contest(self)
|
856
|
+
self.hide_band_mode(
|
857
|
+
self.contest_settings.get("ModeCategory", "")
|
858
|
+
)
|
859
|
+
logger.debug("%s", f"{self.contest_settings}")
|
860
|
+
if self.contest_settings.get("ModeCategory", "") == "CW":
|
861
|
+
self.setmode("CW")
|
862
|
+
self.radio_state["mode"] = "CW"
|
863
|
+
if self.rig_control:
|
864
|
+
if self.rig_control.online:
|
865
|
+
self.rig_control.set_mode("CW")
|
866
|
+
band = getband(str(self.radio_state.get("vfoa", "0.0")))
|
867
|
+
self.set_band_indicator(band)
|
868
|
+
self.set_window_title()
|
869
|
+
if self.contest_settings.get("ModeCategory", "") == "SSB":
|
870
|
+
self.setmode("SSB")
|
871
|
+
if int(self.radio_state.get("vfoa", 0)) > 10000000:
|
872
|
+
self.radio_state["mode"] = "USB"
|
873
|
+
else:
|
874
|
+
self.radio_state["mode"] = "LSB"
|
875
|
+
band = getband(str(self.radio_state.get("vfoa", "0.0")))
|
876
|
+
self.set_band_indicator(band)
|
877
|
+
self.set_window_title()
|
878
|
+
if self.rig_control:
|
879
|
+
self.rig_control.set_mode(self.radio_state.get("mode"))
|
880
|
+
except ModuleNotFoundError:
|
881
|
+
self.pref["contest"] = 1
|
882
|
+
self.show_message_box("Contest plugin not found")
|
877
883
|
|
878
884
|
if hasattr(self.contest, "mode"):
|
879
885
|
logger.debug("%s", f" **** {self.contest}")
|
not1mm/data/new_contest.ui
CHANGED
@@ -312,6 +312,16 @@
|
|
312
312
|
<string>NAQP SSB</string>
|
313
313
|
</property>
|
314
314
|
</item>
|
315
|
+
<item>
|
316
|
+
<property name="text">
|
317
|
+
<string>PHONE WEEKLY TEST</string>
|
318
|
+
</property>
|
319
|
+
</item>
|
320
|
+
<item>
|
321
|
+
<property name="text">
|
322
|
+
<string>STEW PERRY TOPBAND</string>
|
323
|
+
</property>
|
324
|
+
</item>
|
315
325
|
<item>
|
316
326
|
<property name="text">
|
317
327
|
<string>WINTER FIELD DAY</string>
|
not1mm/lib/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""It's the version"""
|
2
|
-
__version__ = "
|
2
|
+
__version__ = "24.1.16"
|
@@ -0,0 +1,372 @@
|
|
1
|
+
"""Phone Weekly Test plugin"""
|
2
|
+
|
3
|
+
# Geographic Focus: North America
|
4
|
+
# Participation: Worldwide
|
5
|
+
# Mode: SSB
|
6
|
+
# Bands: 160, 80, 40, 20, 15m
|
7
|
+
# Classes: Single Op
|
8
|
+
# Max power: 100 watts
|
9
|
+
# Exchange: NA: Name + (state/province/country)
|
10
|
+
# non-NA: Name
|
11
|
+
# Work stations: Once per band
|
12
|
+
# QSO Points: NA station: 1 point per QSO
|
13
|
+
# non-NA station: 1 point per QSO with an NA station
|
14
|
+
# Multipliers: Each US state (including KH6/KL7) once per band
|
15
|
+
# Each VE province/territory once per band
|
16
|
+
# Each North American country (except W/VE) once per band
|
17
|
+
# Score Calculation: Total score = total QSO points x total mults
|
18
|
+
# Submit logs by: 0300Z January 19, 2024
|
19
|
+
# E-mail logs to: (none)
|
20
|
+
# Post log summary at: http://www.3830scores.com
|
21
|
+
# Mail logs to: (none)
|
22
|
+
# Find rules at: http://www.perluma.com/Phone_Fray_Contest_Rules.pdf
|
23
|
+
|
24
|
+
|
25
|
+
# pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member, unused-import
|
26
|
+
|
27
|
+
import datetime
|
28
|
+
import logging
|
29
|
+
import platform
|
30
|
+
|
31
|
+
from pathlib import Path
|
32
|
+
|
33
|
+
from PyQt5 import QtWidgets
|
34
|
+
|
35
|
+
from not1mm.lib.plugin_common import gen_adif, get_points
|
36
|
+
from not1mm.lib.version import __version__
|
37
|
+
|
38
|
+
logger = logging.getLogger("__main__")
|
39
|
+
|
40
|
+
name = "PHONE WEEKLY TEST"
|
41
|
+
cabrillo_name = "PHONE-WEEKLY-TEST"
|
42
|
+
mode = "SSB" # CW SSB BOTH RTTY
|
43
|
+
# columns = [0, 1, 2, 3, 4, 10, 11, 14, 15]
|
44
|
+
columns = [
|
45
|
+
"YYYY-MM-DD HH:MM:SS",
|
46
|
+
"Call",
|
47
|
+
"Freq",
|
48
|
+
"Name",
|
49
|
+
"Sect",
|
50
|
+
"M1",
|
51
|
+
"PTS",
|
52
|
+
]
|
53
|
+
|
54
|
+
advance_on_space = [True, True, True, True, True]
|
55
|
+
|
56
|
+
# 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
|
57
|
+
dupe_type = 2
|
58
|
+
|
59
|
+
|
60
|
+
def init_contest(self):
|
61
|
+
"""setup plugin"""
|
62
|
+
set_tab_next(self)
|
63
|
+
set_tab_prev(self)
|
64
|
+
interface(self)
|
65
|
+
self.next_field = self.other_1
|
66
|
+
|
67
|
+
|
68
|
+
def interface(self):
|
69
|
+
"""Setup user interface"""
|
70
|
+
self.field1.hide()
|
71
|
+
self.field2.hide()
|
72
|
+
self.field3.show()
|
73
|
+
self.field4.show()
|
74
|
+
namefield = self.field3.findChild(QtWidgets.QLabel)
|
75
|
+
namefield.setText("Name")
|
76
|
+
self.field3.setAccessibleName("Name")
|
77
|
+
spc = self.field4.findChild(QtWidgets.QLabel)
|
78
|
+
spc.setText("State")
|
79
|
+
self.field4.setAccessibleName("State")
|
80
|
+
|
81
|
+
|
82
|
+
def reset_label(self):
|
83
|
+
"""reset label after field cleared"""
|
84
|
+
|
85
|
+
|
86
|
+
def set_tab_next(self):
|
87
|
+
"""Set TAB Advances"""
|
88
|
+
self.tab_next = {
|
89
|
+
self.callsign: self.field3.findChild(QtWidgets.QLineEdit),
|
90
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
|
91
|
+
QtWidgets.QLineEdit
|
92
|
+
),
|
93
|
+
self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
|
94
|
+
}
|
95
|
+
|
96
|
+
|
97
|
+
def set_tab_prev(self):
|
98
|
+
"""Set TAB Advances"""
|
99
|
+
self.tab_prev = {
|
100
|
+
self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
|
101
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.callsign,
|
102
|
+
self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
103
|
+
QtWidgets.QLineEdit
|
104
|
+
),
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
def set_contact_vars(self):
|
109
|
+
"""Contest Specific"""
|
110
|
+
self.contact["SNT"] = self.sent.text()
|
111
|
+
self.contact["RCV"] = self.receive.text()
|
112
|
+
self.contact["Name"] = self.other_1.text().upper()
|
113
|
+
self.contact["Sect"] = self.other_2.text().upper()
|
114
|
+
self.contact["SentNr"] = self.contest_settings.get("SentExchange", 0)
|
115
|
+
|
116
|
+
if self.contact.get("Sect"):
|
117
|
+
result = self.database.fetch_sect_band_exists(
|
118
|
+
self.contact.get("Sect", ""), self.contact.get("Band", "")
|
119
|
+
)
|
120
|
+
if result.get("sect_count"):
|
121
|
+
self.contact["IsMultiplier1"] = 0
|
122
|
+
else:
|
123
|
+
self.contact["IsMultiplier1"] = 1
|
124
|
+
|
125
|
+
|
126
|
+
def predupe(self):
|
127
|
+
"""called after callsign entered"""
|
128
|
+
|
129
|
+
|
130
|
+
def prefill(self):
|
131
|
+
"""Fill sentnr"""
|
132
|
+
# if len(self.other_2.text()) == 0:
|
133
|
+
# self.other_2.setText(str(self.contact.get("ZN", "")))
|
134
|
+
# self.other_1.setText(str(self.contest_settings.get("SentExchange", 0)))
|
135
|
+
|
136
|
+
|
137
|
+
def points(self):
|
138
|
+
"""Calc point"""
|
139
|
+
mycontinent = ""
|
140
|
+
hiscontinent = ""
|
141
|
+
result = self.cty_lookup(self.station.get("Call", ""))
|
142
|
+
if result:
|
143
|
+
for item in result.items():
|
144
|
+
mycontinent = item[1].get("continent", "")
|
145
|
+
result = self.cty_lookup(self.contact.get("Call", ""))
|
146
|
+
if result:
|
147
|
+
for item in result.items():
|
148
|
+
hiscontinent = item[1].get("continent", "")
|
149
|
+
if mycontinent == "NA" or hiscontinent == "NA":
|
150
|
+
return 1
|
151
|
+
return 0
|
152
|
+
|
153
|
+
|
154
|
+
def show_mults(self):
|
155
|
+
"""Return display string for mults"""
|
156
|
+
result = self.database.fetch_section_band_count_nodx()
|
157
|
+
if result:
|
158
|
+
return int(result.get("sb_count", 0))
|
159
|
+
return 0
|
160
|
+
|
161
|
+
|
162
|
+
def show_qso(self):
|
163
|
+
"""Return qso count"""
|
164
|
+
result = self.database.fetch_qso_count()
|
165
|
+
if result:
|
166
|
+
return int(result.get("qsos", 0))
|
167
|
+
return 0
|
168
|
+
|
169
|
+
|
170
|
+
def calc_score(self):
|
171
|
+
"""Return calculated score"""
|
172
|
+
result = self.database.fetch_points()
|
173
|
+
if result is not None:
|
174
|
+
score = result.get("Points", "0")
|
175
|
+
if score is None:
|
176
|
+
score = "0"
|
177
|
+
contest_points = int(score)
|
178
|
+
mults = show_mults(self)
|
179
|
+
return contest_points * mults
|
180
|
+
return 0
|
181
|
+
|
182
|
+
|
183
|
+
def adif(self):
|
184
|
+
"""Call the generate ADIF function"""
|
185
|
+
gen_adif(self, cabrillo_name, "NAQP-SSB")
|
186
|
+
|
187
|
+
|
188
|
+
def cabrillo(self):
|
189
|
+
"""Generates Cabrillo file. Maybe."""
|
190
|
+
# https://www.cqwpx.com/cabrillo.htm
|
191
|
+
logger.debug("******Cabrillo*****")
|
192
|
+
logger.debug("Station: %s", f"{self.station}")
|
193
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
194
|
+
now = datetime.datetime.now()
|
195
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
196
|
+
filename = (
|
197
|
+
str(Path.home())
|
198
|
+
+ "/"
|
199
|
+
+ f"{self.station.get('Call').upper()}_{cabrillo_name}_{date_time}.log"
|
200
|
+
)
|
201
|
+
logger.debug("%s", filename)
|
202
|
+
log = self.database.fetch_all_contacts_asc()
|
203
|
+
try:
|
204
|
+
with open(filename, "w", encoding="ascii") as file_descriptor:
|
205
|
+
print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
|
206
|
+
print(
|
207
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
208
|
+
end="\r\n",
|
209
|
+
file=file_descriptor,
|
210
|
+
)
|
211
|
+
print(
|
212
|
+
f"CONTEST: {cabrillo_name}",
|
213
|
+
end="\r\n",
|
214
|
+
file=file_descriptor,
|
215
|
+
)
|
216
|
+
print(
|
217
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
218
|
+
end="\r\n",
|
219
|
+
file=file_descriptor,
|
220
|
+
)
|
221
|
+
print(
|
222
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
223
|
+
end="\r\n",
|
224
|
+
file=file_descriptor,
|
225
|
+
)
|
226
|
+
# print(
|
227
|
+
# f"ARRL-SECTION: {self.pref.get('section', '')}",
|
228
|
+
# end="\r\n",
|
229
|
+
# file=file_descriptor,
|
230
|
+
# )
|
231
|
+
print(
|
232
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
233
|
+
end="\r\n",
|
234
|
+
file=file_descriptor,
|
235
|
+
)
|
236
|
+
print(
|
237
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
238
|
+
end="\r\n",
|
239
|
+
file=file_descriptor,
|
240
|
+
)
|
241
|
+
print(
|
242
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
243
|
+
end="\r\n",
|
244
|
+
file=file_descriptor,
|
245
|
+
)
|
246
|
+
print(
|
247
|
+
f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
|
248
|
+
end="\r\n",
|
249
|
+
file=file_descriptor,
|
250
|
+
)
|
251
|
+
print(
|
252
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
253
|
+
end="\r\n",
|
254
|
+
file=file_descriptor,
|
255
|
+
)
|
256
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
257
|
+
print(
|
258
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
259
|
+
end="\r\n",
|
260
|
+
file=file_descriptor,
|
261
|
+
)
|
262
|
+
print(
|
263
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
264
|
+
end="\r\n",
|
265
|
+
file=file_descriptor,
|
266
|
+
)
|
267
|
+
# print(
|
268
|
+
# f"CATEGORY: {None}",
|
269
|
+
# end="\r\n",
|
270
|
+
# file=file_descriptor,
|
271
|
+
# )
|
272
|
+
print(
|
273
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
274
|
+
end="\r\n",
|
275
|
+
file=file_descriptor,
|
276
|
+
)
|
277
|
+
|
278
|
+
print(
|
279
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
280
|
+
end="\r\n",
|
281
|
+
file=file_descriptor,
|
282
|
+
)
|
283
|
+
print(
|
284
|
+
f"OPERATORS: {self.contest_settings.get('Operators','')}",
|
285
|
+
end="\r\n",
|
286
|
+
file=file_descriptor,
|
287
|
+
)
|
288
|
+
print(
|
289
|
+
f"NAME: {self.station.get('Name', '')}",
|
290
|
+
end="\r\n",
|
291
|
+
file=file_descriptor,
|
292
|
+
)
|
293
|
+
print(
|
294
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
295
|
+
end="\r\n",
|
296
|
+
file=file_descriptor,
|
297
|
+
)
|
298
|
+
print(
|
299
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
300
|
+
end="\r\n",
|
301
|
+
file=file_descriptor,
|
302
|
+
)
|
303
|
+
print(
|
304
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
305
|
+
end="\r\n",
|
306
|
+
file=file_descriptor,
|
307
|
+
)
|
308
|
+
print(
|
309
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
310
|
+
end="\r\n",
|
311
|
+
file=file_descriptor,
|
312
|
+
)
|
313
|
+
print(
|
314
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
315
|
+
end="\r\n",
|
316
|
+
file=file_descriptor,
|
317
|
+
)
|
318
|
+
print(
|
319
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
320
|
+
end="\r\n",
|
321
|
+
file=file_descriptor,
|
322
|
+
)
|
323
|
+
for contact in log:
|
324
|
+
the_date_and_time = contact.get("TS", "")
|
325
|
+
themode = contact.get("Mode", "")
|
326
|
+
if themode == "LSB" or themode == "USB":
|
327
|
+
themode = "PH"
|
328
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
329
|
+
|
330
|
+
loggeddate = the_date_and_time[:10]
|
331
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
332
|
+
print(
|
333
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
334
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
335
|
+
f"{str(contact.get('SentNr', '')).upper()} "
|
336
|
+
f"{contact.get('Call', '').ljust(13)} "
|
337
|
+
f"{str(contact.get('Name', '')).ljust(11)} "
|
338
|
+
f"{str(contact.get('Sect', '')).ljust(5)}",
|
339
|
+
end="\r\n",
|
340
|
+
file=file_descriptor,
|
341
|
+
)
|
342
|
+
print("END-OF-LOG:", end="\r\n", file=file_descriptor)
|
343
|
+
except IOError as exception:
|
344
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
345
|
+
return
|
346
|
+
|
347
|
+
|
348
|
+
def recalculate_mults(self):
|
349
|
+
"""Recalculates multipliers after change in logged qso."""
|
350
|
+
|
351
|
+
all_contacts = self.database.fetch_all_contacts_asc()
|
352
|
+
for contact in all_contacts:
|
353
|
+
time_stamp = contact.get("TS")
|
354
|
+
sect = contact.get("Sect", "")
|
355
|
+
band = contact.get("Band", "")
|
356
|
+
query = (
|
357
|
+
f"select count(*) as sect_count from dxlog where TS < '{time_stamp}' "
|
358
|
+
f"and Sect = '{sect}' "
|
359
|
+
f"and Band = '{band}' "
|
360
|
+
f"and ContestNR = {self.pref.get('contest', '1')};"
|
361
|
+
)
|
362
|
+
result = self.database.exec_sql(query)
|
363
|
+
count = result.get("sect_count", 1)
|
364
|
+
if count == 0 and contact.get("Points", 0) == 1 and sect != "DX":
|
365
|
+
contact["IsMultiplier1"] = 1
|
366
|
+
else:
|
367
|
+
contact["IsMultiplier1"] = 0
|
368
|
+
self.database.change_contact(contact)
|
369
|
+
cmd = {}
|
370
|
+
cmd["cmd"] = "UPDATELOG"
|
371
|
+
cmd["station"] = platform.node()
|
372
|
+
self.multicast_interface.send_as_json(cmd)
|
@@ -0,0 +1,324 @@
|
|
1
|
+
"""Stew Perry Topband plugin"""
|
2
|
+
|
3
|
+
# Geographic Focus: Worldwide
|
4
|
+
# Participation: Worldwide
|
5
|
+
# Awards: Worldwide
|
6
|
+
# Mode: CW
|
7
|
+
# Bands: 160m Only
|
8
|
+
# Classes: Single Op (QRP/Low/High)
|
9
|
+
# Multi-Op (QRP/Low/High)
|
10
|
+
# Max operating hours: 14 hours
|
11
|
+
# Max power: HP: >100 watts
|
12
|
+
# LP: 5-100 watts
|
13
|
+
# QRP: <5 watts
|
14
|
+
# Exchange: 4-Character grid square
|
15
|
+
# QSO Points: 1 point per QSO plus 1 point per 500 km
|
16
|
+
# multiply QSO points by 2 if low power station
|
17
|
+
# multiply QSO points by 4 if QRP station
|
18
|
+
# Multipliers: (none)
|
19
|
+
# Score Calculation: Total score = total QSO points x power multiplier
|
20
|
+
# Submit logs by: January 15, 2024
|
21
|
+
# E-mail logs to: (none)
|
22
|
+
# Upload log at: http://www.b4h.net/stew/tbdcsubmitlog.php
|
23
|
+
# Mail logs to: BARC
|
24
|
+
# 50335 NW Hayward Rd
|
25
|
+
# Manning, OR 97125
|
26
|
+
# USA
|
27
|
+
# Find rules at: http://www.kkn.net/stew/
|
28
|
+
|
29
|
+
# pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member
|
30
|
+
|
31
|
+
import datetime
|
32
|
+
import logging
|
33
|
+
|
34
|
+
from pathlib import Path
|
35
|
+
from PyQt5 import QtWidgets
|
36
|
+
from not1mm.lib.plugin_common import gen_adif, get_points
|
37
|
+
from not1mm.lib.version import __version__
|
38
|
+
from not1mm.lib.ham_utility import distance
|
39
|
+
|
40
|
+
logger = logging.getLogger("__main__")
|
41
|
+
|
42
|
+
cabrillo_name = "STEW-PERRY"
|
43
|
+
name = "Stew Perry Topband"
|
44
|
+
|
45
|
+
mode = "CW" # CW SSB BOTH RTTY
|
46
|
+
|
47
|
+
columns = [
|
48
|
+
"YYYY-MM-DD HH:MM:SS",
|
49
|
+
"Call",
|
50
|
+
"Freq",
|
51
|
+
"Mode",
|
52
|
+
"Exchange1",
|
53
|
+
"PTS",
|
54
|
+
]
|
55
|
+
|
56
|
+
advance_on_space = [True, True, True, True, True]
|
57
|
+
|
58
|
+
# 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
|
59
|
+
dupe_type = 1
|
60
|
+
|
61
|
+
|
62
|
+
def init_contest(self):
|
63
|
+
"""setup plugin"""
|
64
|
+
set_tab_next(self)
|
65
|
+
set_tab_prev(self)
|
66
|
+
interface(self)
|
67
|
+
self.next_field = self.other_1
|
68
|
+
|
69
|
+
|
70
|
+
def interface(self):
|
71
|
+
"""Setup user interface"""
|
72
|
+
self.field1.show()
|
73
|
+
self.field2.show()
|
74
|
+
self.field3.show()
|
75
|
+
self.field4.hide()
|
76
|
+
label = self.field3.findChild(QtWidgets.QLabel)
|
77
|
+
label.setText("Grid")
|
78
|
+
self.field3.setAccessibleName("Grid")
|
79
|
+
|
80
|
+
|
81
|
+
def reset_label(self):
|
82
|
+
"""reset label after field cleared"""
|
83
|
+
|
84
|
+
|
85
|
+
def set_tab_next(self):
|
86
|
+
"""Set TAB Advances"""
|
87
|
+
self.tab_next = {
|
88
|
+
self.callsign: self.field3.findChild(QtWidgets.QLineEdit),
|
89
|
+
self.field1.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
90
|
+
QtWidgets.QLineEdit
|
91
|
+
),
|
92
|
+
self.field2.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
93
|
+
QtWidgets.QLineEdit
|
94
|
+
),
|
95
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.callsign,
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
def set_tab_prev(self):
|
100
|
+
"""Set TAB Advances"""
|
101
|
+
self.tab_prev = {
|
102
|
+
self.callsign: self.field3.findChild(QtWidgets.QLineEdit),
|
103
|
+
self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
|
104
|
+
self.field2.findChild(QtWidgets.QLineEdit): self.callsign,
|
105
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.callsign,
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
def set_contact_vars(self):
|
110
|
+
"""Contest Specific"""
|
111
|
+
self.contact["SNT"] = self.sent.text()
|
112
|
+
self.contact["RCV"] = self.receive.text()
|
113
|
+
self.contact["Exchange1"] = self.other_1.text().upper()
|
114
|
+
|
115
|
+
|
116
|
+
def predupe(self):
|
117
|
+
"""called after callsign entered"""
|
118
|
+
|
119
|
+
|
120
|
+
def prefill(self):
|
121
|
+
"""Fill SentNR"""
|
122
|
+
|
123
|
+
|
124
|
+
def points(self):
|
125
|
+
"""Calc point"""
|
126
|
+
_points = 1
|
127
|
+
_kilometers = 0
|
128
|
+
_their_grid = self.other_1.text().upper()
|
129
|
+
_kilometers = distance(self.station.get("GridSquare", ""), _their_grid)
|
130
|
+
if _kilometers > 500:
|
131
|
+
_points = _points + int(_kilometers / 500)
|
132
|
+
if self.contest_settings.get("PowerCategory", "") == "QRP":
|
133
|
+
_points = _points * 4
|
134
|
+
if self.contest_settings.get("PowerCategory", "") == "LOW":
|
135
|
+
_points = _points * 2
|
136
|
+
return _points
|
137
|
+
|
138
|
+
|
139
|
+
def show_mults(self):
|
140
|
+
"""Return display string for mults"""
|
141
|
+
return 0
|
142
|
+
|
143
|
+
|
144
|
+
def show_qso(self):
|
145
|
+
"""Return qso count"""
|
146
|
+
result = self.database.fetch_qso_count()
|
147
|
+
if result:
|
148
|
+
return int(result.get("qsos", 0))
|
149
|
+
return 0
|
150
|
+
|
151
|
+
|
152
|
+
def calc_score(self):
|
153
|
+
"""Return calculated score"""
|
154
|
+
_points = get_points(self)
|
155
|
+
return _points
|
156
|
+
|
157
|
+
|
158
|
+
def adif(self):
|
159
|
+
"""Call the generate ADIF function"""
|
160
|
+
gen_adif(self, cabrillo_name, "STEW-PERRY")
|
161
|
+
|
162
|
+
|
163
|
+
def cabrillo(self):
|
164
|
+
"""Generates Cabrillo file. Maybe."""
|
165
|
+
# https://www.cqwpx.com/cabrillo.htm
|
166
|
+
logger.debug("******Cabrillo*****")
|
167
|
+
logger.debug("Station: %s", f"{self.station}")
|
168
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
169
|
+
now = datetime.datetime.now()
|
170
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
171
|
+
filename = (
|
172
|
+
str(Path.home())
|
173
|
+
+ "/"
|
174
|
+
+ f"{self.station.get('Call').upper()}_{cabrillo_name}_{date_time}.log"
|
175
|
+
)
|
176
|
+
logger.debug("%s", filename)
|
177
|
+
log = self.database.fetch_all_contacts_asc()
|
178
|
+
try:
|
179
|
+
with open(filename, "w", encoding="ascii") as file_descriptor:
|
180
|
+
print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
|
181
|
+
print(
|
182
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
183
|
+
end="\r\n",
|
184
|
+
file=file_descriptor,
|
185
|
+
)
|
186
|
+
print(
|
187
|
+
f"CONTEST: {cabrillo_name}",
|
188
|
+
end="\r\n",
|
189
|
+
file=file_descriptor,
|
190
|
+
)
|
191
|
+
print(
|
192
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
193
|
+
end="\r\n",
|
194
|
+
file=file_descriptor,
|
195
|
+
)
|
196
|
+
print(
|
197
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
198
|
+
end="\r\n",
|
199
|
+
file=file_descriptor,
|
200
|
+
)
|
201
|
+
# print(
|
202
|
+
# f"ARRL-SECTION: {self.pref.get('section', '')}",
|
203
|
+
# end="\r\n",
|
204
|
+
# file=file_descriptor,
|
205
|
+
# )
|
206
|
+
print(
|
207
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
208
|
+
end="\r\n",
|
209
|
+
file=file_descriptor,
|
210
|
+
)
|
211
|
+
print(
|
212
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
213
|
+
end="\r\n",
|
214
|
+
file=file_descriptor,
|
215
|
+
)
|
216
|
+
print(
|
217
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
218
|
+
end="\r\n",
|
219
|
+
file=file_descriptor,
|
220
|
+
)
|
221
|
+
print(
|
222
|
+
f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
|
223
|
+
end="\r\n",
|
224
|
+
file=file_descriptor,
|
225
|
+
)
|
226
|
+
print(
|
227
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
228
|
+
end="\r\n",
|
229
|
+
file=file_descriptor,
|
230
|
+
)
|
231
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
232
|
+
print(
|
233
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
234
|
+
end="\r\n",
|
235
|
+
file=file_descriptor,
|
236
|
+
)
|
237
|
+
print(
|
238
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
239
|
+
end="\r\n",
|
240
|
+
file=file_descriptor,
|
241
|
+
)
|
242
|
+
# print(
|
243
|
+
# f"CATEGORY: {None}",
|
244
|
+
# end="\r\n",
|
245
|
+
# file=file_descriptor,
|
246
|
+
# )
|
247
|
+
print(
|
248
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
249
|
+
end="\r\n",
|
250
|
+
file=file_descriptor,
|
251
|
+
)
|
252
|
+
|
253
|
+
print(
|
254
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
255
|
+
end="\r\n",
|
256
|
+
file=file_descriptor,
|
257
|
+
)
|
258
|
+
print(
|
259
|
+
"OPERATORS: ",
|
260
|
+
end="\r\n",
|
261
|
+
file=file_descriptor,
|
262
|
+
)
|
263
|
+
print(
|
264
|
+
f"NAME: {self.station.get('Name', '')}",
|
265
|
+
end="\r\n",
|
266
|
+
file=file_descriptor,
|
267
|
+
)
|
268
|
+
print(
|
269
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
270
|
+
end="\r\n",
|
271
|
+
file=file_descriptor,
|
272
|
+
)
|
273
|
+
print(
|
274
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
275
|
+
end="\r\n",
|
276
|
+
file=file_descriptor,
|
277
|
+
)
|
278
|
+
print(
|
279
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
280
|
+
end="\r\n",
|
281
|
+
file=file_descriptor,
|
282
|
+
)
|
283
|
+
print(
|
284
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
285
|
+
end="\r\n",
|
286
|
+
file=file_descriptor,
|
287
|
+
)
|
288
|
+
print(
|
289
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
290
|
+
end="\r\n",
|
291
|
+
file=file_descriptor,
|
292
|
+
)
|
293
|
+
print(
|
294
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
295
|
+
end="\r\n",
|
296
|
+
file=file_descriptor,
|
297
|
+
)
|
298
|
+
for contact in log:
|
299
|
+
the_date_and_time = contact.get("TS", "")
|
300
|
+
themode = contact.get("Mode", "")
|
301
|
+
if themode == "LSB" or themode == "USB":
|
302
|
+
themode = "PH"
|
303
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
304
|
+
|
305
|
+
loggeddate = the_date_and_time[:10]
|
306
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
307
|
+
print(
|
308
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
309
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
310
|
+
f"{self.contest_settings.get('SentExchange', '').ljust(9).upper()}"
|
311
|
+
f"{contact.get('Call', '').ljust(13)} "
|
312
|
+
f"{str(contact.get('Exchange1', '')).ljust(3)} "
|
313
|
+
f"{str(contact.get('Sect', '')).ljust(6)}",
|
314
|
+
end="\r\n",
|
315
|
+
file=file_descriptor,
|
316
|
+
)
|
317
|
+
print("END-OF-LOG:", end="\r\n", file=file_descriptor)
|
318
|
+
except IOError as exception:
|
319
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
320
|
+
return
|
321
|
+
|
322
|
+
|
323
|
+
def recalculate_mults(self):
|
324
|
+
"""Recalculates multipliers after change in logged qso."""
|
not1mm/weee.py
ADDED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version:
|
3
|
+
Version: 24.1.16
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
Project-URL: Homepage, https://github.com/mbridak/not1mm
|
@@ -158,19 +158,15 @@ I wish to thank those who've contributed to the project.
|
|
158
158
|
- Japan International DX SSB
|
159
159
|
- NAQP CW
|
160
160
|
- NAQP SSB
|
161
|
+
- Phone Weekly Test
|
161
162
|
- RAC Canada Day
|
163
|
+
- Stew Perry Topband
|
162
164
|
- Winter Field Day
|
163
165
|
|
164
166
|
## Recent Changes
|
165
167
|
|
166
|
-
- [
|
167
|
-
- [
|
168
|
-
- [23-12-20] Add ARRL VHF Jun and Sep.
|
169
|
-
- [23-12-19] Add ARRL VHF contest. Add VHF frequencies. Add Bands TAB to configuration dialog to select active bands you want displayed.
|
170
|
-
- [23-12-17] Add ARRL 10M contest. Fixed crash in RAC Canada Day
|
171
|
-
- [23-12-5] Removed deprecated datetime.utcnow()
|
172
|
-
- [23-12-4] Moved get_points to plugin_common, fixing crash.
|
173
|
-
- [23-12-3] Initial WFD plugin.
|
168
|
+
- [24-1-16] Added Stew Perry Topband.
|
169
|
+
- [24-1-15] Added the Phone Weekly Test.
|
174
170
|
|
175
171
|
See [CHANGELOG.md](CHANGELOG.md) for prior changes.
|
176
172
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256
|
2
|
+
not1mm/__main__.py,sha256=KWJHlEDYQKXJG1cDPPKeEAK12KjX1YnxsFuDU68FBI4,98755
|
3
3
|
not1mm/bandmap.py,sha256=WBCy3erbsmDTNQ5e3H7e1Fl1iQcYljeJRvW5Yqg32sc,28917
|
4
4
|
not1mm/checkwindow.py,sha256=CbdE_q2Ozo3mL04R18gSwjrP2Tr3pFRFXcCkr92IH60,7249
|
5
5
|
not1mm/logwindow.py,sha256=Rw2393HcyXvP5MQXI0nPxEoD0eCT_PiD3S2Ni9dJS38,41889
|
6
6
|
not1mm/vfo.py,sha256=UzQMvI7gc6HyBAhPYCZY1hsDDBM4uygxBRPCl4E_wfQ,10296
|
7
|
+
not1mm/weee.py,sha256=BEvubqsIu18QqFcqnreSSwBVsaNCXu2rU_no7brdwq4,167
|
7
8
|
not1mm/data/JetBrainsMono-Regular.ttf,sha256=UOHctAKY_PzCGh7zy-6f6egnCcSK0wzmF0csBqO9lDY,203952
|
8
9
|
not1mm/data/MASTER.SCP,sha256=kFAOdDe52-pTKrWdi97LvqWVmfc1HYNTnUINKiwURWA,362318
|
9
10
|
not1mm/data/about.ui,sha256=7TqvtXFFm0Rmcu0bmLupwpO1CsK8MekfZ09_xn6kZrQ,2067
|
@@ -25,7 +26,7 @@ not1mm/data/k6gte.not1mm-32.png,sha256=yucSwzlmqv3NegdWUvPvZzSgP7G22Ky3se8TWRXvz
|
|
25
26
|
not1mm/data/k6gte.not1mm-64.png,sha256=1KQvk0WBckUds79BvIFUt-KdTwQKKvTz6hiJu8MiT68,2152
|
26
27
|
not1mm/data/logwindow.ui,sha256=_-wobHhIjALzCswyXIrqNadnLdc88eay1GNF23a-Qh0,970
|
27
28
|
not1mm/data/main.ui,sha256=zhF00NG9BL6EDr7159GNvvU8vb0oH9FUsdTGli9xY58,53841
|
28
|
-
not1mm/data/new_contest.ui,sha256=
|
29
|
+
not1mm/data/new_contest.ui,sha256=hMB8gRc4kNAqsL4JwEkTpKBKsL24gjD6DPNIhHw-prM,21609
|
29
30
|
not1mm/data/not1mm.html,sha256=YfPiT9SrSZfsxShbiLTtdCa3rSY6M2haZ2eKV8kmU3c,25793
|
30
31
|
not1mm/data/opon.ui,sha256=mC4OhoVIfR1H9IqHAKXliPMm8VOVmxSEadpsFQ7XnS4,2247
|
31
32
|
not1mm/data/pickcontest.ui,sha256=_9JFiJw4l-bRRgNDtVg1DpxreylYd_UqEq0wfcr9gJc,1600
|
@@ -102,7 +103,7 @@ not1mm/lib/plugin_common.py,sha256=5IWIy24NpAuuzzPEjmaqeKyFHllkOgVN1gEu8vkCZsg,7
|
|
102
103
|
not1mm/lib/select_contest.py,sha256=XQdRUkPAIHIMVsilm82M54b_v9yWpYrZ1nfInJrtZoo,363
|
103
104
|
not1mm/lib/settings.py,sha256=t_JLJPnDBtMGAvJMAF1AL1eVB7MyucqlksVTU47yxvk,8933
|
104
105
|
not1mm/lib/super_check_partial.py,sha256=GlXgtIblL602iW-V6Mmdf5S4FxtzJ95TbPMMa9xXUfg,1692
|
105
|
-
not1mm/lib/version.py,sha256=
|
106
|
+
not1mm/lib/version.py,sha256=wLKVAjOPJ2wbgGJKMffhgSKeCAJSRHcFKGaptSw9UUU,47
|
106
107
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
107
108
|
not1mm/plugins/10_10_fall_cw.py,sha256=yGMRxMXE6NW2Qie4olq1E9YziHOLCXp4_ZP7LXvbYf0,10307
|
108
109
|
not1mm/plugins/10_10_spring_cw.py,sha256=J3FrRQbkA3dMEQiY7-cWJ0lGCakT1hhl8yynNszQ9qI,10313
|
@@ -131,6 +132,8 @@ not1mm/plugins/jidx_cw.py,sha256=1QJj5mfuxLjqxv3L3Gi-F5tcuG4cUXtHrI4noGhC5-Y,105
|
|
131
132
|
not1mm/plugins/jidx_ph.py,sha256=cTaPoCGYhS8jjTFAP0rnKb_EeO20ssv1dWJsLpWdiWg,10506
|
132
133
|
not1mm/plugins/naqp_cw.py,sha256=Dba9YqJroq9d10lrFLD57Zpgv9kmoF5Y0bJFW_xx0vs,11115
|
133
134
|
not1mm/plugins/naqp_ssb.py,sha256=Wm07zXkWzLTgc09Uq7M-XTQ7NavYmKJrzKuYt87OL-U,11120
|
135
|
+
not1mm/plugins/phone_weekly_test.py,sha256=Zpqm8NnKIP31TcJfCqgAuIi_l7ckXqBwPNiEacJNScs,11922
|
136
|
+
not1mm/plugins/stew_perry_topband.py,sha256=IwKrYp8YBnHdpSm34j76HQQB-X1O4kEzkIPmWzj3YtE,9975
|
134
137
|
not1mm/plugins/winter_field_day.py,sha256=GIwH26HdVlaui_EfuzjlTDrDbrGCxaY0m02XmgzjqDQ,9641
|
135
138
|
not1mm/testing/fakeflrig.py,sha256=_vJHGjARpSNxSZngkHNO_kkHoVnqtf--T6gwTAYnnZQ,2083
|
136
139
|
not1mm/testing/flrigclient.py,sha256=24r_0HqpoTjyJ6Bqg_HIC8Nn9wjtnwwWQ26I7UprwgA,1658
|
@@ -139,9 +142,9 @@ not1mm/testing/n1mm_listener.py,sha256=UD-qyKEnppQua330WEFKMvMJaNjnYKi7dDuX_RGB5
|
|
139
142
|
not1mm/testing/test.py,sha256=wGblvMlyOCVkEiHbxE6wvLsorim15ehL72_EZLQeWkk,1660
|
140
143
|
testing/test.py,sha256=q7socQaMu46q-I-1fYgmQhnygrrC5NjAUM5yuySo4fA,249
|
141
144
|
usb_vfo_knob/code.py,sha256=h59iPPlcYbkXmRcYPQHDBP0yfLEl7fY3VkiIszdQeyI,1057
|
142
|
-
not1mm-
|
143
|
-
not1mm-
|
144
|
-
not1mm-
|
145
|
-
not1mm-
|
146
|
-
not1mm-
|
147
|
-
not1mm-
|
145
|
+
not1mm-24.1.16.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
146
|
+
not1mm-24.1.16.dist-info/METADATA,sha256=b3MG4ZSTB20H_Qzf2cq8rPDE9hmoOtY7ULdG0JwDxuo,25508
|
147
|
+
not1mm-24.1.16.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
148
|
+
not1mm-24.1.16.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
149
|
+
not1mm-24.1.16.dist-info/top_level.txt,sha256=PBUZJeDgW5ta7ghk__UYh_ygOFIhe9ymJDaxEuVumFU,28
|
150
|
+
not1mm-24.1.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|