not1mm 24.6.1__py3-none-any.whl → 24.7.13__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/data/settings.ui CHANGED
@@ -1255,7 +1255,7 @@
1255
1255
  </palette>
1256
1256
  </property>
1257
1257
  <property name="focusPolicy">
1258
- <enum>Qt::StrongFocus</enum>
1258
+ <enum>Qt::FocusPolicy::StrongFocus</enum>
1259
1259
  </property>
1260
1260
  <property name="accessibleName">
1261
1261
  <string>c q zone</string>
@@ -1374,7 +1374,7 @@
1374
1374
  <item>
1375
1375
  <spacer name="horizontalSpacer_2">
1376
1376
  <property name="orientation">
1377
- <enum>Qt::Horizontal</enum>
1377
+ <enum>Qt::Orientation::Horizontal</enum>
1378
1378
  </property>
1379
1379
  <property name="sizeHint" stdset="0">
1380
1380
  <size>
@@ -1387,10 +1387,10 @@
1387
1387
  <item>
1388
1388
  <widget class="QDialogButtonBox" name="buttonBox">
1389
1389
  <property name="orientation">
1390
- <enum>Qt::Horizontal</enum>
1390
+ <enum>Qt::Orientation::Horizontal</enum>
1391
1391
  </property>
1392
1392
  <property name="standardButtons">
1393
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
1393
+ <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
1394
1394
  </property>
1395
1395
  <property name="centerButtons">
1396
1396
  <bool>true</bool>
@@ -1400,7 +1400,7 @@
1400
1400
  <item>
1401
1401
  <spacer name="horizontalSpacer">
1402
1402
  <property name="orientation">
1403
- <enum>Qt::Horizontal</enum>
1403
+ <enum>Qt::Orientation::Horizontal</enum>
1404
1404
  </property>
1405
1405
  <property name="sizeHint" stdset="0">
1406
1406
  <size>
@@ -138,6 +138,8 @@ class CAT:
138
138
  ConnectionRefusedError,
139
139
  xmlrpc.client.Fault,
140
140
  http.client.BadStatusLine,
141
+ http.client.CannotSendRequest,
142
+ http.client.ResponseNotReady,
141
143
  ) as exception:
142
144
  self.online = False
143
145
  logger.debug("getvfo_flrig: %s", f"{exception}")
@@ -177,6 +179,8 @@ class CAT:
177
179
  ConnectionRefusedError,
178
180
  xmlrpc.client.Fault,
179
181
  http.client.BadStatusLine,
182
+ http.client.CannotSendRequest,
183
+ http.client.ResponseNotReady,
180
184
  ) as exception:
181
185
  self.online = False
182
186
  logger.debug("%s", f"{exception}")
@@ -220,6 +224,8 @@ class CAT:
220
224
  ConnectionRefusedError,
221
225
  xmlrpc.client.Fault,
222
226
  http.client.BadStatusLine,
227
+ http.client.CannotSendRequest,
228
+ http.client.ResponseNotReady,
223
229
  ) as exception:
224
230
  self.online = False
225
231
  logger.debug("getbw_flrig: %s", f"{exception}")
@@ -261,6 +267,8 @@ class CAT:
261
267
  ConnectionRefusedError,
262
268
  xmlrpc.client.Fault,
263
269
  http.client.BadStatusLine,
270
+ http.client.CannotSendRequest,
271
+ http.client.ResponseNotReady,
264
272
  ) as exception:
265
273
  self.online = False
266
274
  logger.debug("getpower_flrig: %s", f"{exception}")
@@ -295,6 +303,8 @@ class CAT:
295
303
  ConnectionRefusedError,
296
304
  xmlrpc.client.Fault,
297
305
  http.client.BadStatusLine,
306
+ http.client.CannotSendRequest,
307
+ http.client.ResponseNotReady,
298
308
  ) as exception:
299
309
  self.online = False
300
310
  logger.debug("%s", f"{exception}")
