not1mm 25.3.19__py3-none-any.whl → 25.3.19.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.
@@ -332,6 +332,11 @@
332
332
  <string>EA MAJISTAD CW</string>
333
333
  </property>
334
334
  </item>
335
+ <item>
336
+ <property name="text">
337
+ <string>EA MAJISTAD SSB</string>
338
+ </property>
339
+ </item>
335
340
  <item>
336
341
  <property name="text">
337
342
  <string>EA RTTY</string>
not1mm/lib/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "25.3.19"
3
+ __version__ = "25.3.19.1"
@@ -12,7 +12,7 @@
12
12
  # Classes: Single Op, Multi OP, Trainee
13
13
  # Max power: 100 watts
14
14
  # Exchange: RST + Locator
15
- # Work stations: Once per band
15
+ # Work stations: Once per band
16
16
  # Points: 1 point per km distance between stations
17
17
  # Multipliers: no multis
18
18
  # Score Calculation: Total score = sum of all points
@@ -49,11 +49,11 @@ columns = [
49
49
  "SentNr",
50
50
  "RcvNr",
51
51
  "Exchange1",
52
- "PTS"
52
+ "PTS",
53
53
  ]
54
54
  cabrillo_name = "DARC VHF"
55
55
 
56
- advance_on_space = [True, True, True,True, False]
56
+ advance_on_space = [True, True, True, True, False]
57
57
  call_parse_exchange_on_edit = True
58
58
 
59
59
  # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
@@ -86,6 +86,7 @@ def reset_label(self):
86
86
  """reset label after field cleared"""
87
87
  self.exch_label.setText("# Grid")
88
88
 
89
+
89
90
  def set_tab_next(self):
90
91
  """Set TAB Advances"""
91
92
  self.tab_next = {
@@ -106,20 +107,20 @@ def set_tab_prev(self):
106
107
  self.other_1: self.receive,
107
108
  self.other_2: self.other_1,
108
109
  }
109
-
110
+
110
111
 
111
112
  def set_contact_vars(self):
112
- """Contest Specific"""
113
+ """Contest Specific"""
113
114
  sn, grid = parse_exchange(self)
114
115
  self.contact["SNT"] = self.sent.text()
115
116
  self.contact["RCV"] = self.receive.text()
116
- self.contact["SentNr"] = self.other_1.text()
117
- self.contact["NR"]= sn
118
- self.contact["Exchange1"] =grid
119
-
120
-
117
+ self.contact["SentNr"] = self.other_1.text()
118
+ self.contact["NR"] = sn
119
+ self.contact["Exchange1"] = grid
120
+
121
+
121
122
  def parse_exchange(self):
122
- """Parse exchange..."""
123
+ """Parse exchange..."""
123
124
  exchange = self.other_2.text()
124
125
  exchange = exchange.upper()
125
126
  sn = ""
@@ -160,9 +161,9 @@ def points(self):
160
161
  """Calc point"""
161
162
  _points = 1
162
163
  _kilometers = 0
163
- _their_grid = self.contact["Exchange1"] .upper()
164
+ _their_grid = self.contact["Exchange1"].upper()
164
165
  _kilometers = distance(self.station.get("GridSquare", ""), _their_grid)
165
- _points = max(1,_kilometers)
166
+ _points = max(1, _kilometers)
166
167
  return _points
167
168
 
168
169
 
@@ -170,7 +171,6 @@ def show_mults(self, rtc=None):
170
171
  """Return display string for mults"""
171
172
 
172
173
 
173
-
174
174
  def show_qso(self):
175
175
  """Return qso count"""
176
176
  result = self.database.fetch_qso_count()
@@ -187,7 +187,7 @@ def calc_score(self):
187
187
  if score is None:
188
188
  score = "0"
189
189
  contest_points = int(score)
190
- return contest_points
190
+ return contest_points
191
191
  return 0
192
192
 
193
193
 
@@ -197,8 +197,8 @@ def adif(self):
197
197
 
198
198
 
199
199
  def edi(self):
200
- """ Generate an edi file """
201
- file_encoding="ascii"
200
+ """Generate an edi file"""
201
+ file_encoding = "ascii"
202
202
  logger.debug("******EDI*****")
203
203
  logger.debug("Station: %s", f"{self.station}")
204
204
  logger.debug("Contest: %s", f"{self.contest_settings}")
@@ -212,7 +212,7 @@ def edi(self):
212
212
  logger.debug("%s", filename)
213
213
  log = self.database.fetch_all_contacts_asc()
214
214
  try:
