not1mm 24.12.15__py3-none-any.whl → 25.1.1__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 +4 -1
- not1mm/data/new_contest.ui +5 -0
- not1mm/lib/version.py +1 -1
- not1mm/plugins/arrl_rtty_ru.py +422 -170
- not1mm/plugins/general_logging.py +23 -14
- {not1mm-24.12.15.dist-info → not1mm-25.1.1.dist-info}/METADATA +4 -16
- {not1mm-24.12.15.dist-info → not1mm-25.1.1.dist-info}/RECORD +11 -11
- {not1mm-24.12.15.dist-info → not1mm-25.1.1.dist-info}/LICENSE +0 -0
- {not1mm-24.12.15.dist-info → not1mm-25.1.1.dist-info}/WHEEL +0 -0
- {not1mm-24.12.15.dist-info → not1mm-25.1.1.dist-info}/entry_points.txt +0 -0
- {not1mm-24.12.15.dist-info → not1mm-25.1.1.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -1742,7 +1742,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1742
1742
|
"""
|
1743
1743
|
|
1744
1744
|
self.show_message_box(
|
1745
|
-
"[
|
1745
|
+
"[ESC]\tStops cwdaemon from sending Morse.\n"
|
1746
1746
|
"[PgUp]\tIncreases the cw sending speed.\n"
|
1747
1747
|
"[PgDown]\tDecreases the cw sending speed.\n"
|
1748
1748
|
"[Arrow-Up] Jump to the next spot above the current VFO cursor\n"
|
@@ -2731,6 +2731,9 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2731
2731
|
macro = macro.replace(
|
2732
2732
|
"{EXCH}", self.contest_settings.get("SentExchange", "xxx")
|
2733
2733
|
)
|
2734
|
+
if "{LOGIT}" in macro:
|
2735
|
+
macro = macro.replace("{LOGIT}", "")
|
2736
|
+
self.save_contact()
|
2734
2737
|
return macro
|
2735
2738
|
|
2736
2739
|
def ptt_on(self) -> None:
|
not1mm/data/new_contest.ui
CHANGED
not1mm/lib/version.py
CHANGED
not1mm/plugins/arrl_rtty_ru.py
CHANGED
@@ -1,19 +1,55 @@
|
|
1
|
-
"""
|
1
|
+
"""
|
2
|
+
Mode: RTTY
|
3
|
+
Bands: 80, 40, 20, 15, 10m
|
4
|
+
Classes: Single Op (QRP/Low/High)
|
5
|
+
Single Op Unlimited (QRP/Low/High)
|
6
|
+
Single Op Overlay: (Limited Antennas)
|
7
|
+
Multi-Single (Low/High)
|
8
|
+
Multi-Two
|
9
|
+
Multi-Multi
|
10
|
+
Max operating hours: 24 hours
|
11
|
+
Max power: HP: 1500 watts
|
12
|
+
LP: 100 watts
|
13
|
+
Exchange: W/VE: RST + (state/province)
|
14
|
+
non-W/VE: RST + Serial No.
|
15
|
+
Work stations: Once per band
|
16
|
+
QSO Points: 1 point per QSO
|
17
|
+
Multipliers: Each US state+DC (except KH6/KL7) once only
|
18
|
+
Each VE province/territory once only
|
19
|
+
Each DXCC country (including KH6/KL7) once only
|
20
|
+
Score Calculation: Total score = total QSO points x total mults
|
21
|
+
Submit logs by: 2359Z January 12, 2025
|
22
|
+
E-mail logs to: (none)
|
23
|
+
Upload log at: https://contest-log-submission.arrl.org/
|
24
|
+
Mail logs to: RTTY Roundup
|
25
|
+
ARRL
|
26
|
+
225 Main St.
|
27
|
+
Newington, CT 06111
|
28
|
+
USA
|
29
|
+
Find rules at: https://www.arrl.org/rtty-roundup
|
30
|
+
|
31
|
+
|
32
|
+
"""
|
2
33
|
|
3
34
|
# pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member
|
4
35
|
|
5
36
|
import datetime
|
6
|
-
|
7
|
-
from pathlib import Path
|
37
|
+
import logging
|
8
38
|
|
39
|
+
from pathlib import Path
|
9
40
|
from PyQt6 import QtWidgets
|
10
|
-
from not1mm.lib.plugin_common import online_score_xml
|
11
41
|
|
12
|
-
|
42
|
+
from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
|
43
|
+
from not1mm.lib.version import __version__
|
44
|
+
|
45
|
+
logger = logging.getLogger(__name__)
|
13
46
|
|
14
|
-
|
47
|
+
EXCHANGE_HINT = "State/Province or #"
|
48
|
+
|
49
|
+
name = "ARRL RTTY Roundup"
|
50
|
+
mode = "RTTY" # CW SSB BOTH RTTY
|
15
51
|
cabrillo_name = "ARRL-RTTY"
|
16
|
-
|
52
|
+
|
17
53
|
columns = [
|
18
54
|
"YYYY-MM-DD HH:MM:SS",
|
19
55
|
"Call",
|
@@ -22,23 +58,13 @@ columns = [
|
|
22
58
|
"Rcv",
|
23
59
|
"SentNr",
|
24
60
|
"RcvNr",
|
25
|
-
"Exchange1",
|
26
|
-
"CK",
|
27
|
-
"Prec",
|
28
|
-
"Sect",
|
29
|
-
"WPX",
|
30
|
-
"Power",
|
31
|
-
"M1",
|
32
|
-
"ZN",
|
33
|
-
"M2",
|
34
|
-
"PFX",
|
35
61
|
"PTS",
|
36
|
-
"Name",
|
37
|
-
"Comment",
|
38
62
|
]
|
39
63
|
|
64
|
+
advance_on_space = [True, True, True, True, True]
|
65
|
+
|
40
66
|
# 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
|
41
|
-
dupe_type =
|
67
|
+
dupe_type = 2
|
42
68
|
|
43
69
|
|
44
70
|
def init_contest(self):
|
@@ -46,10 +72,23 @@ def init_contest(self):
|
|
46
72
|
set_tab_next(self)
|
47
73
|
set_tab_prev(self)
|
48
74
|
interface(self)
|
75
|
+
self.next_field = self.other_2
|
49
76
|
|
50
77
|
|
51
78
|
def interface(self):
|
52
79
|
"""Setup user interface"""
|
80
|
+
self.field1.show()
|
81
|
+
self.field2.show()
|
82
|
+
self.field3.show()
|
83
|
+
self.field4.show()
|
84
|
+
self.snt_label.setText("SNT")
|
85
|
+
self.field1.setAccessibleName("RST Sent")
|
86
|
+
# label = self.field3.findChild(QtWidgets.QLabel)
|
87
|
+
self.other_label.setText("SentNR")
|
88
|
+
self.field3.setAccessibleName("Sent Number")
|
89
|
+
# label = self.field4.findChild(QtWidgets.QLabel)
|
90
|
+
self.exch_label.setText("State|Prov|SN")
|
91
|
+
self.field4.setAccessibleName("State Province or Serial Number")
|
53
92
|
|
54
93
|
|
55
94
|
def reset_label(self):
|
@@ -78,8 +117,22 @@ def set_tab_prev(self):
|
|
78
117
|
}
|
79
118
|
|
80
119
|
|
120
|
+
def validate(self):
|
121
|
+
"""doc"""
|
122
|
+
# exchange = self.other_2.text().upper().split()
|
123
|
+
# if len(exchange) == 3:
|
124
|
+
# if exchange[0].isalpha() and exchange[1].isdigit() and exchange[2].isalpha():
|
125
|
+
# return True
|
126
|
+
# return False
|
127
|
+
return True
|
128
|
+
|
129
|
+
|
81
130
|
def set_contact_vars(self):
|
82
131
|
"""Contest Specific"""
|
132
|
+
self.contact["SNT"] = self.sent.text()
|
133
|
+
self.contact["RCV"] = self.receive.text()
|
134
|
+
self.contact["NR"] = self.other_2.text().upper()
|
135
|
+
self.contact["SentNr"] = self.other_1.text()
|
83
136
|
|
84
137
|
|
85
138
|
def predupe(self):
|
@@ -87,15 +140,51 @@ def predupe(self):
|
|
87
140
|
|
88
141
|
|
89
142
|
def prefill(self):
|
90
|
-
"""Fill
|
143
|
+
"""Fill sentnr"""
|
144
|
+
result = self.database.get_serial()
|
145
|
+
serial_nr = str(result.get("serial_nr", "1")).zfill(3)
|
146
|
+
if serial_nr == "None":
|
147
|
+
serial_nr = "001"
|
148
|
+
|
149
|
+
exchange = self.contest_settings.get("SentExchange", "").replace("#", serial_nr)
|
150
|
+
if len(self.other_1.text()) == 0:
|
151
|
+
self.other_1.setText(exchange)
|
91
152
|
|
92
153
|
|
93
154
|
def points(self):
|
94
155
|
"""Calc point"""
|
156
|
+
return 1
|
95
157
|
|
96
158
|
|
97
159
|
def show_mults(self, rtc=None):
|
98
160
|
"""Return display string for mults"""
|
161
|
+
# CountryPrefix, integer
|
162
|
+
|
163
|
+
us_ve = 0
|
164
|
+
dx = 0
|
165
|
+
|
166
|
+
sql = (
|
167
|
+
"select count(DISTINCT(NR || ':' || Mode)) as mult_count "
|
168
|
+
f"from dxlog where ContestNR = {self.database.current_contest} and typeof(NR) = 'text';"
|
169
|
+
)
|
170
|
+
result = self.database.exec_sql(sql)
|
171
|
+
if result:
|
172
|
+
us_ve = result.get("mult_count", 0)
|
173
|
+
|
174
|
+
# DX
|
175
|
+
sql = (
|
176
|
+
"select count(DISTINCT(CountryPrefix || ':' || Mode)) as mult_count "
|
177
|
+
f"from dxlog where ContestNR = {self.database.current_contest} "
|
178
|
+
"and typeof(NR) = 'integer';"
|
179
|
+
)
|
180
|
+
result = self.database.exec_sql(sql)
|
181
|
+
if result:
|
182
|
+
dx = result.get("mult_count", 0)
|
183
|
+
|
184
|
+
if rtc is not None:
|
185
|
+
return dx, us_ve
|
186
|
+
|
187
|
+
return us_ve + dx
|
99
188
|
|
100
189
|
|
101
190
|
def show_qso(self):
|
@@ -106,183 +195,346 @@ def show_qso(self):
|
|
106
195
|
return 0
|
107
196
|
|
108
197
|
|
109
|
-
def get_points(self):
|
110
|
-
"""Return raw points before mults"""
|
111
|
-
result = self.database.fetch_points()
|
112
|
-
if result:
|
113
|
-
return int(result.get("Points", 0))
|
114
|
-
return 0
|
115
|
-
|
116
|
-
|
117
198
|
def calc_score(self):
|
118
199
|
"""Return calculated score"""
|
119
|
-
|
200
|
+
# Multipliers: Each US State + DC once per mode
|
201
|
+
_points = get_points(self)
|
202
|
+
_mults = show_mults(self)
|
203
|
+
_power_mult = 1
|
204
|
+
# if self.contest_settings.get("PowerCategory", "") == "QRP":
|
205
|
+
# _power_mult = 2
|
206
|
+
return _points * _power_mult * _mults
|
120
207
|
|
121
208
|
|
122
209
|
def adif(self):
|
123
|
-
"""
|
124
|
-
|
125
|
-
|
210
|
+
"""Call the generate ADIF function"""
|
211
|
+
gen_adif(self, cabrillo_name)
|
212
|
+
|
213
|
+
|
214
|
+
def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
|
215
|
+
""""""
|
216
|
+
print(
|
217
|
+
line_to_output.encode(file_encoding, errors="ignore").decode(),
|
218
|
+
end=ending,
|
219
|
+
file=file_descriptor,
|
220
|
+
)
|
221
|
+
|
222
|
+
|
223
|
+
def cabrillo(self, file_encoding):
|
224
|
+
"""Generates Cabrillo file. Maybe."""
|
225
|
+
# https://www.cqwpx.com/cabrillo.htm
|
226
|
+
logger.debug("******Cabrillo*****")
|
227
|
+
logger.debug("Station: %s", f"{self.station}")
|
228
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
126
229
|
now = datetime.datetime.now()
|
127
230
|
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
128
231
|
filename = (
|
129
232
|
str(Path.home())
|
130
233
|
+ "/"
|
131
|
-
+ f"{self.station.get('Call').upper()}_{cabrillo_name}_{date_time}.
|
234
|
+
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
|
132
235
|
)
|
236
|
+
logger.debug("%s", filename)
|
133
237
|
log = self.database.fetch_all_contacts_asc()
|
134
238
|
try:
|
135
|
-
with open(filename, "w", encoding=
|
136
|
-
|
137
|
-
|
239
|
+
with open(filename, "w", encoding=file_encoding) as file_descriptor:
|
240
|
+
output_cabrillo_line(
|
241
|
+
"START-OF-LOG: 3.0",
|
242
|
+
"\r\n",
|
243
|
+
file_descriptor,
|
244
|
+
file_encoding,
|
245
|
+
)
|
246
|
+
output_cabrillo_line(
|
247
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
248
|
+
"\r\n",
|
249
|
+
file_descriptor,
|
250
|
+
file_encoding,
|
251
|
+
)
|
252
|
+
output_cabrillo_line(
|
253
|
+
f"CONTEST: {cabrillo_name}",
|
254
|
+
"\r\n",
|
255
|
+
file_descriptor,
|
256
|
+
file_encoding,
|
257
|
+
)
|
258
|
+
if self.station.get("Club", ""):
|
259
|
+
output_cabrillo_line(
|
260
|
+
f"CLUB: {self.station.get('Club', '')}",
|
261
|
+
"\r\n",
|
262
|
+
file_descriptor,
|
263
|
+
file_encoding,
|
264
|
+
)
|
265
|
+
output_cabrillo_line(
|
266
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
267
|
+
"\r\n",
|
268
|
+
file_descriptor,
|
269
|
+
file_encoding,
|
270
|
+
)
|
271
|
+
output_cabrillo_line(
|
272
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
273
|
+
"\r\n",
|
274
|
+
file_descriptor,
|
275
|
+
file_encoding,
|
276
|
+
)
|
277
|
+
output_cabrillo_line(
|
278
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
279
|
+
"\r\n",
|
280
|
+
file_descriptor,
|
281
|
+
file_encoding,
|
282
|
+
)
|
283
|
+
output_cabrillo_line(
|
284
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
285
|
+
"\r\n",
|
286
|
+
file_descriptor,
|
287
|
+
file_encoding,
|
288
|
+
)
|
289
|
+
output_cabrillo_line(
|
290
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
291
|
+
"\r\n",
|
292
|
+
file_descriptor,
|
293
|
+
file_encoding,
|
294
|
+
)
|
295
|
+
mode = self.contest_settings.get("ModeCategory", "")
|
296
|
+
if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
|
297
|
+
mode = "MIXED"
|
298
|
+
output_cabrillo_line(
|
299
|
+
f"CATEGORY-MODE: {mode}",
|
300
|
+
"\r\n",
|
301
|
+
file_descriptor,
|
302
|
+
file_encoding,
|
303
|
+
)
|
304
|
+
output_cabrillo_line(
|
305
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
306
|
+
"\r\n",
|
307
|
+
file_descriptor,
|
308
|
+
file_encoding,
|
309
|
+
)
|
310
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
311
|
+
output_cabrillo_line(
|
312
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
313
|
+
"\r\n",
|
314
|
+
file_descriptor,
|
315
|
+
file_encoding,
|
316
|
+
)
|
317
|
+
output_cabrillo_line(
|
318
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
319
|
+
"\r\n",
|
320
|
+
file_descriptor,
|
321
|
+
file_encoding,
|
322
|
+
)
|
323
|
+
output_cabrillo_line(
|
324
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
325
|
+
"\r\n",
|
326
|
+
file_descriptor,
|
327
|
+
file_encoding,
|
328
|
+
)
|
329
|
+
|
330
|
+
output_cabrillo_line(
|
331
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
332
|
+
"\r\n",
|
333
|
+
file_descriptor,
|
334
|
+
file_encoding,
|
335
|
+
)
|
336
|
+
ops = f"@{self.station.get('Call','')}"
|
337
|
+
list_of_ops = self.database.get_ops()
|
338
|
+
for op in list_of_ops:
|
339
|
+
ops += f", {op.get('Operator', '')}"
|
340
|
+
output_cabrillo_line(
|
341
|
+
f"OPERATORS: {ops}",
|
342
|
+
"\r\n",
|
343
|
+
file_descriptor,
|
344
|
+
file_encoding,
|
345
|
+
)
|
346
|
+
output_cabrillo_line(
|
347
|
+
f"NAME: {self.station.get('Name', '')}",
|
348
|
+
"\r\n",
|
349
|
+
file_descriptor,
|
350
|
+
file_encoding,
|
351
|
+
)
|
352
|
+
output_cabrillo_line(
|
353
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
354
|
+
"\r\n",
|
355
|
+
file_descriptor,
|
356
|
+
file_encoding,
|
357
|
+
)
|
358
|
+
output_cabrillo_line(
|
359
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
360
|
+
"\r\n",
|
361
|
+
file_descriptor,
|
362
|
+
file_encoding,
|
363
|
+
)
|
364
|
+
output_cabrillo_line(
|
365
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
366
|
+
"\r\n",
|
367
|
+
file_descriptor,
|
368
|
+
file_encoding,
|
369
|
+
)
|
370
|
+
output_cabrillo_line(
|
371
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
372
|
+
"\r\n",
|
373
|
+
file_descriptor,
|
374
|
+
file_encoding,
|
375
|
+
)
|
376
|
+
output_cabrillo_line(
|
377
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
378
|
+
"\r\n",
|
379
|
+
file_descriptor,
|
380
|
+
file_encoding,
|
381
|
+
)
|
382
|
+
output_cabrillo_line(
|
383
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
384
|
+
"\r\n",
|
385
|
+
file_descriptor,
|
386
|
+
file_encoding,
|
387
|
+
)
|
138
388
|
for contact in log:
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
sentrst = contact.get("SNT", "")
|
146
|
-
rcvrst = contact.get("RCV", "")
|
147
|
-
sentnr = str(contact.get("SentNr", "0"))
|
148
|
-
rcvnr = str(contact.get("NR", "0"))
|
149
|
-
grid = contact.get("GridSquare", "")
|
150
|
-
comment = contact.get("Comment", "")
|
389
|
+
the_date_and_time = contact.get("TS", "")
|
390
|
+
themode = contact.get("Mode", "")
|
391
|
+
if themode == "LSB" or themode == "USB":
|
392
|
+
themode = "PH"
|
393
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
394
|
+
|
151
395
|
loggeddate = the_date_and_time[:10]
|
152
396
|
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
153
|
-
|
154
|
-
f"
|
155
|
-
f"{
|
156
|
-
|
157
|
-
|
397
|
+
output_cabrillo_line(
|
398
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
399
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
400
|
+
f"{str(contact.get('SNT', '')).ljust(3)} "
|
401
|
+
f"{str(contact.get('SentNr', '')).ljust(6)} "
|
402
|
+
f"{contact.get('Call', '').ljust(13)} "
|
403
|
+
f"{str(contact.get('RCV', '')).ljust(3)} "
|
404
|
+
f"{str(contact.get('NR', '')).ljust(6)}",
|
405
|
+
"\r\n",
|
406
|
+
file_descriptor,
|
407
|
+
file_encoding,
|
158
408
|
)
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
)
|
166
|
-
except TypeError:
|
167
|
-
...
|
168
|
-
|
169
|
-
try:
|
170
|
-
print(
|
171
|
-
f"<CALL:{len(hiscall)}>{hiscall.upper()}",
|
172
|
-
end="\r\n",
|
173
|
-
file=file_descriptor,
|
174
|
-
)
|
175
|
-
except TypeError:
|
176
|
-
...
|
177
|
-
|
178
|
-
try:
|
179
|
-
if len(hisname):
|
180
|
-
print(
|
181
|
-
f"<NAME:{len(hisname)}>{hisname.title()}",
|
182
|
-
end="\r\n",
|
183
|
-
file=file_descriptor,
|
184
|
-
)
|
185
|
-
except TypeError:
|
186
|
-
...
|
187
|
-
|
188
|
-
try:
|
189
|
-
print(
|
190
|
-
f"<MODE:{len(themode)}>{themode}",
|
191
|
-
end="\r\n",
|
192
|
-
file=file_descriptor,
|
193
|
-
)
|
194
|
-
except TypeError:
|
195
|
-
...
|
196
|
-
|
197
|
-
try:
|
198
|
-
print(
|
199
|
-
f"<FREQ:{len(frequency)}>{frequency}",
|
200
|
-
end="\r\n",
|
201
|
-
file=file_descriptor,
|
202
|
-
)
|
203
|
-
except TypeError:
|
204
|
-
...
|
205
|
-
|
206
|
-
try:
|
207
|
-
print(
|
208
|
-
f"<RST_SENT:{len(sentrst)}>{sentrst}",
|
209
|
-
end="\r\n",
|
210
|
-
file=file_descriptor,
|
211
|
-
)
|
212
|
-
except TypeError:
|
213
|
-
...
|
214
|
-
|
215
|
-
try:
|
216
|
-
print(
|
217
|
-
f"<RST_RCVD:{len(rcvrst)}>{rcvrst}",
|
218
|
-
end="\r\n",
|
219
|
-
file=file_descriptor,
|
220
|
-
)
|
221
|
-
except TypeError:
|
222
|
-
...
|
223
|
-
|
224
|
-
try:
|
225
|
-
if sentnr != "0":
|
226
|
-
print(
|
227
|
-
f"<STX_STRING:{len(sentnr)}>{sentnr}",
|
228
|
-
end="\r\n",
|
229
|
-
file=file_descriptor,
|
230
|
-
)
|
231
|
-
except TypeError:
|
232
|
-
...
|
233
|
-
|
234
|
-
try:
|
235
|
-
if rcvnr != "0":
|
236
|
-
print(
|
237
|
-
f"<SRX_STRING:{len(rcvnr)}>{rcvnr}",
|
238
|
-
end="\r\n",
|
239
|
-
file=file_descriptor,
|
240
|
-
)
|
241
|
-
except TypeError:
|
242
|
-
...
|
243
|
-
|
244
|
-
try:
|
245
|
-
if len(grid) > 1:
|
246
|
-
print(
|
247
|
-
f"<GRIDSQUARE:{len(grid)}>{grid}",
|
248
|
-
end="\r\n",
|
249
|
-
file=file_descriptor,
|
250
|
-
)
|
251
|
-
except TypeError:
|
252
|
-
...
|
253
|
-
|
254
|
-
try:
|
255
|
-
if len(comment):
|
256
|
-
print(
|
257
|
-
f"<COMMENT:{len(comment)}>{comment}",
|
258
|
-
end="\r\n",
|
259
|
-
file=file_descriptor,
|
260
|
-
)
|
261
|
-
except TypeError:
|
262
|
-
...
|
263
|
-
|
264
|
-
print("<EOR>", end="\r\n", file=file_descriptor)
|
265
|
-
print("", end="\r\n", file=file_descriptor)
|
266
|
-
except IOError:
|
267
|
-
...
|
268
|
-
|
269
|
-
|
270
|
-
def cabrillo(self):
|
271
|
-
"""Generates Cabrillo file. Maybe."""
|
409
|
+
output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
|
410
|
+
self.show_message_box(f"Cabrillo saved to: {filename}")
|
411
|
+
except IOError as exception:
|
412
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
413
|
+
self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
|
414
|
+
return
|
272
415
|
|
273
416
|
|
274
417
|
def recalculate_mults(self):
|
275
418
|
"""Recalculates multipliers after change in logged qso."""
|
276
419
|
|
277
420
|
|
278
|
-
|
421
|
+
def process_esm(self, new_focused_widget=None, with_enter=False):
|
422
|
+
"""ESM State Machine"""
|
423
|
+
|
424
|
+
# self.pref["run_state"]
|
425
|
+
|
426
|
+
# -----===== Assigned F-Keys =====-----
|
427
|
+
# self.esm_dict["CQ"]
|
428
|
+
# self.esm_dict["EXCH"]
|
429
|
+
# self.esm_dict["QRZ"]
|
430
|
+
# self.esm_dict["AGN"]
|
431
|
+
# self.esm_dict["HISCALL"]
|
432
|
+
# self.esm_dict["MYCALL"]
|
433
|
+
# self.esm_dict["QSOB4"]
|
434
|
+
|
435
|
+
# ----==== text fields ====----
|
436
|
+
# self.callsign
|
437
|
+
# self.sent
|
438
|
+
# self.receive
|
439
|
+
# self.other_1
|
440
|
+
# self.other_2
|
441
|
+
|
442
|
+
if new_focused_widget is not None:
|
443
|
+
self.current_widget = self.inputs_dict.get(new_focused_widget)
|
444
|
+
|
445
|
+
# print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
|
446
|
+
|
447
|
+
for a_button in [
|
448
|
+
self.esm_dict["CQ"],
|
449
|
+
self.esm_dict["EXCH"],
|
450
|
+
self.esm_dict["QRZ"],
|
451
|
+
self.esm_dict["AGN"],
|
452
|
+
self.esm_dict["HISCALL"],
|
453
|
+
self.esm_dict["MYCALL"],
|
454
|
+
self.esm_dict["QSOB4"],
|
455
|
+
]:
|
456
|
+
if a_button is not None:
|
457
|
+
self.restore_button_color(a_button)
|
458
|
+
|
459
|
+
buttons_to_send = []
|
460
|
+
|
461
|
+
if self.pref.get("run_state"):
|
462
|
+
if self.current_widget == "callsign":
|
463
|
+
if len(self.callsign.text()) < 3:
|
464
|
+
self.make_button_green(self.esm_dict["CQ"])
|
465
|
+
buttons_to_send.append(self.esm_dict["CQ"])
|
466
|
+
elif len(self.callsign.text()) > 2:
|
467
|
+
self.make_button_green(self.esm_dict["HISCALL"])
|
468
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
469
|
+
buttons_to_send.append(self.esm_dict["HISCALL"])
|
470
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
471
|
+
|
472
|
+
elif self.current_widget in ["other_2"]:
|
473
|
+
if self.other_2.text() == "":
|
474
|
+
self.make_button_green(self.esm_dict["AGN"])
|
475
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
476
|
+
else:
|
477
|
+
self.make_button_green(self.esm_dict["QRZ"])
|
478
|
+
buttons_to_send.append(self.esm_dict["QRZ"])
|
479
|
+
buttons_to_send.append("LOGIT")
|
480
|
+
|
481
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
482
|
+
for button in buttons_to_send:
|
483
|
+
if button:
|
484
|
+
if button == "LOGIT":
|
485
|
+
self.save_contact()
|
486
|
+
continue
|
487
|
+
if button == self.esm_dict["HISCALL"]:
|
488
|
+
self.process_function_key(button, rttysendrx=False)
|
489
|
+
continue
|
490
|
+
self.process_function_key(button)
|
491
|
+
else:
|
492
|
+
if self.current_widget == "callsign":
|
493
|
+
if len(self.callsign.text()) > 2:
|
494
|
+
self.make_button_green(self.esm_dict["MYCALL"])
|
495
|
+
buttons_to_send.append(self.esm_dict["MYCALL"])
|
496
|
+
|
497
|
+
elif self.current_widget in ["other_2"]:
|
498
|
+
if self.other_2.text() == "":
|
499
|
+
self.make_button_green(self.esm_dict["AGN"])
|
500
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
501
|
+
else:
|
502
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
503
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
504
|
+
buttons_to_send.append("LOGIT")
|
505
|
+
|
506
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
507
|
+
for button in buttons_to_send:
|
508
|
+
if button:
|
509
|
+
if button == "LOGIT":
|
510
|
+
self.save_contact()
|
511
|
+
continue
|
512
|
+
self.process_function_key(button)
|
513
|
+
|
514
|
+
|
515
|
+
def populate_history_info_line(self):
|
516
|
+
result = self.database.fetch_call_history(self.callsign.text())
|
517
|
+
if result:
|
518
|
+
self.history_info.setText(
|
519
|
+
f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('State', '')}, {result.get('UserText','...')}"
|
520
|
+
)
|
521
|
+
else:
|
522
|
+
self.history_info.setText("")
|
523
|
+
|
524
|
+
|
525
|
+
def check_call_history(self):
|
526
|
+
""""""
|
527
|
+
result = self.database.fetch_call_history(self.callsign.text())
|
528
|
+
if result:
|
529
|
+
self.history_info.setText(f"{result.get('UserText','')}")
|
530
|
+
if self.other_2.text() == "":
|
531
|
+
self.other_2.setText(f"{result.get('State', '')}")
|
279
532
|
|
280
533
|
|
281
534
|
def get_mults(self):
|
282
535
|
""""""
|
283
|
-
|
284
536
|
mults = {}
|
285
|
-
mults["
|
537
|
+
mults["country"], mults["state"] = show_mults(self, rtc=True)
|
286
538
|
return mults
|
287
539
|
|
288
540
|
|
@@ -183,14 +183,18 @@ def process_esm(self, new_focused_widget=None, with_enter=False):
|
|
183
183
|
buttons_to_send.append(self.esm_dict["HISCALL"])
|
184
184
|
buttons_to_send.append(self.esm_dict["EXCH"])
|
185
185
|
|
186
|
+
# elif self.current_widget in ["other_1", "other_2"]:
|
187
|
+
# if self.other_2.text() == "" and self.other_1.text() == "":
|
188
|
+
# self.make_button_green(self.esm_dict["AGN"])
|
189
|
+
# buttons_to_send.append(self.esm_dict["AGN"])
|
190
|
+
# else:
|
191
|
+
# self.make_button_green(self.esm_dict["QRZ"])
|
192
|
+
# buttons_to_send.append(self.esm_dict["QRZ"])
|
193
|
+
# buttons_to_send.append("LOGIT")
|
194
|
+
|
186
195
|
elif self.current_widget in ["other_1", "other_2"]:
|
187
|
-
|
188
|
-
|
189
|
-
buttons_to_send.append(self.esm_dict["AGN"])
|
190
|
-
else:
|
191
|
-
self.make_button_green(self.esm_dict["QRZ"])
|
192
|
-
buttons_to_send.append(self.esm_dict["QRZ"])
|
193
|
-
buttons_to_send.append("LOGIT")
|
196
|
+
buttons_to_send.append("LOGIT")
|
197
|
+
|
194
198
|
|
195
199
|
if with_enter is True and bool(len(buttons_to_send)):
|
196
200
|
for button in buttons_to_send:
|
@@ -205,14 +209,19 @@ def process_esm(self, new_focused_widget=None, with_enter=False):
|
|
205
209
|
self.make_button_green(self.esm_dict["MYCALL"])
|
206
210
|
buttons_to_send.append(self.esm_dict["MYCALL"])
|
207
211
|
|
212
|
+
# elif self.current_widget in ["other_1", "other_2"]:
|
213
|
+
# if self.other_2.text() == "" and self.other_1.text() == "":
|
214
|
+
# self.make_button_green(self.esm_dict["AGN"])
|
215
|
+
# buttons_to_send.append(self.esm_dict["AGN"])
|
216
|
+
# else:
|
217
|
+
# self.make_button_green(self.esm_dict["EXCH"])
|
218
|
+
# buttons_to_send.append(self.esm_dict["EXCH"])
|
219
|
+
# buttons_to_send.append("LOGIT")
|
220
|
+
|
208
221
|
elif self.current_widget in ["other_1", "other_2"]:
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
else:
|
213
|
-
self.make_button_green(self.esm_dict["EXCH"])
|
214
|
-
buttons_to_send.append(self.esm_dict["EXCH"])
|
215
|
-
buttons_to_send.append("LOGIT")
|
222
|
+
buttons_to_send.append("LOGIT")
|
223
|
+
|
224
|
+
|
216
225
|
if with_enter is True and bool(len(buttons_to_send)):
|
217
226
|
for button in buttons_to_send:
|
218
227
|
if button:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version:
|
3
|
+
Version: 25.1.1
|
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
|
@@ -214,6 +214,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
214
214
|
- ARRL 160M
|
215
215
|
- ARRL DX CW, SSB
|
216
216
|
- ARRL Field Day
|
217
|
+
- ARRL RTTY Roundup
|
217
218
|
- ARRL Sweepstakes CW, SSB
|
218
219
|
- ARRL VHF January, June, September
|
219
220
|
- CQ 160 CW, SSB
|
@@ -239,21 +240,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
239
240
|
|
240
241
|
## Recent Changes (Polishing the Turd)
|
241
242
|
|
242
|
-
- [
|
243
|
-
- [24-12-14] Changed method of detecting fldigi QSOs. See docs.
|
244
|
-
- [24-12-12] Add a try exception for a unicode decode error.
|
245
|
-
- [24-12-11-1] Add RTC to RAC Canada Day, ARRL VHF, ARRL Field Day, ARRL SS, ARRL DX, 10 10
|
246
|
-
- [24-12-11] Add RTC to IARU HF, IARU Field Day, DARC XMAS, CQ WW, CQ WPX
|
247
|
-
- [24-12-9] Add RTC to Winter Field Day, Stew Perry, REF, RAEM, NAQP, LZ-DX, JIDX
|
248
|
-
- [24-12-8-2] Add RTC to ARRL 10M, Tweaked cabrillo file output.
|
249
|
-
- [24-12-8-1] Changed cabrillo names for Weekly RTTY, CW Ops CWT and K1USN SST.
|
250
|
-
- [24-12-8] Fix: Weekly RTTY mults. Add RTC to Weekly RTTY.
|
251
|
-
- [24-12-6] Add RTC to K1USN.
|
252
|
-
-[24-12-5-1] ARRL 160 gets rtc.
|
253
|
-
- [24-12-5] Add 'real time' score posting to external sites.
|
254
|
-
- [24-12-4] Merged PR from @alduhoo Add STATION_CALLSIGN field to ADIF output
|
255
|
-
- [24-12-3-1] Adding ARRL 160
|
256
|
-
- [24-12-3] Add button to bandmap to delete marked spots.
|
243
|
+
- [25-1-1] Added ARRL RTTY RU.
|
257
244
|
|
258
245
|
See [CHANGELOG.md](CHANGELOG.md) for prior changes.
|
259
246
|
|
@@ -688,6 +675,7 @@ You can include a limited set of substitution instructions.
|
|
688
675
|
| {SNT} | Sends 5nn (cw) or 599 (ssb) |
|
689
676
|
| {SENTNR} | Sends whats in the SentNR field. |
|
690
677
|
| {EXCH} | Sends what's in the Sent Exchange field when contest is defined. |
|
678
|
+
| {LOGIT} | Log the contact after macro pressed. |
|
691
679
|
| '#' | Sends serial number. |
|
692
680
|
|
693
681
|
### Macro use with voice
|
@@ -1,5 +1,5 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=mMKDAkCWN5gF4SM7-wod-njba7RDw2Zfr-pNI5q7FxY,144819
|
3
3
|
not1mm/bandmap.py,sha256=zD3aUf36NVQCy0plAcZLNxYhSEM9xZ8J1Cu9vrcFPYA,31136
|
4
4
|
not1mm/checkwindow.py,sha256=VFAcKYTcoWhmIf91chwY6tyao9FQMWPiUkgDDkkWaog,9670
|
5
5
|
not1mm/fsutils.py,sha256=ukHKxKTeNKxKwqRaJjtzRShL4X5Xl0jRBbADyy3Ifp8,1701
|
@@ -32,7 +32,7 @@ not1mm/data/k6gte.not1mm-64.png,sha256=6ku45Gq1g5ezh04F07osoKRtanb3e4kbx5XdIEh3N
|
|
32
32
|
not1mm/data/logwindow.ui,sha256=f7vULj96tHIQuR1nJMyvPHHcmVgzkhv9D1isyojsnFU,1458
|
33
33
|
not1mm/data/logwindowx.ui,sha256=CwpI-h7cI1yqyldH9quKftsdHL5lTyL9ABOcf80nfqc,1632
|
34
34
|
not1mm/data/main.ui,sha256=pI-70TYESe85ENkRH8l1DXnKDOkwYqKXUdMk6KYaN50,63193
|
35
|
-
not1mm/data/new_contest.ui,sha256=
|
35
|
+
not1mm/data/new_contest.ui,sha256=Sc8HquH7BK0bmkypeK_HbfhArE6yaw02WONOUlRdmuA,23953
|
36
36
|
not1mm/data/not1mm.html,sha256=c9-mfjMwDt4f5pySUruz2gREW33CQ2_rCddM2z5CZQo,23273
|
37
37
|
not1mm/data/opon.ui,sha256=QDicqAk2lORG2UWsHa6jHlsGn6uzrrI2R4HSAocpPes,2258
|
38
38
|
not1mm/data/pickcontest.ui,sha256=4hPBszCglObThx_eIWtmK9CEcbr7WBjbB1rKZdI-o3I,1707
|
@@ -114,7 +114,7 @@ not1mm/lib/plugin_common.py,sha256=-cvXtEAUgZ7GtxaNiwVdHbZ-7wEBeoMPRZXNdCxnPyA,1
|
|
114
114
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
115
115
|
not1mm/lib/settings.py,sha256=j5lIMLHJ-eqIaVr_QhI82gkbOl17_C-5suRkWbHYET8,14717
|
116
116
|
not1mm/lib/super_check_partial.py,sha256=hwT2NRwobu0PLDyw6ltmbmcAtGBD02CKGFbgGWjXMqA,2334
|
117
|
-
not1mm/lib/version.py,sha256=
|
117
|
+
not1mm/lib/version.py,sha256=CqwwZgPnGFUAeenWk7Ey1p5bFWF45s1jdEZbwTt9guc,47
|
118
118
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
119
119
|
not1mm/plugins/10_10_fall_cw.py,sha256=5QUyGMvGBC-HxcY_z9QbfuxSg3f7p6C9K4qhTxgZE7k,14719
|
120
120
|
not1mm/plugins/10_10_spring_cw.py,sha256=XjYFM263WYyG6nVQzPObW4YC7Z9L93rixSOcVsxPvH4,14722
|
@@ -126,7 +126,7 @@ not1mm/plugins/arrl_160m.py,sha256=9SHfxjTX_LECOYDsICnoX_Q133atojsJbmFapehleYE,2
|
|
126
126
|
not1mm/plugins/arrl_dx_cw.py,sha256=4UMN1HWPNbkz2T6K33GJ0wUkE7yq46C57C6BUwbu5cs,18014
|
127
127
|
not1mm/plugins/arrl_dx_ssb.py,sha256=X2C0hPY45_CvA2_97O0NAw3HF4QGgs5o0WVTlwMMme8,18017
|
128
128
|
not1mm/plugins/arrl_field_day.py,sha256=X7BLs87ikQEm1xuh2sSj-8KcFA9pqnut6uFGM2xJe7c,16743
|
129
|
-
not1mm/plugins/arrl_rtty_ru.py,sha256=
|
129
|
+
not1mm/plugins/arrl_rtty_ru.py,sha256=ag1Man_y1A5gyWcU98TcXbOL33nVdPpRXrzotI7Snkc,17061
|
130
130
|
not1mm/plugins/arrl_ss_cw.py,sha256=uv71xstpmBiDTyU5zF8pe6UIS-5v6hi0aMBksbPvCzc,17458
|
131
131
|
not1mm/plugins/arrl_ss_phone.py,sha256=V3dgBXoLb3mWMbb1s-ovx-SoUBL5IxE8omkQbP7siwk,16794
|
132
132
|
not1mm/plugins/arrl_vhf_jan.py,sha256=SDk0gGg00XPuCpl6DsyozAnEoOBgiS1wMUhDPPB5RsM,20267
|
@@ -143,7 +143,7 @@ not1mm/plugins/cq_ww_rtty.py,sha256=RJywVSNujM4CxxTRCGKXhjmbz6OMzGR5eHSAmQcT6Pc,
|
|
143
143
|
not1mm/plugins/cq_ww_ssb.py,sha256=uRMXaTfkIt7QJxQBaBAvc2fmT6ak26SzBBezd5k_hMc,17991
|
144
144
|
not1mm/plugins/cwt.py,sha256=7BoKVrIywlHpP4f4_mrUyWKVsK6vujreb8jDWyXrwUc,17530
|
145
145
|
not1mm/plugins/darc_xmas.py,sha256=p9JbOJlEoOsB86E5ciHdrY7L-10tnNEWuTxq9EfCNBM,18907
|
146
|
-
not1mm/plugins/general_logging.py,sha256=
|
146
|
+
not1mm/plugins/general_logging.py,sha256=gpZhoBr9fKpcTrefufmtvMHVrzlSqUsch64O8-oKhls,6915
|
147
147
|
not1mm/plugins/helvetia.py,sha256=CnAq0mXZC2tO_pEwIoDN6MHAv95NPcLRvG1gnjfAcF8,20032
|
148
148
|
not1mm/plugins/iaru_fieldday_r1_cw.py,sha256=lueTnK50yRSMqASlktrhuFOJkSBDsQw4OyT9eYwpugU,17155
|
149
149
|
not1mm/plugins/iaru_fieldday_r1_ssb.py,sha256=1lYxeo4j_piiFZ_db-vHIHT5c1jSeFPBuw6yf1kur6Y,17159
|
@@ -163,9 +163,9 @@ not1mm/plugins/ref_ssb.py,sha256=vfS9-mcnbw2znRvU4jh20JqI9BXap8jV65OV5mbCkCk,209
|
|
163
163
|
not1mm/plugins/stew_perry_topband.py,sha256=D1hekmMbx-i4BhaP2uzOK3OzaVVMMdgcN3RmfweNqHo,15341
|
164
164
|
not1mm/plugins/weekly_rtty.py,sha256=huZszbZsIh4vF3cP80UyPzy3qxIoHdEiT1b6KuvwgYc,20083
|
165
165
|
not1mm/plugins/winter_field_day.py,sha256=cSCFwy1LOoDDA9Zs1LHRG3r8spDMSKDisxyPxnVrLjw,15149
|
166
|
-
not1mm-
|
167
|
-
not1mm-
|
168
|
-
not1mm-
|
169
|
-
not1mm-
|
170
|
-
not1mm-
|
171
|
-
not1mm-
|
166
|
+
not1mm-25.1.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
167
|
+
not1mm-25.1.1.dist-info/METADATA,sha256=qmgKembLLFua5erWr8T0EjHT0Ah_ZYtiZ3tnnVhVbBk,35673
|
168
|
+
not1mm-25.1.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
169
|
+
not1mm-25.1.1.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
170
|
+
not1mm-25.1.1.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
171
|
+
not1mm-25.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|