@@ -333,6 +343,8 @@ class CAT:
333
343
  ConnectionRefusedError,
334
344
  xmlrpc.client.Fault,
335
345
  http.client.BadStatusLine,
346
+ http.client.CannotSendRequest,
347
+ http.client.ResponseNotReady,
336
348
  ) as exception:
337
349
  self.online = False
338
350
  logger.debug("setvfo_flrig: %s", f"{exception}")
@@ -371,6 +383,8 @@ class CAT:
371
383
  ConnectionRefusedError,
372
384
  xmlrpc.client.Fault,
373
385
  http.client.BadStatusLine,
386
+ http.client.CannotSendRequest,
387
+ http.client.ResponseNotReady,
374
388
  ) as exception:
375
389
  self.online = False
376
390
  logger.debug("setmode_flrig: %s", f"{exception}")
@@ -408,6 +422,8 @@ class CAT:
408
422
  ConnectionRefusedError,
409
423
  xmlrpc.client.Fault,
410
424
  http.client.BadStatusLine,
425
+ http.client.CannotSendRequest,
426
+ http.client.ResponseNotReady,
411
427
  ) as exception:
412
428
  self.online = False
413
429
  logger.debug("setpower_flrig: %s", f"{exception}")
@@ -462,6 +478,8 @@ class CAT:
462
478
  ConnectionRefusedError,
463
479
  xmlrpc.client.Fault,
464
480
  http.client.BadStatusLine,
481
+ http.client.CannotSendRequest,
482
+ http.client.ResponseNotReady,
465
483
  ) as exception:
466
484
  self.online = False
467
485
  logger.debug("%s", f"{exception}")
@@ -496,6 +514,8 @@ class CAT:
496
514
  ConnectionRefusedError,
497
515
  xmlrpc.client.Fault,
498
516
  http.client.BadStatusLine,
517
+ http.client.CannotSendRequest,
518
+ http.client.ResponseNotReady,
499
519
  ) as exception:
500
520
  self.online = False
501
521
  logger.debug("%s", f"{exception}")
not1mm/lib/ham_utility.py CHANGED
@@ -242,7 +242,7 @@ def fakefreq(band: str, mode: str) -> str:
242
242
  "80": ["3530", "3559", "3970"],
243
243
  "60": ["5332", "5373", "5405"],
244
244
  "40": ["7030", "7040", "7250"],
245
- "30": ["10130", "10130", "0000"],
245
+ "30": ["10130", "10130", "10130"],
246
246
  "20": ["14030", "14070", "14250"],
247
247
  "17": ["18080", "18100", "18150"],
248
248
  "15": ["21065", "21070", "21200"],
not1mm/lib/n1mm.py CHANGED
@@ -102,6 +102,21 @@ class N1MM:
102
102
  "ID": "",
103
103
  }
104
104
 