215
- with open(filename, "w", encoding=file_encoding) as file_descriptor:
215
+ with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
216
216
  output_cabrillo_line(
217
217
  "[REG1TEST;1]",
218
218
  "\r\n",
@@ -229,7 +229,7 @@ def edi(self):
229
229
  loggedyear = value[0:4]
230
230
  loggedmonth = value[5:7]
231
231
  loggedday = value[8:10]
232
- loggeddate = loggedyear + loggedmonth +loggedday
232
+ loggeddate = loggedyear + loggedmonth + loggedday
233
233
  output_cabrillo_line(
234
234
  f"TDate: {loggeddate}",
235
235
  "\r\n",
@@ -271,8 +271,8 @@ def edi(self):
271
271
  "\r\n",
272
272
  file_descriptor,
273
273
  file_encoding,
274
- )
275
- BandInMHz = bandinMHz(self.contest_settings.get('BandCategory',''))
274
+ )
275
+ BandInMHz = bandinMHz(self.contest_settings.get("BandCategory", ""))
276
276
  output_cabrillo_line(
277
277
  f"PBand:{BandInMHz}",
278
278
  "\r\n",
@@ -320,7 +320,7 @@ def edi(self):
320
320
  "\r\n",
321
321
  file_descriptor,
322
322
  file_encoding,
323
- )
323
+ )
324
324
  output_cabrillo_line(
325
325
  f"RCoun:{self.station.get('Country', '')} ",
326
326
  "\r\n",
@@ -350,7 +350,7 @@ def edi(self):
350
350
  "\r\n",
351
351
  file_descriptor,
352
352
  file_encoding,
353
- )
353
+ )
354
354
  output_cabrillo_line(
355
355
  f"STXEq:{self.station.get('stationtxrx', '')}",
356
356
  "\r\n",
@@ -387,7 +387,7 @@ def edi(self):
387
387
  "\r\n",
388
388
  file_descriptor,
389
389
  file_encoding,
390
- )
390
+ )
391
391
  output_cabrillo_line(
392
392
  f"CQSOP:{calc_score(self)}",
393
393
  "\r\n",
@@ -447,7 +447,7 @@ def edi(self):
447
447
  "\r\n",
448
448
  file_descriptor,
449
449
  file_encoding,
450
- )
450
+ )
451
451
  output_cabrillo_line(
452
452
  f"[QSORecords;{NumberOfQsos}]",
453
453
  "\r\n",
@@ -457,25 +457,25 @@ def edi(self):
457
457
  for contact in log:
458
458
  the_date_and_time = contact.get("TS", "")
459
459
  themode = contact.get("Mode", "")
460
- modeCode=0
461
- if themode == "LSB" or themode == "USB" or themode=="SSB":
460
+ modeCode = 0
461
+ if themode == "LSB" or themode == "USB" or themode == "SSB":
462
462
  modeCode = 1
463
- if themode == "CW" or themode == "CWL" or themode=="CWU":
463
+ if themode == "CW" or themode == "CWL" or themode == "CWU":
464
464
  modeCode = 2
465
- frequency = str(int(contact.get("Freq", "0"))).rjust(5)
465
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
466
466
  loggedyear = the_date_and_time[2:4]
467
467
  loggedmonth = the_date_and_time[5:7]
468
468
  loggedday = the_date_and_time[8:10]
469
- loggeddate = loggedyear + loggedmonth +loggedday
469
+ loggeddate = loggedyear + loggedmonth + loggedday
470
470
  loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
471
- NumberSend = contact.get('SentNr', '')
472
- NumberReceived = contact.get('NR', '')
471
+ NumberSend = contact.get("SentNr", "")
472
+ NumberReceived = contact.get("NR", "")
473
473
  output_cabrillo_line(
474
474
  f"{loggeddate};"
475
475
  f"{loggedtime};"
476
476
  f"{contact.get('Call', '')};"
477
477
  f"{modeCode};"
478
- f"{str(contact.get('SNT', ''))};"
478
+ f"{str(contact.get('SNT', ''))};"
479
479
  f"{NumberSend:03d};"
480
480
  f"{str(contact.get('RCV', ''))};"
481
481
  f"{NumberReceived:03d};"
@@ -495,14 +495,14 @@ def edi(self):
495
495
 
496
496
 
497
497
  def bandinMHz(band):
498
- switch={
499
- "6M": "50 MHz",
500
- "4M": "70 MHz",
501
- "2M": "144 MHz",
502
- "70cm": "432 MHz",
503
- "23cm": "1,3 GHz",
504
- }
505
- return switch.get(band,"Invalid input {band}")
498
+ switch = {
499
+ "6M": "50 MHz",
500
+ "4M": "70 MHz",
501
+ "2M": "144 MHz",
502
+ "70cm": "432 MHz",
503
+ "23cm": "1,3 GHz",
504
+ }
505
+ return switch.get(band, "Invalid input {band}")
506
506
 
507
507
 
508
508
  def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
@@ -530,7 +530,7 @@ def cabrillo(self, file_encoding):
530
530
  logger.debug("%s", filename)
531
531
  log = self.database.fetch_all_contacts_asc()
532
532
  try:
533
- with open(filename, "w", encoding=file_encoding) as file_descriptor:
533
+ with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
534
534
  output_cabrillo_line(
535
535
  "START-OF-LOG: 3.0",
536
536
  "\r\n",
@@ -714,9 +714,9 @@ def recalculate_mults(self):
714
714
  all_contacts = self.database.fetch_all_contacts_asc()
715
715
  for contact in all_contacts:
716
716
  # recalculate points
717
- _their_grid = contact.get("Exchange1") .upper()
717
+ _their_grid = contact.get("Exchange1").upper()
718
718
  _kilometers = distance(self.station.get("GridSquare", ""), _their_grid)
719
- _points = max(1,_kilometers)
719
+ _points = max(1, _kilometers)
720
720
  contact["Points"] = _points
721
721
 
722
722
  self.database.change_contact(contact)
@@ -582,7 +582,7 @@ def populate_history_info_line(self):
582
582
  result = self.database.fetch_call_history(self.callsign.text())
583
583
  if result:
584
584
  self.history_info.setText(
585
- f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('State', '')}, {result.get('UserText','...')}"
585
+ f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('Exch1', '')}, {result.get('UserText','...')}"
586
586
  )
587
587
  else:
588
588
  self.history_info.setText("")
@@ -594,7 +594,7 @@ def check_call_history(self):
594
594
  if result:
595
595
  self.history_info.setText(f"{result.get('UserText','')}")
596
596
  if self.other_2.text() == "":
597
- self.other_2.setText(f"{result.get('State', '')}")
597
+ self.other_2.setText(f"{result.get('Exch1', '')}")
598
598
 
599
599
 
600
600
  def get_mults(self):
@@ -0,0 +1,727 @@
1
+ """
2
+ His Maj. King of Spain Contest, SSB
3
+ Status: Active
4
+ Geographic Focus: Worldwide
5
+ Participation: Worldwide
6
+ Awards: Worldwide
7
+ Mode: SSB
8
+ Bands: 160, 80, 40, 20, 15, 10m
9
+ Classes: Single Op All Band (QRP/Low/High)
10
+ Single Op All Band Youth
11
+ Single Op Single Band
12
+ Multi-Op (Low/High)
13
+ Max power: HP: >100 watts
14
+ LP: 100 watts
15
+ QRP: 5 watts
16
+ Exchange: EA: RST + province
17
+ non-EA: RST + Serial No.
18
+ Work stations: Once per band
19
+ QSO Points: (see rules)
20
+ Multipliers: Each EA province once per band
21
+ Each EADX100 entity once per band
22
+ Each special (EA0) station once per band
23
+ Score Calculation: Total score = total QSO points x total mults
24
+ E-mail logs to: (none)
25
+ Upload log at: https://concursos.ure.es/en/logs/
26
+ Mail logs to: (none)
27
+ Find rules at: https://concursos.ure.es/en/s-m-el-rey-de-espana-ssb/bases/
28
+ Cabrillo name: EA-MAJESTAD-SSB
29
+ """
30
+
31
+ # pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member
32
+
33
+ # EA1: AV, BU, C, LE, LO, LU, O, OU, P, PO, S, SA, SG, SO, VA, ZA
34
+ # EA2: BI, HU, NA, SS, TE, VI, Z
35
+ # EA3: B, GI, L, T
36
+ # EA4: BA, CC, CR, CU, GU, M, TO
37
+ # EA5: A, AB, CS, MU, V
38
+ # EA6: IB
39
+ # EA7: AL, CA, CO, GR, H, J, MA, SE
40
+ # EA8: GC, TF
41
+ # EA9: CE, ML
42
+
43
+
44
+ import datetime
45
+ import logging
46
+
47
+ from pathlib import Path
48
+ from PyQt6 import QtWidgets
49
+
50
+ from not1mm.lib.ham_utility import get_logged_band
51
+ from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
52
+ from not1mm.lib.version import __version__
53
+
54
+ logger = logging.getLogger(__name__)
55
+
56
+ EXCHANGE_HINT = "Province or #"
57
+
58
+ name = "His Maj. King of Spain Contest, SSB"
59
+ mode = "SSB" # CW SSB BOTH RTTY
60
+ cabrillo_name = "EA-MAJESTAD-SSB"
61
+
62
+ columns = [
63
+ "YYYY-MM-DD HH:MM:SS",
64
+ "Call",
65
+ "Freq",
66
+ "Snt",
67
+ "Rcv",
68
+ "SentNr",
69
+ "RcvNr",
70
+ "PTS",
71
+ ]
72
+
73
+ advance_on_space = [True, True, True, True, True]
74
+
75
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
76
+ dupe_type = 2
77
+
78
+
79
+ def init_contest(self) -> None:
80
+ """setup plugin"""
81
+ set_tab_next(self)
82
+ set_tab_prev(self)
83
+ interface(self)
84
+ self.next_field = self.other_2
85
+
86
+
87
+ def interface(self) -> None:
88
+ """
89
+ Setup the user interface.
90
+ Unhides the input fields and sets the lebels.
91
+ """
92
+ self.field1.show()
93
+ self.field2.show()
94
+ self.field3.show()
95
+ self.field4.show()
96
+ self.snt_label.setText("SNT")
97
+ self.field1.setAccessibleName("RST Sent")
98
+ self.other_label.setText("SentNR")
99
+ self.field3.setAccessibleName("Sent Number")
100
+ self.exch_label.setText("Prov or SN")
101
+ self.field4.setAccessibleName("Province or Serial Number")
102
+
103
+
104
+ def reset_label(self) -> None:
105
+ """
106
+ Reset label after field cleared.
107
+ Not needed for this contest.
108
+ """
109
+
110
+
111
+ def set_tab_next(self) -> None:
112
+ """
113
+ Set TAB Advances.
114
+ Defines which which of the fields are next to get focus when the TAB key is pressed.
115
+ """
116
+ self.tab_next = {
117
+ self.callsign: self.sent,
118
+ self.sent: self.receive,
119
+ self.receive: self.other_1,
120
+ self.other_1: self.other_2,
121
+ self.other_2: self.callsign,
122
+ }
123
+
124
+
125
+ def set_tab_prev(self) -> None:
126
+ """
127
+ Set TAB Advances.
128
+ Defines which which of the fields are next to get focus when the Shift-TAB key is pressed.
129
+ """
130
+ self.tab_prev = {
131
+ self.callsign: self.other_2,
132
+ self.sent: self.callsign,
133
+ self.receive: self.sent,
134
+ self.other_1: self.receive,
135
+ self.other_2: self.other_1,
136
+ }
137
+
138
+
139
+ def validate(self) -> bool:
140
+ """Not Used"""
141
+ return True
142
+
143
+
144
+ def set_contact_vars(self) -> None:
145
+ """Contest Specific"""
146
+ self.contact["SNT"] = self.sent.text()
147
+ self.contact["RCV"] = self.receive.text()
148
+ self.contact["NR"] = self.other_2.text().upper()
149
+ self.contact["SentNr"] = self.other_1.text()
150
+
151
+
152
+ def predupe(self) -> None:
153
+ """called after callsign entered. Not needed here."""
154
+
155
+
156
+ def prefill(self) -> None:
157
+ """
158
+ Fill the SentNR field with either the next serial number or the province.
159
+ """
160
+ result = self.database.get_serial()
161
+ serial_nr = str(result.get("serial_nr", "1")).zfill(3)
162
+ if serial_nr == "None":
163
+ serial_nr = "001"
164
+
165
+ exchange = self.contest_settings.get("SentExchange", "").replace("#", serial_nr)
166
+ if len(self.other_1.text()) == 0:
167
+ self.other_1.setText(exchange)
168
+
169
+
170
+ def points(self) -> int:
171
+ """
172
+ Calculate the points for this contact.
173
+ """
174
+ # EA: 2 points per QSO with EA
175
+ # EA: 1 point per QSO with non-EA
176
+ # non-EA: 3 points per QSO with EA
177
+ # non-EA: 1 point per QSO with non-EA
178
+
179
+ ea_prefixes = ["EA", "EA1", "EA2", "EA3", "EA4", "EA5", "EA6", "EA7", "EA8", "EA9"]
180
+
181
+ me = None
182
+ him = None
183
+
184
+ result = self.cty_lookup(self.station.get("Call", ""))
185
+ if result:
186
+ for item in result.items():
187
+ me = item[1].get("primary_pfx", "")
188
+
189
+ result = self.cty_lookup(self.contact.get("Call", ""))
190
+ if result:
191
+ for item in result.items():
192
+ him = item[1].get("primary_pfx", "")
193
+
194
+ if me is not None and him is not None:
195
+ if me in ea_prefixes and him in ea_prefixes:
196
+ return 2
197
+ elif me in ea_prefixes and him not in ea_prefixes:
198
+ return 1
199
+ elif me not in ea_prefixes and him in ea_prefixes:
200
+ return 3
201
+ else:
202
+ return 1
203
+
204
+ return 1
205
+
206
+
207
+ def show_mults(self, rtc=None) -> int:
208
+ """Return display string for mults"""
209
+
210
+ ea_provinces = 0
211
+ # dx = 0
212
+ ef0f = 0
213
+ eadx100 = 0
214
+
215
+ # Each EADX100 entity once per band
216
+ sql = (
217
+ "select count(DISTINCT(CountryPrefix || ':' || Band)) as mult_count "
218
+ f"from dxlog where ContestNR = {self.database.current_contest};"
219
+ )
220
+ result = self.database.exec_sql(sql)
221
+ if result:
222
+ eadx100 = result.get("mult_count", 0)
223
+
224
+ # Each EA province once per band
225
+ sql = (
226
+ "select count(DISTINCT(NR || ':' || Band)) as mult_count "
227
+ f"from dxlog where ContestNR = {self.database.current_contest} and typeof(NR) = 'text';"
228
+ )
229
+ result = self.database.exec_sql(sql)
230
+ if result:
231
+ ea_provinces = result.get("mult_count", 0)
232
+
233
+ # Each QSO with EF0F/8 once per band
234
+ sql = (
235
+ "select count(DISTINCT(Band)) as mult_count "
236
+ f"from dxlog where Call = 'EF0F/8' and ContestNR = {self.database.current_contest};"
237
+ )
238
+ result = self.database.exec_sql(sql)
239
+ if result:
240
+ ef0f = result.get("mult_count", 0)
241
+
242
+ if rtc is not None:
243
+ return 0, 0
244
+
245
+ return ea_provinces + ef0f + eadx100
246
+
247
+
248
+ def show_qso(self) -> int:
249
+ """Return qso count"""
250
+ result = self.database.fetch_qso_count()
251
+ if result:
252
+ return int(result.get("qsos", 0))
253
+ return 0
254
+
255
+
256
+ def calc_score(self) -> int:
257
+ """Return calculated score"""
258
+ _points = get_points(self)
259
+ _mults = show_mults(self)
260
+
261
+ return _points * _mults
262
+
263
+
264
+ def adif(self) -> None:
265
+ """Call the generate ADIF function"""
266
+ gen_adif(self, cabrillo_name, contest_id=cabrillo_name)
267
+
268
+
269
+ def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
270
+ """"""
271
+ print(
272
+ line_to_output.encode(file_encoding, errors="ignore").decode(),
273
+ end=ending,
274
+ file=file_descriptor,
275
+ )
276
+
277
+
278
+ def cabrillo(self, file_encoding):
279
+ """Generates Cabrillo file. Maybe."""
280
+ # https://www.cqwpx.com/cabrillo.htm
281
+ logger.debug("******Cabrillo*****")
282
+ logger.debug("Station: %s", f"{self.station}")
283
+ logger.debug("Contest: %s", f"{self.contest_settings}")
284
+ now = datetime.datetime.now()
285
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
286
+ filename = (
287
+ str(Path.home())
288
+ + "/"
289
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
290
+ )
291
+ logger.debug("%s", filename)
292
+ log = self.database.fetch_all_contacts_asc()
293
+ try:
294
+ with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
295
+ output_cabrillo_line(
296
+ "START-OF-LOG: 3.0",
297
+ "\r\n",
298
+ file_descriptor,
299
+ file_encoding,
300
+ )
301
+ output_cabrillo_line(
302
+ f"CREATED-BY: Not1MM v{__version__}",
303
+ "\r\n",
304
+ file_descriptor,
305
+ file_encoding,
306
+ )
307
+ output_cabrillo_line(
308
+ f"CONTEST: {cabrillo_name}",
309
+ "\r\n",
310
+ file_descriptor,
311
+ file_encoding,
312
+ )
313
+ if self.station.get("Club", ""):
314
+ output_cabrillo_line(
315
+ f"CLUB: {self.station.get('Club', '')}",
316
+ "\r\n",
317
+ file_descriptor,
318
+ file_encoding,
319
+ )
320
+ output_cabrillo_line(
321
+ f"CALLSIGN: {self.station.get('Call','')}",
322
+ "\r\n",
323
+ file_descriptor,
324
+ file_encoding,
325
+ )
326
+ output_cabrillo_line(
327
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
328
+ "\r\n",
329
+ file_descriptor,
330
+ file_encoding,
331
+ )
332
+ output_cabrillo_line(
333
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
334
+ "\r\n",
335
+ file_descriptor,
336
+ file_encoding,
337
+ )
338
+ output_cabrillo_line(
339
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
340
+ "\r\n",
341
+ file_descriptor,
342
+ file_encoding,
343
+ )
344
+ output_cabrillo_line(
345
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
346
+ "\r\n",
347
+ file_descriptor,
348
+ file_encoding,
349
+ )
350
+ mode = self.contest_settings.get("ModeCategory", "")
351
+ if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
352
+ mode = "MIXED"
353
+ output_cabrillo_line(
354
+ f"CATEGORY-MODE: {mode}",
355
+ "\r\n",
356
+ file_descriptor,
357
+ file_encoding,
358
+ )
359
+ output_cabrillo_line(
360
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
361
+ "\r\n",
362
+ file_descriptor,
363
+ file_encoding,
364
+ )
365
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
366
+ output_cabrillo_line(
367
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
368
+ "\r\n",
369
+ file_descriptor,
370
+ file_encoding,
371
+ )
372
+ output_cabrillo_line(
373
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
374
+ "\r\n",
375
+ file_descriptor,
376
+ file_encoding,
377
+ )
378
+ output_cabrillo_line(
379
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
380
+ "\r\n",
381
+ file_descriptor,
382
+ file_encoding,
383
+ )
384
+
385
+ output_cabrillo_line(
386
+ f"CLAIMED-SCORE: {calc_score(self)}",
387
+ "\r\n",
388
+ file_descriptor,
389
+ file_encoding,
390
+ )
391
+ ops = f"@{self.station.get('Call','')}"
392
+ list_of_ops = self.database.get_ops()
393
+ for op in list_of_ops:
394
+ ops += f", {op.get('Operator', '')}"
395
+ output_cabrillo_line(
396
+ f"OPERATORS: {ops}",
397
+ "\r\n",
398
+ file_descriptor,
399
+ file_encoding,
400
+ )
401
+ output_cabrillo_line(
402
+ f"NAME: {self.station.get('Name', '')}",
403
+ "\r\n",
404
+ file_descriptor,
405
+ file_encoding,
406
+ )
407
+ output_cabrillo_line(
408
+ f"ADDRESS: {self.station.get('Street1', '')}",
409
+ "\r\n",
410
+ file_descriptor,
411
+ file_encoding,
412
+ )
413
+ output_cabrillo_line(
414
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
415
+ "\r\n",
416
+ file_descriptor,
417
+ file_encoding,
418
+ )
419
+ output_cabrillo_line(
420
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
421
+ "\r\n",
422
+ file_descriptor,
423
+ file_encoding,
424
+ )
425
+ output_cabrillo_line(
426
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
427
+ "\r\n",
428
+ file_descriptor,
429
+ file_encoding,
430
+ )
431
+ output_cabrillo_line(
432
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
433
+ "\r\n",
434
+ file_descriptor,
435
+ file_encoding,
436
+ )
437
+ output_cabrillo_line(
438
+ f"EMAIL: {self.station.get('Email', '')}",
439
+ "\r\n",
440
+ file_descriptor,
441
+ file_encoding,
442
+ )
443
+ for contact in log:
444
+ the_date_and_time = contact.get("TS", "")
445
+ themode = contact.get("Mode", "")
446
+ if themode == "LSB" or themode == "USB":
447
+ themode = "PH"
448
+ if themode == "RTTY":
449
+ themode = "RY"
450
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
451
+
452
+ loggeddate = the_date_and_time[:10]
453
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
454
+ output_cabrillo_line(
455
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
456
+ f"{contact.get('StationPrefix', '').ljust(13)} "
457
+ f"{str(contact.get('SNT', '')).ljust(3)} "
458
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
459
+ f"{contact.get('Call', '').ljust(13)} "
460
+ f"{str(contact.get('RCV', '')).ljust(3)} "
461
+ f"{str(contact.get('NR', '')).ljust(6)}",
462
+ "\r\n",
463
+ file_descriptor,
464
+ file_encoding,
465
+ )
466
+ output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
467
+ self.show_message_box(f"Cabrillo saved to: {filename}")
468
+ except IOError as exception:
469
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
470
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
471
+ return
472
+
473
+
474
+ def recalculate_mults(self) -> None:
475
+ """Recalculates multipliers after change in logged qso."""
476
+
477
+
478
+ def process_esm(self, new_focused_widget=None, with_enter=False):
479
+ """ESM State Machine"""
480
+
481
+ # self.pref["run_state"]
482
+
483
+ # -----===== Assigned F-Keys =====-----
484
+ # self.esm_dict["CQ"]
485
+ # self.esm_dict["EXCH"]
486
+ # self.esm_dict["QRZ"]
487
+ # self.esm_dict["AGN"]
488
+ # self.esm_dict["HISCALL"]
489
+ # self.esm_dict["MYCALL"]
490
+ # self.esm_dict["QSOB4"]
491
+
492
+ # ----==== text fields ====----
493
+ # self.callsign
494
+ # self.sent
495
+ # self.receive
496
+ # self.other_1
497
+ # self.other_2
498
+
499
+ if new_focused_widget is not None:
500
+ self.current_widget = self.inputs_dict.get(new_focused_widget)
501
+
502
+ # print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
503
+
504
+ for a_button in [
505
+ self.esm_dict["CQ"],
506
+ self.esm_dict["EXCH"],
507
+ self.esm_dict["QRZ"],
508
+ self.esm_dict["AGN"],
509
+ self.esm_dict["HISCALL"],
510
+ self.esm_dict["MYCALL"],
511
+ self.esm_dict["QSOB4"],
512
+ ]:
513
+ if a_button is not None:
514
+ self.restore_button_color(a_button)
515
+
516
+ buttons_to_send = []
517
+
518
+ if self.pref.get("run_state"):
519
+ if self.current_widget == "callsign":
520
+ if len(self.callsign.text()) < 3:
521
+ self.make_button_green(self.esm_dict["CQ"])
522
+ buttons_to_send.append(self.esm_dict["CQ"])
523
+ elif len(self.callsign.text()) > 2:
524
+ self.make_button_green(self.esm_dict["HISCALL"])
525
+ self.make_button_green(self.esm_dict["EXCH"])
526
+ buttons_to_send.append(self.esm_dict["HISCALL"])
527
+ buttons_to_send.append(self.esm_dict["EXCH"])
528
+
529
+ elif self.current_widget in ["other_2"]:
530
+ if self.other_2.text() == "":
531
+ self.make_button_green(self.esm_dict["AGN"])
532
+ buttons_to_send.append(self.esm_dict["AGN"])
533
+ else:
534
+ self.make_button_green(self.esm_dict["QRZ"])
535
+ buttons_to_send.append(self.esm_dict["QRZ"])
536
+ buttons_to_send.append("LOGIT")
537
+
538
+ if with_enter is True and bool(len(buttons_to_send)):
539
+ for button in buttons_to_send:
540
+ if button:
541
+ if button == "LOGIT":
542
+ self.save_contact()
543
+ continue
544
+ if button == self.esm_dict["HISCALL"]:
545
+ self.process_function_key(button, rttysendrx=False)
546
+ continue
547
+ self.process_function_key(button)
548
+ else:
549
+ if self.current_widget == "callsign":
550
+ if len(self.callsign.text()) > 2:
551
+ self.make_button_green(self.esm_dict["MYCALL"])
552
+ buttons_to_send.append(self.esm_dict["MYCALL"])
553
+
554
+ elif self.current_widget in ["other_2"]:
555
+ if self.other_2.text() == "":
556
+ self.make_button_green(self.esm_dict["AGN"])
557
+ buttons_to_send.append(self.esm_dict["AGN"])
558
+ else:
559
+ self.make_button_green(self.esm_dict["EXCH"])
560
+ buttons_to_send.append(self.esm_dict["EXCH"])
561
+ buttons_to_send.append("LOGIT")
562
+
563
+ if with_enter is True and bool(len(buttons_to_send)):
564
+ for button in buttons_to_send:
565
+ if button:
566
+ if button == "LOGIT":
567
+ self.save_contact()
568
+ continue
569
+ self.process_function_key(button)
570
+
571
+
572
+ def populate_history_info_line(self):
573
+ result = self.database.fetch_call_history(self.callsign.text())
574
+ if result:
575
+ self.history_info.setText(
576
+ f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('Exch1', '')}, {result.get('UserText','...')}"
577
+ )
578
+ else:
579
+ self.history_info.setText("")
580
+
581
+
582
+ def check_call_history(self):
583
+ """"""
584
+ result = self.database.fetch_call_history(self.callsign.text())
585
+ if result:
586
+ self.history_info.setText(f"{result.get('UserText','')}")
587
+ if self.other_2.text() == "":
588
+ self.other_2.setText(f"{result.get('Exch1', '')}")
589
+
590
+
591
+ def get_mults(self):
592
+ """"""
593
+ mults = {}
594
+ mults["country"], mults["state"] = show_mults(self, rtc=True)
595
+ return mults
596
+
597
+
598
+ def just_points(self):
599
+ """"""
600
+ return get_points(self)
601
+
602
+
603
+ def set_self(the_outie):
604
+ """..."""
605
+ globals()["ALTEREGO"] = the_outie
606
+
607
+
608
+ def ft8_handler(the_packet: dict):
609
+ print(f"{the_packet=}")
610
+ """Process FT8 QSO packets
611
+ # FT8
612
+ # {
613
+ # 'CALL': 'KE0OG',
614
+ # 'GRIDSQUARE': 'DM10AT',
615
+ # 'MODE': 'FT8',
616
+ # 'RST_SENT': '',
617
+ # 'RST_RCVD': '',
618
+ # 'QSO_DATE': '20210329',
619
+ # 'TIME_ON': '183213',
620
+ # 'QSO_DATE_OFF': '20210329',
621
+ # 'TIME_OFF': '183213',
622
+ # 'BAND': '20M',
623
+ # 'FREQ': '14.074754',
624
+ # 'STATION_CALLSIGN': 'K6GTE',
625
+ # 'MY_GRIDSQUARE': 'DM13AT',
626
+ # 'CONTEST_ID': 'ARRL-FIELD-DAY',
627
+ # 'SRX_STRING': '1D UT',
628
+ # 'CLASS': '1D',
629
+ # 'ARRL_SECT': 'UT'
630
+ # }
631
+ # FlDigi
632
+ # {
633
+ # 'CALL': 'K5TUS',
634
+ # 'MODE': 'RTTY',
635
+ # 'FREQ': '14.068415',
636
+ # 'BAND': '20M',
637
+ # 'QSO_DATE': '20250103',
638
+ # 'TIME_ON': '2359',
639
+ # 'QSO_DATE_OFF': '20250103',
640
+ # 'TIME_OFF': '2359',
641
+ # 'NAME': '',
642
+ # 'QTH': '',
643
+ # 'STATE': 'ORG',
644
+ # 'VE_PROV': '',
645
+ # 'COUNTRY': 'USA',
646
+ # 'RST_SENT': '599',
647
+ # 'RST_RCVD': '599',
648
+ # 'TX_PWR': '0',
649
+ # 'CNTY': '',
650
+ # 'DXCC': '',
651
+ # 'CQZ': '5',
652
+ # 'IOTA': '',
653
+ # 'CONT': '',
654
+ # 'ITUZ': '',
655
+ # 'GRIDSQUARE': '',
656
+ # 'QSLRDATE': '',
657
+ # 'QSLSDATE': '',
658
+ # 'EQSLRDATE': '',
659
+ # 'EQSLSDATE': '',
660
+ # 'LOTWRDATE': '',
661
+ # 'LOTWSDATE': '',
662
+ # 'QSL_VIA': '',
663
+ # 'NOTES': '',
664
+ # 'SRX': '',
665
+ # 'STX': '000',
666
+ # 'SRX_STRING': '',
667
+ # 'STX_STRING': 'CA',
668
+
669
+
670
+ # 'SRX': '666',
671
+ # 'STX': '000',
672
+ # 'SRX_STRING': '',
673
+ # 'STX_STRING': 'CA',
674
+
675
+ # 'SRX': '004', 'STX': '000', 'SRX_STRING': '', 'STX_STRING': '#',
676
+
677
+ # 'CLASS': '',
678
+ # 'ARRL_SECT': '',
679
+ # 'OPERATOR': 'K6GTE',
680
+ # 'STATION_CALLSIGN': 'K6GTE',
681
+ # 'MY_GRIDSQUARE': 'DM13AT',
682
+ # 'MY_CITY': 'ANAHEIM, CA',
683
+ # 'CHECK': '',
684
+ # 'AGE': '',
685
+ # 'TEN_TEN': '',
686
+ # 'CWSS_PREC': '',
687
+ # 'CWSS_SECTION': '',
688
+ # 'CWSS_SERNO': '',
689
+ # 'CWSS_CHK': ''
690
+ # }
691
+
692
+ # """
693
+
694
+ # logger.debug(f"{the_packet=}")
695
+ # if ALTEREGO is not None:
696
+ # ALTEREGO.callsign.setText(the_packet.get("CALL"))
697
+ # ALTEREGO.contact["Call"] = the_packet.get("CALL", "")
698
+ # ALTEREGO.contact["SNT"] = the_packet.get("RST_SENT", "599")
699
+ # ALTEREGO.contact["RCV"] = the_packet.get("RST_RCVD", "599")
700
+
701
+ # sent_string = the_packet.get("STX_STRING", "")
702
+ # if sent_string != "":
703
+ # ALTEREGO.contact["SentNr"] = sent_string
704
+ # ALTEREGO.other_1.setText(str(sent_string))
705
+ # else:
706
+ # ALTEREGO.contact["SentNr"] = the_packet.get("STX", "000")
707
+ # ALTEREGO.other_1.setText(str(the_packet.get("STX", "000")))
708
+
709
+ # rx_string = the_packet.get("SRX_STRING", "")
710
+ # if rx_string != "":
711
+ # ALTEREGO.contact["NR"] = rx_string
712
+ # ALTEREGO.other_2.setText(str(rx_string))
713
+ # else:
714
+ # ALTEREGO.contact["NR"] = the_packet.get("SRX", "000")
715
+ # ALTEREGO.other_2.setText(str(the_packet.get("SRX", "000")))
716
+
717
+ # ALTEREGO.contact["Mode"] = the_packet.get("MODE", "ERR")
718
+ # ALTEREGO.contact["Freq"] = round(float(the_packet.get("FREQ", "0.0")) * 1000, 2)
719
+ # ALTEREGO.contact["QSXFreq"] = round(
720
+ # float(the_packet.get("FREQ", "0.0")) * 1000, 2
721
+ # )
722
+ # ALTEREGO.contact["Band"] = get_logged_band(
723
+ # str(int(float(the_packet.get("FREQ", "0.0")) * 1000000))
724
+ # )
725
+ # logger.debug(f"{ALTEREGO.contact=}")
726
+
727
+ # ALTEREGO.save_contact()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: not1mm
3
- Version: 25.3.19
3
+ Version: 25.3.19.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
@@ -224,6 +224,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
224
224
  - DARC Xmas
