not1mm 24.12.29__py3-none-any.whl → 25.1.6__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.
@@ -237,6 +237,11 @@
237
237
  <string>ARRL FIELD DAY</string>
238
238
  </property>
239
239
  </item>
240
+ <item>
241
+ <property name="text">
242
+ <string>ARRL RTTY RU</string>
243
+ </property>
244
+ </item>
240
245
  <item>
241
246
  <property name="text">
242
247
  <string>ARRL SS CW</string>
not1mm/lib/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.12.29"
3
+ __version__ = "25.1.6"
@@ -1,19 +1,54 @@
1
- """ARRL plugin"""
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
+ """
2
31
 
3
32
  # pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member
4
33
 
5
34
  import datetime
6
- from decimal import Decimal
7
- from pathlib import Path
35
+ import logging
8
36
 
37
+ from pathlib import Path
9
38
  from PyQt6 import QtWidgets
10
- from not1mm.lib.plugin_common import online_score_xml
11
39
 
12
- EXCHANGE_HINT = ""
40
+ from not1mm.lib.ham_utility import get_logged_band
41
+ from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
42
+ from not1mm.lib.version import __version__
43
+
44
+ logger = logging.getLogger(__name__)
13
45
 
14
- name = "ARRL RTTY Round Up"
46
+ EXCHANGE_HINT = "State/Province or #"
47
+
48
+ name = "ARRL RTTY Roundup"
49
+ mode = "RTTY" # CW SSB BOTH RTTY
15
50
  cabrillo_name = "ARRL-RTTY"
16
- mode = "BOTH" # CW SSB BOTH RTTY
51
+
17
52
  columns = [
18
53
  "YYYY-MM-DD HH:MM:SS",
19
54
  "Call",
@@ -22,23 +57,13 @@ columns = [
22
57
  "Rcv",
23
58
  "SentNr",
24
59
  "RcvNr",
25
- "Exchange1",
26
- "CK",
27
- "Prec",
28
- "Sect",
29
- "WPX",
30
- "Power",
31
- "M1",
32
- "ZN",
33
- "M2",
34
- "PFX",
35
60
  "PTS",
36
- "Name",
37
- "Comment",
38
61
  ]
39
62
 
63
+ advance_on_space = [True, True, True, True, True]
64
+
40
65
  # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
41
- dupe_type = 4
66
+ dupe_type = 2
42
67
 
43
68
 
44
69
  def init_contest(self):
@@ -46,10 +71,23 @@ def init_contest(self):
46
71
  set_tab_next(self)
47
72
  set_tab_prev(self)
48
73
  interface(self)
74
+ self.next_field = self.other_2
49
75
 
50
76
 
51
77
  def interface(self):
52
78
  """Setup user interface"""
79
+ self.field1.show()
80
+ self.field2.show()
81
+ self.field3.show()
82
+ self.field4.show()
83
+ self.snt_label.setText("SNT")
84
+ self.field1.setAccessibleName("RST Sent")
85
+ # label = self.field3.findChild(QtWidgets.QLabel)
86
+ self.other_label.setText("SentNR")
87
+ self.field3.setAccessibleName("Sent Number")
88
+ # label = self.field4.findChild(QtWidgets.QLabel)
89
+ self.exch_label.setText("State|Prov|SN")
90
+ self.field4.setAccessibleName("State Province or Serial Number")
53
91
 
54
92
 
55
93
  def reset_label(self):
@@ -78,8 +116,22 @@ def set_tab_prev(self):
78
116
  }
79
117
 
80
118
 
119
+ def validate(self):
120
+ """doc"""
121
+ # exchange = self.other_2.text().upper().split()
122
+ # if len(exchange) == 3:
123
+ # if exchange[0].isalpha() and exchange[1].isdigit() and exchange[2].isalpha():
124
+ # return True
125
+ # return False
126
+ return True
127
+
128
+
81
129
  def set_contact_vars(self):
82
130
  """Contest Specific"""
131
+ self.contact["SNT"] = self.sent.text()
132
+ self.contact["RCV"] = self.receive.text()
133
+ self.contact["NR"] = self.other_2.text().upper()
134
+ self.contact["SentNr"] = self.other_1.text()
83
135
 
84
136
 
85
137
  def predupe(self):
@@ -87,15 +139,51 @@ def predupe(self):
87
139
 
88
140
 
89
141
  def prefill(self):
90
- """Fill SentNR"""
142
+ """Fill sentnr"""
143
+ result = self.database.get_serial()
144
+ serial_nr = str(result.get("serial_nr", "1")).zfill(3)
145
+ if serial_nr == "None":
146
+ serial_nr = "001"
147
+
148
+ exchange = self.contest_settings.get("SentExchange", "").replace("#", serial_nr)
149
+ if len(self.other_1.text()) == 0:
150
+ self.other_1.setText(exchange)
91
151
 
92
152
 
93
153
  def points(self):
94
154
  """Calc point"""
155
+ return 1
95
156
 
96
157
 
97
158
  def show_mults(self, rtc=None):
98
159
  """Return display string for mults"""
160
+ # CountryPrefix, integer
161
+
162
+ us_ve = 0
163
+ dx = 0
164
+
165
+ sql = (
166
+ "select count(DISTINCT(NR || ':' || Mode)) as mult_count "
167
+ f"from dxlog where ContestNR = {self.database.current_contest} and typeof(NR) = 'text';"
168
+ )
169
+ result = self.database.exec_sql(sql)
170
+ if result:
171
+ us_ve = result.get("mult_count", 0)
172
+
173
+ # DX
174
+ sql = (
175
+ "select count(DISTINCT(CountryPrefix || ':' || Mode)) as mult_count "
176
+ f"from dxlog where ContestNR = {self.database.current_contest} "
177
+ "and typeof(NR) = 'integer';"
178
+ )
179
+ result = self.database.exec_sql(sql)
180
+ if result:
181
+ dx = result.get("mult_count", 0)
182
+
183
+ if rtc is not None:
184
+ return dx, us_ve
185
+
186
+ return us_ve + dx
99
187
 
100
188
 
101
189
  def show_qso(self):
@@ -106,186 +194,475 @@ def show_qso(self):
106
194
  return 0
107
195
 
108
196
 
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
197
  def calc_score(self):
118
198
  """Return calculated score"""
119
- result = self.database.fetch_points()
199
+ # Multipliers: Each US State + DC once per mode
200
+ _points = get_points(self)
201
+ _mults = show_mults(self)
202
+ _power_mult = 1
203
+ # if self.contest_settings.get("PowerCategory", "") == "QRP":
204
+ # _power_mult = 2
205
+ return _points * _power_mult * _mults
120
206
 
121
207
 
122
208
  def adif(self):
123
- """
124
- Creates an ADIF file of the contacts made.
125
- """
209
+ """Call the generate ADIF function"""
210
+ gen_adif(self, cabrillo_name)
211
+
212
+
213
+ def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
214
+ """"""
215
+ print(
216
+ line_to_output.encode(file_encoding, errors="ignore").decode(),
217
+ end=ending,
218
+ file=file_descriptor,
219
+ )
220
+
221
+
222
+ def cabrillo(self, file_encoding):
223
+ """Generates Cabrillo file. Maybe."""
224
+ # https://www.cqwpx.com/cabrillo.htm
225
+ logger.debug("******Cabrillo*****")
226
+ logger.debug("Station: %s", f"{self.station}")
227
+ logger.debug("Contest: %s", f"{self.contest_settings}")
126
228
  now = datetime.datetime.now()
127
229
  date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
128
230
  filename = (
129
231
  str(Path.home())
130
232
  + "/"
131
- + f"{self.station.get('Call').upper()}_{cabrillo_name}_{date_time}.adi"
233
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
132
234
  )
235
+ logger.debug("%s", filename)
133
236
  log = self.database.fetch_all_contacts_asc()
134
237
  try:
135
- with open(filename, "w", encoding="utf-8") as file_descriptor:
136
- print("<ADIF_VER:5>2.2.0", end="\r\n", file=file_descriptor)
137
- print("<EOH>", end="\r\n", file=file_descriptor)
238
+ with open(filename, "w", encoding=file_encoding) as file_descriptor:
239
+ output_cabrillo_line(
240
+ "START-OF-LOG: 3.0",
241
+ "\r\n",
242
+ file_descriptor,
243
+ file_encoding,
244
+ )
245
+ output_cabrillo_line(
246
+ f"CREATED-BY: Not1MM v{__version__}",
247
+ "\r\n",
248
+ file_descriptor,
249
+ file_encoding,
250
+ )
251
+ output_cabrillo_line(
252
+ f"CONTEST: {cabrillo_name}",
253
+ "\r\n",
254
+ file_descriptor,
255
+ file_encoding,
256
+ )
257
+ if self.station.get("Club", ""):
258
+ output_cabrillo_line(
259
+ f"CLUB: {self.station.get('Club', '')}",
260
+ "\r\n",
261
+ file_descriptor,
262
+ file_encoding,
263
+ )
264
+ output_cabrillo_line(
265
+ f"CALLSIGN: {self.station.get('Call','')}",
266
+ "\r\n",
267
+ file_descriptor,
268
+ file_encoding,
269
+ )
270
+ output_cabrillo_line(
271
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
272
+ "\r\n",
273
+ file_descriptor,
274
+ file_encoding,
275
+ )
276
+ output_cabrillo_line(
277
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
278
+ "\r\n",
279
+ file_descriptor,
280
+ file_encoding,
281
+ )
282
+ output_cabrillo_line(
283
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
284
+ "\r\n",
285
+ file_descriptor,
286
+ file_encoding,
287
+ )
288
+ output_cabrillo_line(
289
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
290
+ "\r\n",
291
+ file_descriptor,
292
+ file_encoding,
293
+ )
294
+ mode = self.contest_settings.get("ModeCategory", "")
295
+ if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
296
+ mode = "MIXED"
297
+ output_cabrillo_line(
298
+ f"CATEGORY-MODE: {mode}",
299
+ "\r\n",
300
+ file_descriptor,
301
+ file_encoding,
302
+ )
303
+ output_cabrillo_line(
304
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
305
+ "\r\n",
306
+ file_descriptor,
307
+ file_encoding,
308
+ )
309
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
310
+ output_cabrillo_line(
311
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
312
+ "\r\n",
313
+ file_descriptor,
314
+ file_encoding,
315
+ )
316
+ output_cabrillo_line(
317
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
318
+ "\r\n",
319
+ file_descriptor,
320
+ file_encoding,
321
+ )
322
+ output_cabrillo_line(
323
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
324
+ "\r\n",
325
+ file_descriptor,
326
+ file_encoding,
327
+ )
328
+
329
+ output_cabrillo_line(
330
+ f"CLAIMED-SCORE: {calc_score(self)}",
331
+ "\r\n",
332
+ file_descriptor,
333
+ file_encoding,
334
+ )
335
+ ops = f"@{self.station.get('Call','')}"
336
+ list_of_ops = self.database.get_ops()
337
+ for op in list_of_ops:
338
+ ops += f", {op.get('Operator', '')}"
339
+ output_cabrillo_line(
340
+ f"OPERATORS: {ops}",
341
+ "\r\n",
342
+ file_descriptor,
343
+ file_encoding,
344
+ )
345
+ output_cabrillo_line(
346
+ f"NAME: {self.station.get('Name', '')}",
347
+ "\r\n",
348
+ file_descriptor,
349
+ file_encoding,
350
+ )
351
+ output_cabrillo_line(
352
+ f"ADDRESS: {self.station.get('Street1', '')}",
353
+ "\r\n",
354
+ file_descriptor,
355
+ file_encoding,
356
+ )
357
+ output_cabrillo_line(
358
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
359
+ "\r\n",
360
+ file_descriptor,
361
+ file_encoding,
362
+ )
363
+ output_cabrillo_line(
364
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
365
+ "\r\n",
366
+ file_descriptor,
367
+ file_encoding,
368
+ )
369
+ output_cabrillo_line(
370
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
371
+ "\r\n",
372
+ file_descriptor,
373
+ file_encoding,
374
+ )
375
+ output_cabrillo_line(
376
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
377
+ "\r\n",
378
+ file_descriptor,
379
+ file_encoding,
380
+ )
381
+ output_cabrillo_line(
382
+ f"EMAIL: {self.station.get('Email', '')}",
383
+ "\r\n",
384
+ file_descriptor,
385
+ file_encoding,
386
+ )
138
387
  for contact in log:
139
- hiscall = contact.get("Call", "")
140
- hisname = contact.get("Name", "")
141
- the_date_and_time = contact.get("TS")
142
- # band = contact.get("Band")
143
- themode = contact.get("Mode")
144
- frequency = str(Decimal(str(contact.get("Freq", 0))) / 1000)
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", "")
388
+ the_date_and_time = contact.get("TS", "")
389
+ themode = contact.get("Mode", "")
390
+ if themode == "LSB" or themode == "USB":
391
+ themode = "PH"
392
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
393
+
151
394
  loggeddate = the_date_and_time[:10]
152
395
  loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
153
- print(
154
- f"<QSO_DATE:{len(''.join(loggeddate.split('-')))}:d>"
155
- f"{''.join(loggeddate.split('-'))}",
156
- end="\r\n",
157
- file=file_descriptor,
396
+ output_cabrillo_line(
397
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
398
+ f"{contact.get('StationPrefix', '').ljust(13)} "
399
+ f"{str(contact.get('SNT', '')).ljust(3)} "
400
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
401
+ f"{contact.get('Call', '').ljust(13)} "
402
+ f"{str(contact.get('RCV', '')).ljust(3)} "
403
+ f"{str(contact.get('NR', '')).ljust(6)}",
404
+ "\r\n",
405
+ file_descriptor,
406
+ file_encoding,
158
407
  )
159
-
160
- try:
161
- print(
162
- f"<TIME_ON:{len(loggedtime)}>{loggedtime}",
163
- end="\r\n",
164
- file=file_descriptor,
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."""
408
+ output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
409
+ self.show_message_box(f"Cabrillo saved to: {filename}")
410
+ except IOError as exception:
411
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
412
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
413
+ return
272
414
 