105
+ score_report = {
106
+ "app": "NOT1MM",
107
+ "contest": "",
108
+ "call": "",
109
+ "class": {
110
+ "ops": "SINGLE-OP",
111
+ "mode": "MIXED",
112
+ "power": "LOW",
113
+ "bands": "ALL",
114
+ "transmitter": "ONE",
115
+ },
116
+ "score": 0,
117
+ "timestamp": "",
118
+ }
119
+
105
120
  def __init__(
106
121
  self,
107
122
  radioport="127.0.0.1:12060",
@@ -159,6 +174,14 @@ class N1MM:
159
174
  """Send lookup request"""
160
175
  self._send(self.lookup_port, self.contact_info, "lookupinfo")
161
176
 
177
+ def send_score(self):
178
+ """Send score"""
179
+ self._send(self.score_port, self.score_report, "scoreinfo")
180
+
181
+ def send_realtime_score(self):
182
+ """Send score"""
183
+ self._send(self.score_port, self.score_report, "dynamicresults")
184
+
162
185
  def _send(self, port_list, payload, package_name):
163
186
  """Send XML data"""
164
187
  # bytes_to_send = dicttoxml(
not1mm/lib/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.6.1"
3
+ __version__ = "24.7.13"
@@ -21,4 +21,347 @@
21
21
  # Find rules at: http://www.k1usn.com/sst.html
22
22
 
23
23
  import datetime
24
+ import logging
25
+ import platform
24
26
 
27
+ from pathlib import Path
28
+
29
+ from PyQt6 import QtWidgets
30
+
31
+ from not1mm.lib.plugin_common import gen_adif, get_points
32
+ from not1mm.lib.version import __version__
33
+
34
+ logger = logging.getLogger(__name__)
35
+
36
+ EXCHANGE_HINT = "Name or Name + SPC"
37
+
38
+ name = "PHONE WEEKLY TEST"
39
+ cabrillo_name = "PHONE-WEEKLY-TEST"
40
+ mode = "SSB" # CW SSB BOTH RTTY
41
+ # columns = [0, 1, 2, 3, 4, 10, 11, 14, 15]
42
+ columns = [
43
+ "YYYY-MM-DD HH:MM:SS",
44
+ "Call",
45
+ "Freq",
46
+ "Name",
47
+ "Sect",
48
+ "M1",
49
+ "PTS",
50
+ ]
51
+
52
+ advance_on_space = [True, True, True, True, True]
53
+
54
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
55
+ dupe_type = 2
56
+
57
+
58
+ def init_contest(self):
59
+ """setup plugin"""
60
+ set_tab_next(self)
61
+ set_tab_prev(self)
62
+ interface(self)
63
+ self.next_field = self.other_1
64
+
65
+
66
+ def interface(self):
67
+ """Setup user interface"""
68
+ self.field1.hide()
69
+ self.field2.hide()
70
+ self.field3.show()
71
+ self.field4.show()
72
+ namefield = self.field3.findChild(QtWidgets.QLabel)
73
+ namefield.setText("Name")
74
+ self.field3.setAccessibleName("Name")
75
+ spc = self.field4.findChild(QtWidgets.QLabel)
76
+ spc.setText("State")
77
+ self.field4.setAccessibleName("State")
78
+
79
+
80
+ def reset_label(self):
81
+ """reset label after field cleared"""
82
+
83
+
84
+ def set_tab_next(self):
85
+ """Set TAB Advances"""
86
+ self.tab_next = {
87
+ self.callsign: self.field3.findChild(QtWidgets.QLineEdit),
88
+ self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
89
+ QtWidgets.QLineEdit
90
+ ),
91
+ self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
92
+ }
93
+
94
+
95
+ def set_tab_prev(self):
96
+ """Set TAB Advances"""
97
+ self.tab_prev = {
98
+ self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
99
+ self.field3.findChild(QtWidgets.QLineEdit): self.callsign,
100
+ self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
101
+ QtWidgets.QLineEdit
102
+ ),
103
+ }
104
+
105
+
106
+ def set_contact_vars(self):
107
+ """Contest Specific"""
108
+ self.contact["SNT"] = self.sent.text()
109
+ self.contact["RCV"] = self.receive.text()
110
+ self.contact["Name"] = self.other_1.text().upper()
111
+ self.contact["Sect"] = self.other_2.text().upper()
112
+ self.contact["SentNr"] = self.contest_settings.get("SentExchange", 0)
113
+
114
+ if self.contact.get("Sect", ""):
115
+ result = self.database.fetch_sect_band_exists(
116
+ self.contact.get("Sect", ""), self.contact.get("Band", "")
117
+ )
118
+ if result.get("sect_count", ""):
119
+ self.contact["IsMultiplier1"] = 0
120
+ else:
121
+ self.contact["IsMultiplier1"] = 1
122
+
123
+
124
+ def predupe(self):
125
+ """called after callsign entered"""
126
+
127
+
128
+ def prefill(self):
129
+ """Fill sentnr"""
130
+
131
+
132
+ def points(self):
133
+ """Calc point"""
134
+ return 1
135
+
136
+
137
+ def show_mults(self):
138
+ """Return display string for mults"""
139
+ result = self.database.fetch_section_band_count_nodx()
140
+ if result:
141
+ return int(result.get("sb_count", 0))
142
+ return 0
143
+
144
+
145
+ def show_qso(self):
146
+ """Return qso count"""
147
+ result = self.database.fetch_qso_count()
148
+ if result:
149
+ return int(result.get("qsos", 0))
150
+ return 0
151
+
152
+
153
+ def calc_score(self):
154
+ """Return calculated score"""
155
+ result = self.database.fetch_points()
156
+ if result is not None:
157
+ score = result.get("Points", "0")
158
+ if score is None:
159
+ score = "0"
160
+ contest_points = int(score)
161
+ mults = show_mults(self)
162
+ return contest_points * mults
163
+ return 0
164
+
165
+
166
+ def adif(self):
167
+ """Call the generate ADIF function"""
168
+ gen_adif(self, cabrillo_name, "K1USN-SST")
169
+
170
+
171
+ def cabrillo(self):
172
+ """Generates Cabrillo file. Maybe."""
173
+ # https://www.cqwpx.com/cabrillo.htm
174
+ logger.debug("******Cabrillo*****")
175
+ logger.debug("Station: %s", f"{self.station}")
176
+ logger.debug("Contest: %s", f"{self.contest_settings}")
177
+ now = datetime.datetime.now()
178
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
179
+ filename = (
180
+ str(Path.home())
181
+ + "/"
182
+ + f"{self.station.get('Call','').upper()}_{cabrillo_name}_{date_time}.log"
183
+ )
184
+ logger.debug("%s", filename)
185
+ log = self.database.fetch_all_contacts_asc()
186
+ try:
187
+ with open(filename, "w", encoding="ascii") as file_descriptor:
188
+ print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
189
+ print(
190
+ f"CREATED-BY: Not1MM v{__version__}",
191
+ end="\r\n",
192
+ file=file_descriptor,
193
+ )
194
+ print(
195
+ f"CONTEST: {cabrillo_name}",
196
+ end="\r\n",
197
+ file=file_descriptor,
198
+ )
199
+ if self.station.get("Club", ""):
200
+ print(
201
+ f"CLUB: {self.station.get('Club', '').upper()}",
202
+ end="\r\n",
203
+ file=file_descriptor,
204
+ )
205
+ print(
206
+ f"CALLSIGN: {self.station.get('Call','')}",
207
+ end="\r\n",
208
+ file=file_descriptor,
209
+ )
210
+ print(
211
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
212
+ end="\r\n",
213
+ file=file_descriptor,
214
+ )
215
+ # print(
216
+ # f"ARRL-SECTION: {self.pref.get('section', '')}",
217
+ # end="\r\n",
218
+ # file=file_descriptor,
219
+ # )
220
+ print(
221
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
222
+ end="\r\n",
223
+ file=file_descriptor,
224
+ )
225
+ print(
226
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
227
+ end="\r\n",
228
+ file=file_descriptor,
229
+ )
230
+ print(
231
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
232
+ end="\r\n",
233
+ file=file_descriptor,
234
+ )
235
+ print(
236
+ f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
237
+ end="\r\n",
238
+ file=file_descriptor,
239
+ )
240
+ print(
241
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
242
+ end="\r\n",
243
+ file=file_descriptor,
244
+ )
245
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
246
+ print(
247
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
248
+ end="\r\n",
249
+ file=file_descriptor,
250
+ )
251
+ print(
252
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
253
+ end="\r\n",
254
+ file=file_descriptor,
255
+ )
256
+ # print(
257
+ # f"CATEGORY: {None}",
258
+ # end="\r\n",
259
+ # file=file_descriptor,
260
+ # )
261
+ print(
262
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
263
+ end="\r\n",
264
+ file=file_descriptor,
265
+ )
266
+
267
+ print(
268
+ f"CLAIMED-SCORE: {calc_score(self)}",
269
+ end="\r\n",
270
+ file=file_descriptor,
271
+ )
272
+ ops = f"@{self.station.get('Call','')}"
273
+ list_of_ops = self.database.get_ops()
274
+ for op in list_of_ops:
275
+ ops += f", {op.get('Operator', '')}"
276
+ print(
277
+ f"OPERATORS: {ops}",
278
+ end="\r\n",
279
+ file=file_descriptor,
280
+ )
281
+ print(
282
+ f"NAME: {self.station.get('Name', '')}",
283
+ end="\r\n",
284
+ file=file_descriptor,
285
+ )
286
+ print(
287
+ f"ADDRESS: {self.station.get('Street1', '')}",
288
+ end="\r\n",
289
+ file=file_descriptor,
290
+ )
291
+ print(
292
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
293
+ end="\r\n",
294
+ file=file_descriptor,
295
+ )
296
+ print(
297
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
298
+ end="\r\n",
299
+ file=file_descriptor,
300
+ )
301
+ print(
302
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
303
+ end="\r\n",
304
+ file=file_descriptor,
305
+ )
306
+ print(
307
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
308
+ end="\r\n",
309
+ file=file_descriptor,
310
+ )
311
+ print(
312
+ f"EMAIL: {self.station.get('Email', '')}",
313
+ end="\r\n",
314
+ file=file_descriptor,
315
+ )
316
+ for contact in log:
317
+ the_date_and_time = contact.get("TS", "")
318
+ themode = contact.get("Mode", "")
319
+ if themode == "LSB" or themode == "USB":
320
+ themode = "PH"
321
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
322
+
323
+ loggeddate = the_date_and_time[:10]
324
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
325
+ print(
326
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
327
+ f"{contact.get('StationPrefix', '').ljust(13)} "
328
+ f"{str(contact.get('SentNr', '')).upper()} "
329
+ f"{contact.get('Call', '').ljust(13)} "
330
+ f"{str(contact.get('Name', '')).ljust(11)} "
331
+ f"{str(contact.get('Sect', '')).ljust(5)}",
332
+ end="\r\n",
333
+ file=file_descriptor,
334
+ )
335
+ print("END-OF-LOG:", end="\r\n", file=file_descriptor)
336
+ self.show_message_box(f"Cabrillo saved to: {filename}")
337
+ except IOError as exception:
338
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
339
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
340
+ return
341
+
342
+
343
+ def recalculate_mults(self):
344
+ """Recalculates multipliers after change in logged qso."""
345
+
346
+ all_contacts = self.database.fetch_all_contacts_asc()
347
+ for contact in all_contacts:
348
+ time_stamp = contact.get("TS", "")
349
+ sect = contact.get("Sect", "")
350
+ band = contact.get("Band", "")
351
+ query = (
352
+ f"select count(*) as sect_count from dxlog where TS < '{time_stamp}' "
353
+ f"and Sect = '{sect}' "
354
+ f"and Band = '{band}' "
355
+ f"and ContestNR = {self.pref.get('contest', '1')};"
356
+ )
357
+ result = self.database.exec_sql(query)
358
+ count = result.get("sect_count", 1)
359
+ if count == 0 and contact.get("Points", 0) == 1 and sect != "DX":
360
+ contact["IsMultiplier1"] = 1
361
+ else:
362
+ contact["IsMultiplier1"] = 0
363
+ self.database.change_contact(contact)
364
+ cmd = {}
365
+ cmd["cmd"] = "UPDATELOG"
366
+ cmd["station"] = platform.node()
367
+ self.multicast_interface.send_as_json(cmd)
@@ -181,7 +181,7 @@ def calc_score(self):
181
181
 
182
182
  def adif(self):
183
183
  """Call the generate ADIF function"""
184
- gen_adif(self, cabrillo_name, "NAQP-SSB")
184
+ gen_adif(self, cabrillo_name, "WEEKLY-PHONE-TEST")
185
185
 
186
186
 
187
187
  def cabrillo(self):