225
225
  - DARC VHF
226
226
  - EA Majistad CW
227
+ - EA Majistad SSB
227
228
  - EA RTTY
228
229
  - Helvetia
229
230
  - IARU Fieldday R1 CW, SSB
@@ -245,6 +246,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
245
246
 
246
247
  ## Recent Changes
247
248
 
249
+ - [25-3-19-1] Add EA His Maj King of Spain SSB.
248
250
  - [25-3-19] Merged PR from @DD5ML Adding DARC VHF.
249
251
  - [25-3-18] Add His Maj King of Spain CW
250
252
  - [25-3-17] Add EA RTTY contest.
@@ -33,7 +33,7 @@ not1mm/data/k6gte.not1mm-64.png,sha256=6ku45Gq1g5ezh04F07osoKRtanb3e4kbx5XdIEh3N
33
33
  not1mm/data/logwindow.ui,sha256=f7vULj96tHIQuR1nJMyvPHHcmVgzkhv9D1isyojsnFU,1458
34
34
  not1mm/data/logwindowx.ui,sha256=CwpI-h7cI1yqyldH9quKftsdHL5lTyL9ABOcf80nfqc,1632
35
35
  not1mm/data/main.ui,sha256=k7qmK-rnAN62t_YWyN5ZKK3-p1a3KREAVqU-SzKxEG8,63389