273
415
 
274
416
  def recalculate_mults(self):
275
417
  """Recalculates multipliers after change in logged qso."""
276
418
 
277
419
 
278
- # States/Prov. DXCC state country
420
+ def process_esm(self, new_focused_widget=None, with_enter=False):
421
+ """ESM State Machine"""
422
+
423
+ # self.pref["run_state"]
424
+
425
+ # -----===== Assigned F-Keys =====-----
426
+ # self.esm_dict["CQ"]
427
+ # self.esm_dict["EXCH"]
428
+ # self.esm_dict["QRZ"]
429
+ # self.esm_dict["AGN"]
430
+ # self.esm_dict["HISCALL"]
431
+ # self.esm_dict["MYCALL"]
432
+ # self.esm_dict["QSOB4"]
433
+
434
+ # ----==== text fields ====----
435
+ # self.callsign
436
+ # self.sent
437
+ # self.receive
438
+ # self.other_1
439
+ # self.other_2
440
+
441
+ if new_focused_widget is not None:
442
+ self.current_widget = self.inputs_dict.get(new_focused_widget)
443
+
444
+ # print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
445
+
446
+ for a_button in [
447
+ self.esm_dict["CQ"],
448
+ self.esm_dict["EXCH"],
449
+ self.esm_dict["QRZ"],
450
+ self.esm_dict["AGN"],
451
+ self.esm_dict["HISCALL"],
452
+ self.esm_dict["MYCALL"],
453
+ self.esm_dict["QSOB4"],
454
+ ]:
455
+ if a_button is not None:
456
+ self.restore_button_color(a_button)
457
+
458
+ buttons_to_send = []
459
+
460
+ if self.pref.get("run_state"):
461
+ if self.current_widget == "callsign":
462
+ if len(self.callsign.text()) < 3:
463
+ self.make_button_green(self.esm_dict["CQ"])
464
+ buttons_to_send.append(self.esm_dict["CQ"])
465
+ elif len(self.callsign.text()) > 2:
466
+ self.make_button_green(self.esm_dict["HISCALL"])
467
+ self.make_button_green(self.esm_dict["EXCH"])
468
+ buttons_to_send.append(self.esm_dict["HISCALL"])
469
+ buttons_to_send.append(self.esm_dict["EXCH"])
470
+
471
+ elif self.current_widget in ["other_2"]:
472
+ if self.other_2.text() == "":
473
+ self.make_button_green(self.esm_dict["AGN"])
474
+ buttons_to_send.append(self.esm_dict["AGN"])
475
+ else:
476
+ self.make_button_green(self.esm_dict["QRZ"])
477
+ buttons_to_send.append(self.esm_dict["QRZ"])
478
+ buttons_to_send.append("LOGIT")
479
+
480
+ if with_enter is True and bool(len(buttons_to_send)):
481
+ for button in buttons_to_send:
482
+ if button:
483
+ if button == "LOGIT":
484
+ self.save_contact()
485
+ continue
486
+ if button == self.esm_dict["HISCALL"]:
487
+ self.process_function_key(button, rttysendrx=False)
488
+ continue
489
+ self.process_function_key(button)
490
+ else:
491
+ if self.current_widget == "callsign":
492
+ if len(self.callsign.text()) > 2:
493
+ self.make_button_green(self.esm_dict["MYCALL"])
494
+ buttons_to_send.append(self.esm_dict["MYCALL"])
495
+
496
+ elif self.current_widget in ["other_2"]:
497
+ if self.other_2.text() == "":
498
+ self.make_button_green(self.esm_dict["AGN"])
499
+ buttons_to_send.append(self.esm_dict["AGN"])
500
+ else:
501
+ self.make_button_green(self.esm_dict["EXCH"])
502
+ buttons_to_send.append(self.esm_dict["EXCH"])
503
+ buttons_to_send.append("LOGIT")
504
+
505
+ if with_enter is True and bool(len(buttons_to_send)):
506
+ for button in buttons_to_send:
507
+ if button:
508
+ if button == "LOGIT":
509
+ self.save_contact()
510
+ continue
511
+ self.process_function_key(button)
512
+
513
+
514
+ def populate_history_info_line(self):
515
+ result = self.database.fetch_call_history(self.callsign.text())
516
+ if result:
517
+ self.history_info.setText(
518
+ f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('State', '')}, {result.get('UserText','...')}"
519
+ )
520
+ else:
521
+ self.history_info.setText("")
279
522
 