36
- not1mm/data/new_contest.ui,sha256=_Eznl2rS830YHDH2rsGKGsKGaiLCcercQqe8GYJPmvw,24490
36
+ not1mm/data/new_contest.ui,sha256=m41EGeg1yPSUZAkF8jA2z1EKytZD9hZYiQDh1sjE2ac,24602
37
37
  not1mm/data/not1mm.html,sha256=c9-mfjMwDt4f5pySUruz2gREW33CQ2_rCddM2z5CZQo,23273
38
38
  not1mm/data/opon.ui,sha256=QDicqAk2lORG2UWsHa6jHlsGn6uzrrI2R4HSAocpPes,2258
39
39
  not1mm/data/pickcontest.ui,sha256=4hPBszCglObThx_eIWtmK9CEcbr7WBjbB1rKZdI-o3I,1707
@@ -116,7 +116,7 @@ not1mm/lib/plugin_common.py,sha256=D1OBjyLmX7zuSPqgTCmHwXzAKA12J_zTQItvyIem-4Y,1
116
116
  not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
117
117
  not1mm/lib/settings.py,sha256=mXffn8Xaj5KATPQinNBR0V5DbHWQPsRfh24_axWGYuk,15254
118
118
  not1mm/lib/super_check_partial.py,sha256=hwT2NRwobu0PLDyw6ltmbmcAtGBD02CKGFbgGWjXMqA,2334
119
- not1mm/lib/version.py,sha256=xxIOV5hNtkeAby6sRH2WKMLOsJnak7kyLYV_w52eU_8,48
119
+ not1mm/lib/version.py,sha256=D36haw75BmT7nbfjzMyIS7VQGPLJvRzA8aVsd7gzB5Y,50
120
120
  not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
121
121
  not1mm/plugins/10_10_fall_cw.py,sha256=P63dEhRmvsEV7ixHYg-qhs5zzj0_DJXjjPHQBQr8Wwg,14731
122
122
  not1mm/plugins/10_10_spring_cw.py,sha256=S_z-KbExH4_kfRbKo07zM-iVlJUKxFwzbm6LRnXYyNU,14734
@@ -144,9 +144,10 @@ not1mm/plugins/cq_ww_cw.py,sha256=GCsKohb1SQf9RbsXVUa_ojwkPIzm_TmCJHu2SAjaeKg,18
144
144
  not1mm/plugins/cq_ww_rtty.py,sha256=6McNrXDziFpxgUP244jFXr3FirpVAKHPK8PU_szXvvE,22498
145
145
  not1mm/plugins/cq_ww_ssb.py,sha256=gDAizDcr9cIgXJQ6S63UDtG64jvjIZQfvWw_MYfkNKU,18003