280
523
 
281
- def get_mults(self):
524
+ def check_call_history(self):
282
525
  """"""
526
+ result = self.database.fetch_call_history(self.callsign.text())
527
+ if result:
528
+ self.history_info.setText(f"{result.get('UserText','')}")
529
+ if self.other_2.text() == "":
530
+ self.other_2.setText(f"{result.get('State', '')}")
283
531
 
532
+
533
+ def get_mults(self):
534
+ """"""
284
535
  mults = {}
285
- mults["state"], mults["country"] = show_mults(self, rtc=True)
536
+ mults["country"], mults["state"] = show_mults(self, rtc=True)
286
537
  return mults
287
538
 
288
539
 
289
540
  def just_points(self):
290
541
  """"""
291
542
  return get_points(self)
543
+
544
+
545
+ def set_self(the_outie):
546
+ """..."""
547
+ globals()["ALTEREGO"] = the_outie
548
+
549
+
550
+ def ft8_handler(the_packet: dict):
551
+ print(f"{the_packet=}")
552
+ """Process FT8 QSO packets
553
+ FT8
554
+ {
555
+ 'CALL': 'KE0OG',
556
+ 'GRIDSQUARE': 'DM10AT',
557
+ 'MODE': 'FT8',
558
+ 'RST_SENT': '',
559
+ 'RST_RCVD': '',
560
+ 'QSO_DATE': '20210329',
561
+ 'TIME_ON': '183213',
562
+ 'QSO_DATE_OFF': '20210329',
563
+ 'TIME_OFF': '183213',
564
+ 'BAND': '20M',
565
+ 'FREQ': '14.074754',
566
+ 'STATION_CALLSIGN': 'K6GTE',
567
+ 'MY_GRIDSQUARE': 'DM13AT',
568
+ 'CONTEST_ID': 'ARRL-FIELD-DAY',
569
+ 'SRX_STRING': '1D UT',
570
+ 'CLASS': '1D',
571
+ 'ARRL_SECT': 'UT'
572
+ }
573
+ FlDigi
574
+ {
575
+ 'CALL': 'K5TUS',
576
+ 'MODE': 'RTTY',
577
+ 'FREQ': '14.068415',
578
+ 'BAND': '20M',
579
+ 'QSO_DATE': '20250103',
580
+ 'TIME_ON': '2359',
581
+ 'QSO_DATE_OFF': '20250103',
582
+ 'TIME_OFF': '2359',
583
+ 'NAME': '',
584
+ 'QTH': '',
585
+ 'STATE': 'ORG',
586
+ 'VE_PROV': '',
587
+ 'COUNTRY': 'USA',
588
+ 'RST_SENT': '599',
589
+ 'RST_RCVD': '599',
590
+ 'TX_PWR': '0',
591
+ 'CNTY': '',
592
+ 'DXCC': '',
593
+ 'CQZ': '5',
594
+ 'IOTA': '',
595
+ 'CONT': '',
596
+ 'ITUZ': '',
597
+ 'GRIDSQUARE': '',
598
+ 'QSLRDATE': '',
599
+ 'QSLSDATE': '',
600
+ 'EQSLRDATE': '',
601
+ 'EQSLSDATE': '',
602
+ 'LOTWRDATE': '',
603
+ 'LOTWSDATE': '',
604
+ 'QSL_VIA': '',
605
+ 'NOTES': '',
606
+ 'SRX': '',
607
+ 'STX': '000',
608
+ 'SRX_STRING': '',
609
+ 'STX_STRING': 'CA',
610
+
611
+
612
+ 'SRX': '666',
613
+ 'STX': '000',
614
+ 'SRX_STRING': '',
615
+ 'STX_STRING': 'CA',
616
+
617
+ 'SRX': '004', 'STX': '000', 'SRX_STRING': '', 'STX_STRING': '#',
618
+
619
+ 'CLASS': '',
620
+ 'ARRL_SECT': '',
621
+ 'OPERATOR': 'K6GTE',
622
+ 'STATION_CALLSIGN': 'K6GTE',
623
+ 'MY_GRIDSQUARE': 'DM13AT',
624
+ 'MY_CITY': 'ANAHEIM, CA',
625
+ 'CHECK': '',
626
+ 'AGE': '',
627
+ 'TEN_TEN': '',
628
+ 'CWSS_PREC': '',
629
+ 'CWSS_SECTION': '',
630
+ 'CWSS_SERNO': '',
631
+ 'CWSS_CHK': ''
632
+ }
633
+
634
+ """
635
+ logger.debug(f"{the_packet=}")
636
+ if ALTEREGO is not None:
637
+ ALTEREGO.callsign.setText(the_packet.get("CALL"))
638
+ ALTEREGO.contact["Call"] = the_packet.get("CALL", "")
639
+ ALTEREGO.contact["SNT"] = the_packet.get("RST_SENT", "599")
640
+ ALTEREGO.contact["RCV"] = the_packet.get("RST_RCVD", "599")
641
+
642
+ sent_string = the_packet.get("STX_STRING", "")
643
+ if sent_string != "":
644
+ ALTEREGO.contact["SentNr"] = sent_string
645
+ ALTEREGO.other_1.setText(str(sent_string))
646
+ else:
647
+ ALTEREGO.contact["SentNr"] = the_packet.get("STX", "000")
648
+ ALTEREGO.other_1.setText(str(the_packet.get("STX", "000")))
649
+
650
+ rx_string = the_packet.get("STATE", "")
651
+ if rx_string != "":
652
+ ALTEREGO.contact["NR"] = rx_string
653
+ ALTEREGO.other_2.setText(str(rx_string))
654
+ else:
655
+ ALTEREGO.contact["NR"] = the_packet.get("SRX", "000")
656
+ ALTEREGO.other_2.setText(str(the_packet.get("SRX", "000")))
657
+
658
+ ALTEREGO.contact["Mode"] = the_packet.get("MODE", "ERR")
659
+ ALTEREGO.contact["Freq"] = round(float(the_packet.get("FREQ", "0.0")) * 1000, 2)
660
+ ALTEREGO.contact["QSXFreq"] = round(
661
+ float(the_packet.get("FREQ", "0.0")) * 1000, 2
662
+ )
663
+ ALTEREGO.contact["Band"] = get_logged_band(
664
+ str(int(float(the_packet.get("FREQ", "0.0")) * 1000000))
665
+ )
666
+ logger.debug(f"{ALTEREGO.contact=}")
667
+
668
+ ALTEREGO.save_contact()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 24.12.29
3
+ Version: 25.1.6
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,22 +240,8 @@ 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
- - [24-12-29] Add {LOGIT} macro.
243
- - [24-12-15] Fixed Button focus policy in the bandmap window.
244
- - [24-12-14] Changed method of detecting fldigi QSOs. See docs.
245
- - [24-12-12] Add a try exception for a unicode decode error.
246
- - [24-12-11-1] Add RTC to RAC Canada Day, ARRL VHF, ARRL Field Day, ARRL SS, ARRL DX, 10 10
247
- - [24-12-11] Add RTC to IARU HF, IARU Field Day, DARC XMAS, CQ WW, CQ WPX
248
- - [24-12-9] Add RTC to Winter Field Day, Stew Perry, REF, RAEM, NAQP, LZ-DX, JIDX
249
- - [24-12-8-2] Add RTC to ARRL 10M, Tweaked cabrillo file output.
250
- - [24-12-8-1] Changed cabrillo names for Weekly RTTY, CW Ops CWT and K1USN SST.
251
- - [24-12-8] Fix: Weekly RTTY mults. Add RTC to Weekly RTTY.
252
- - [24-12-6] Add RTC to K1USN.
253
- -[24-12-5-1] ARRL 160 gets rtc.
254
- - [24-12-5] Add 'real time' score posting to external sites.
255
- - [24-12-4] Merged PR from @alduhoo Add STATION_CALLSIGN field to ADIF output
256
- - [24-12-3-1] Adding ARRL 160
257
- - [24-12-3] Add button to bandmap to delete marked spots.
243
+ - [25-1-6] Altered RTTY RU UDP ADIF parse.
244
+ - [25-1-1] Added ARRL RTTY RU.
258
245
 