146
146
  not1mm/plugins/cwt.py,sha256=mN1wGGao9lcXN8ztqED564tEbf1APl8_jQDoDFaThkw,17542
147
- not1mm/plugins/darc_vhf.py,sha256=zseAgqxbVUqVrPygWKJPX-mxAmQTzWPouCuJnXuKqAQ,27466
147
+ not1mm/plugins/darc_vhf.py,sha256=WENCNr_v5_OrjluXDTYsIY9rPnhlx2qi-aD-96sjpZI,27367
148
148
  not1mm/plugins/darc_xmas.py,sha256=KmpFXWS1jKegPCvk8XZWlzUCshhtDww2AgTGtauricQ,18919
149
- not1mm/plugins/ea_majistad_cw.py,sha256=YBTfe9cNjz5dve8X1-h_DcUW4S77EzJDBtgr5jnIeP8,23301
149
+ not1mm/plugins/ea_majistad_cw.py,sha256=WUPM9sY2mOKSVFfOCPxtNAvEAwbjDIP8S1X1KgPJn0E,23301
150
+ not1mm/plugins/ea_majistad_ssb.py,sha256=FOd26kb_QjGCk_CIkQiG0FDw5fZQfAqE2b2xooPNylc,22895
150
151
  not1mm/plugins/ea_rtty.py,sha256=RBaavcn2CRcH3NuSx5YAPsChYY2BCKpES-8YT9FtS0E,23178