259
246
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
260
247
 
@@ -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=KXLQixsrKPnS7siN12CznMxtJtwVInf8Aqdw7o4Q2kA,23844
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=Zxj8R2RAU3f3QjwyIVhlY4RGN0LkJWYSJyWj2VVCBmk,49
117
+ not1mm/lib/version.py,sha256=iW32MIFaiAvBUPU7oYgyRhnGFlmeNjNzGML_oIFxa6s,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=Cov4_0AQEWSmj8hjiuW_lgpqRZHuxqufbXBbKjPYLH4,7667
129
+ not1mm/plugins/arrl_rtty_ru.py,sha256=_NQUaIXinlY6gSa_f6J1nUpfZBGgg6SAoi1voDmmB20,20893
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
@@ -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-24.12.29.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
167
- not1mm-24.12.29.dist-info/METADATA,sha256=qeSNlzyaIxW-VbMNR5UWfFyyxaUTSMSiOPP0i5nJzf0,36585
168
- not1mm-24.12.29.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
169
- not1mm-24.12.29.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
170
- not1mm-24.12.29.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
171
- not1mm-24.12.29.dist-info/RECORD,,
166
+ not1mm-25.1.6.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
167
+ not1mm-25.1.6.dist-info/METADATA,sha256=GQZzZaXZQcA238AIpNfqQXP4SYN2Xddwlvv2H6shzuE,35716
168
+ not1mm-25.1.6.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
169
+ not1mm-25.1.6.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
170
+ not1mm-25.1.6.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
171
+ not1mm-25.1.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5