151
152
  not1mm/plugins/general_logging.py,sha256=eQuna-LnrWpf93LmHTTo6956GWoGocVfeYnzY5cyTmw,9600
152
153
  not1mm/plugins/helvetia.py,sha256=-aL4GYn3boRMJWVWqqS3xvXUgehB58-5cTs1jWTsnxE,20027
@@ -170,9 +171,9 @@ not1mm/plugins/ref_ssb.py,sha256=tGK5XeFrc3z7l8OViG9DM3rc4HLUBF9S3SUkaAPrjQk,215
170
171
  not1mm/plugins/stew_perry_topband.py,sha256=LHt0WnWMRS_m5nO9BOIQs0kO38M6x-k4eaA4nbEqDVA,15353
171
172
  not1mm/plugins/weekly_rtty.py,sha256=4gfFg25KGkU9tKmwslHLc38qPAXuRGWNX48n582NC7w,20078
172
173
  not1mm/plugins/winter_field_day.py,sha256=jLgEr95hJCZoc3Fi95PiNeB06thPQHFI3zOHmR6NprE,15234
173
- not1mm-25.3.19.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
174
- not1mm-25.3.19.dist-info/METADATA,sha256=qUltk00irrJxx5AfCwWp2pc62zmq-Jkw77_43PLPEVw,37158
175
- not1mm-25.3.19.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
176
- not1mm-25.3.19.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
177
- not1mm-25.3.19.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
178
- not1mm-25.3.19.dist-info/RECORD,,
174
+ not1mm-25.3.19.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
175
+ not1mm-25.3.19.1.dist-info/METADATA,sha256=1edRS2VupikCzWq1a2BhoJ_6Uc18pGQ7Waj5wgIFOMo,37226
176
+ not1mm-25.3.19.1.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
177
+ not1mm-25.3.19.1.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
178
+ not1mm-25.3.19.1.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
179
+ not1mm-25.3.19.1.dist-info/RECORD,,