not1mm 25.3.18__py3-none-any.whl → 25.3.19__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 CHANGED
@@ -249,6 +249,7 @@ class MainWindow(QtWidgets.QMainWindow):
249
249
  lambda x: self.generate_cabrillo("utf-8")
250
250
  )
251
251
  self.actionGenerate_ADIF.triggered.connect(self.generate_adif)
252
+ self. actionGenerate_EDI.triggered.connect(self.generate_edi)
252
253
 
253
254
  self.actionConfiguration_Settings.triggered.connect(
254
255
  self.edit_configuration_settings
@@ -3331,6 +3332,9 @@ class MainWindow(QtWidgets.QMainWindow):
3331
3332
  if "ARRL Sweepstakes" in self.contest.name:
3332
3333
  self.contest.parse_exchange(self)
3333
3334
  return
3335
+ if hasattr(self.contest, "call_parse_exchange_on_edit"):
3336
+ if self.contest.advance_on_space:
3337
+ self.contest.parse_exchange(self)
3334
3338
  if hasattr(self.contest, "advance_on_space"):
3335
3339
  if self.contest.advance_on_space[4]:
3336
3340
  text = self.other_2.text()
@@ -3978,6 +3982,22 @@ class MainWindow(QtWidgets.QMainWindow):
3978
3982
  logger.debug("******ADIF*****")
3979
3983
  self.contest.adif(self)
3980
3984
 
3985
+ def generate_edi(self) -> None:
3986
+ """
3987
+ Calls the contest EDI file generator.
3988
+
3989
+ Parameters
3990
+ ----------
3991
+ None
3992
+
3993
+ Returns
3994
+ -------
3995
+ None
3996
+ """
3997
+
3998
+ logger.debug("******EDI*****")
3999
+ self.contest.edi(self)
4000
+
3981
4001
  def generate_cabrillo(self, file_encoding: str) -> None:
3982
4002
  """
3983
4003
  Calls the contest Cabrillo file generator. Maybe.
not1mm/data/main.ui CHANGED
@@ -1480,6 +1480,7 @@
1480
1480
  <addaction name="actionGenerate_ADIF"/>
1481
1481
  <addaction name="actionGenerate_Cabrillo_ASCII"/>
1482
1482
  <addaction name="actionGenerate_Cabrillo_UTF8"/>
1483
+ <addaction name="actionGenerate_EDI"/>
1483
1484
  <addaction name="separator"/>
1484
1485
  <addaction name="actionEdit_Macros"/>
1485
1486
  <addaction name="separator"/>
@@ -1779,6 +1780,28 @@
1779
1780
  <property name="shortcutVisibleInContextMenu">
1780
1781
  <bool>false</bool>
1781
1782
  </property>
1783
+ </action>
1784
+ <action name="actionGenerate_EDI">
1785
+ <property name="text">
1786
+ <string>Generate EDI</string>
1787
+ </property>
1788
+ <property name="font">
1789
+ <font>
1790
+ <family>JetBrains Mono ExtraLight</family>
1791
+ </font>
1792
+ </property>
1793
+ <property name="shortcut">
1794
+ <string/>
1795
+ </property>
1796
+ <property name="autoRepeat">
1797
+ <bool>false</bool>
1798
+ </property>
1799
+ <property name="iconVisibleInMenu">
1800
+ <bool>false</bool>
1801
+ </property>
1802
+ <property name="shortcutVisibleInContextMenu">
1803
+ <bool>false</bool>
1804
+ </property>
1782
1805
  </action>
1783
1806
  <action name="actionRecalculate_Mults">
1784
1807
  <property name="text">
@@ -322,6 +322,11 @@
322
322
  <string>DARC XMAS</string>
323
323
  </property>
324
324
  </item>
325
+ <item>
326
+ <property name="text">
327
+ <string>DARC VHF</string>
328
+ </property>
329
+ </item>
325
330
  <item>
326
331
  <property name="text">
327
332
  <string>EA MAJISTAD CW</string>
not1mm/lib/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "25.3.18"
3
+ __version__ = "25.3.19"
@@ -0,0 +1,848 @@
1
+ """DARC VHF plugin"""
2
+
3
+ # pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member, unused-import
4
+
5
+ # DARC VHF and above
6
+ # Status: Active
7
+ # Geographic Focus: Germany
8
+ # Participation: Worldwide
9
+ # Awards: Worldwide
10
+ # Mode: SSB, CW, FM
11
+ # Bands: 145 MHz, 435 MHz, 1.3 GHz, 2.3 GHz, 3.4 GHz, 5.7 GHz, 10 GHz, 24 GHz, 47 GHz, 76 GHz, 122 GHz, 134 GHz, 245 GHz, >300 GHz
12
+ # Classes: Single Op, Multi OP, Trainee
13
+ # Max power: 100 watts
14
+ # Exchange: RST + Locator
15
+ # Work stations: Once per band
16
+ # Points: 1 point per km distance between stations
17
+ # Multipliers: no multis
18
+ # Score Calculation: Total score = sum of all points
19
+ # Mail logs to: (none)
20
+ # Find rules at: https://www.darc.de/der-club/referate/conteste/ukw/tnukwcontest001/tnukwcontest007000/
21
+ # Cabrillo name: DARC VHF
22
+ # Log Format: EDI
23
+
24
+
25
+ import datetime
26
+ import logging
27
+
28
+ from pathlib import Path
29
+
30
+ from PyQt6 import QtWidgets
31
+
32
+ from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
33
+ from not1mm.lib.version import __version__
34
+ from not1mm.lib.ham_utility import distance
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+ EXCHANGE_HINT = "#"
39
+
40
+ name = "DARC VHF"
41
+ mode = "BOTH" # CW SSB BOTH RTTY
42
+ # columns = [0, 1, 2, 3, 4, 5, 6, 11, 15]
43
+ columns = [
44
+ "YYYY-MM-DD HH:MM:SS",
45
+ "Call",
46
+ "Freq",
47
+ "Snt",
48
+ "Rcv",
49
+ "SentNr",
50
+ "RcvNr",
51
+ "Exchange1",
52
+ "PTS"
53
+ ]
54
+ cabrillo_name = "DARC VHF"
55
+
56
+ advance_on_space = [True, True, True,True, False]
57
+ call_parse_exchange_on_edit = True
58
+
59
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
60
+ dupe_type = 3
61
+
62
+
63
+ def init_contest(self):
64
+ """setup plugin"""
65
+ set_tab_next(self)
66
+ set_tab_prev(self)
67
+ interface(self)
68
+ self.next_field = self.other_2
69
+
70
+
71
+ def interface(self):
72
+ """Setup user interface"""
73
+ self.field1.show()
74
+ self.field2.show()
75
+ self.field3.show()
76
+ self.field4.show()
77
+ self.snt_label.setText("SNT")
78
+ self.field1.setAccessibleName("RST Sent")
79
+ self.other_label.setText("SentNR")
80
+ self.field3.setAccessibleName("Sent Number")
81
+ self.exch_label.setText("# Grid")
82
+ self.field4.setAccessibleName("Gridsquare")
83
+
84
+
85
+ def reset_label(self):
86
+ """reset label after field cleared"""
87
+ self.exch_label.setText("# Grid")
88
+
89
+ def set_tab_next(self):
90
+ """Set TAB Advances"""
91
+ self.tab_next = {
92
+ self.callsign: self.sent,
93
+ self.sent: self.receive,
94
+ self.receive: self.other_1,
95
+ self.other_1: self.other_2,
96
+ self.other_2: self.callsign,
97
+ }
98
+
99
+
100
+ def set_tab_prev(self):
101
+ """Set TAB Advances"""
102
+ self.tab_prev = {
103
+ self.callsign: self.other_2,
104
+ self.sent: self.callsign,
105
+ self.receive: self.sent,
106
+ self.other_1: self.receive,
107
+ self.other_2: self.other_1,
108
+ }
109
+
110
+
111
+ def set_contact_vars(self):
112
+ """Contest Specific"""
113
+ sn, grid = parse_exchange(self)
114
+ self.contact["SNT"] = self.sent.text()
115
+ 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
+
121
+ def parse_exchange(self):
122
+ """Parse exchange..."""
123
+ exchange = self.other_2.text()
124
+ exchange = exchange.upper()
125
+ sn = ""
126
+ grid = ""
127
+ for tokens in exchange.split():
128
+ if tokens.isdigit():
129
+ if sn == "":
130
+ sn = tokens
131
+ continue
132
+ elif tokens.isalnum():
133
+ if len(tokens) == 6:
134
+ grid = tokens
135
+ continue
136
+ label = f"Sn:{sn} Grid:{grid}"
137
+ self.exch_label.setText(label)
138
+ return (sn, grid)
139
+
140
+
141
+ def predupe(self):
142
+ """prefill his exchange with last known values"""
143
+
144
+
145
+ def prefill(self):
146
+ """Fill SentNR"""
147
+ sent_sxchange_setting = self.contest_settings.get("SentExchange", "")
148
+ if sent_sxchange_setting.strip() == "#":
149
+ result = self.database.get_serial()
150
+ serial_nr = str(result.get("serial_nr", "1")).zfill(3)
151
+ if serial_nr == "None":
152
+ serial_nr = "001"
153
+ if len(self.other_1.text()) == 0:
154
+ self.other_1.setText(serial_nr)
155
+ else:
156
+ self.other_1.setText(sent_sxchange_setting)
157
+
158
+
159
+ def points(self):
160
+ """Calc point"""
161
+ _points = 1
162
+ _kilometers = 0
163
+ _their_grid = self.contact["Exchange1"] .upper()
164
+ _kilometers = distance(self.station.get("GridSquare", ""), _their_grid)
165
+ _points = max(1,_kilometers)
166
+ return _points
167
+
168
+
169
+ def show_mults(self, rtc=None):
170
+ """Return display string for mults"""
171
+
172
+
173
+
174
+ def show_qso(self):
175
+ """Return qso count"""
176
+ result = self.database.fetch_qso_count()
177
+ if result:
178
+ return int(result.get("qsos", 0))
179
+ return 0
180
+
181
+
182
+ def calc_score(self):
183
+ """Return calculated score"""
184
+ result = self.database.fetch_points()
185
+ if result is not None:
186
+ score = result.get("Points", "0")
187
+ if score is None:
188
+ score = "0"
189
+ contest_points = int(score)
190
+ return contest_points
191
+ return 0
192
+
193
+
194
+ def adif(self):
195
+ """Call the generate ADIF function"""
196
+ gen_adif(self, cabrillo_name, "DARC VHF Contest")
197
+
198
+
199
+ def edi(self):
200
+ """ Generate an edi file """
201
+ file_encoding="ascii"
202
+ logger.debug("******EDI*****")
203
+ logger.debug("Station: %s", f"{self.station}")
204
+ logger.debug("Contest: %s", f"{self.contest_settings}")
205
+ now = datetime.datetime.now()
206
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
207
+ filename = (
208
+ str(Path.home())
209
+ + "/"
210
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.edi"
211
+ )
212
+ logger.debug("%s", filename)
213
+ log = self.database.fetch_all_contacts_asc()
214
+ try:
215
+ with open(filename, "w", encoding=file_encoding) as file_descriptor:
216
+ output_cabrillo_line(
217
+ "[REG1TEST;1]",
218
+ "\r\n",
219
+ file_descriptor,
220
+ file_encoding,
221
+ )
222
+ output_cabrillo_line(
223
+ f"TName: {cabrillo_name}",
224
+ "\r\n",
225
+ file_descriptor,
226
+ file_encoding,
227
+ )
228
+ value = self.contest_settings.get("StartDate")
229
+ loggedyear = value[0:4]
230
+ loggedmonth = value[5:7]
231
+ loggedday = value[8:10]
232
+ loggeddate = loggedyear + loggedmonth +loggedday
233
+ output_cabrillo_line(
234
+ f"TDate: {loggeddate}",
235
+ "\r\n",
236
+ file_descriptor,
237
+ file_encoding,
238
+ )
239
+ output_cabrillo_line(
240
+ f"PCall: {self.station.get('Call','')}",
241
+ "\r\n",
242
+ file_descriptor,
243
+ file_encoding,
244
+ )
245
+ output_cabrillo_line(
246
+ f"PWWLo: {self.station.get('GridSquare','')}",
247
+ "\r\n",
248
+ file_descriptor,
249
+ file_encoding,
250
+ )
251
+ output_cabrillo_line(
252
+ f"PExch: ",
253
+ "\r\n",
254
+ file_descriptor,
255
+ file_encoding,
256
+ )
257
+ output_cabrillo_line(
258
+ f"PAdr1: {self.station.get('Street1', '')}, {self.station.get('Zip', '')} {self.station.get('City', '')}, {self.station.get('Country', '')}",
259
+ "\r\n",
260
+ file_descriptor,
261
+ file_encoding,
262
+ )
263
+ output_cabrillo_line(
264
+ f"PAdr2:",
265
+ "\r\n",
266
+ file_descriptor,
267
+ file_encoding,
268
+ )
269
+ output_cabrillo_line(
270
+ f"PSect:{self.contest_settings.get('OperatorCategory','')}",
271
+ "\r\n",
272
+ file_descriptor,
273
+ file_encoding,
274
+ )
275
+ BandInMHz = bandinMHz(self.contest_settings.get('BandCategory',''))
276
+ output_cabrillo_line(
277
+ f"PBand:{BandInMHz}",
278
+ "\r\n",
279
+ file_descriptor,
280
+ file_encoding,
281
+ )
282
+ output_cabrillo_line(
283
+ f"PClub:{self.station.get('Club', '').upper()}",
284
+ "\r\n",
285
+ file_descriptor,
286
+ file_encoding,
287
+ )
288
+ output_cabrillo_line(
289
+ f"RName:{self.station.get('Name', '')}",
290
+ "\r\n",
291
+ file_descriptor,
292
+ file_encoding,
293
+ )
294
+ output_cabrillo_line(
295
+ f"RCall:{self.station.get('Call','')}",
296
+ "\r\n",
297
+ file_descriptor,
298
+ file_encoding,
299
+ )
300
+ output_cabrillo_line(
301
+ f"RAdr1:{self.station.get('Street1', '')}",
302
+ "\r\n",
303
+ file_descriptor,
304
+ file_encoding,
305
+ )
306
+ output_cabrillo_line(
307
+ f"RAdr2:{self.station.get('Street2', '')}",
308
+ "\r\n",
309
+ file_descriptor,
310
+ file_encoding,
311
+ )
312
+ output_cabrillo_line(
313
+ f"RPoCo:{self.station.get('Zip', '')}",
314
+ "\r\n",
315
+ file_descriptor,
316
+ file_encoding,
317
+ )
318
+ output_cabrillo_line(
319
+ f"RCity:{self.station.get('City', '')}",
320
+ "\r\n",
321
+ file_descriptor,
322
+ file_encoding,
323
+ )
324
+ output_cabrillo_line(
325
+ f"RCoun:{self.station.get('Country', '')} ",
326
+ "\r\n",
327
+ file_descriptor,
328
+ file_encoding,
329
+ )
330
+ output_cabrillo_line(
331
+ f"RPhon:",
332
+ "\r\n",
333
+ file_descriptor,
334
+ file_encoding,
335
+ )
336
+ output_cabrillo_line(
337
+ f"RHBBS:{self.station.get('Email', '')}",
338
+ "\r\n",
339
+ file_descriptor,
340
+ file_encoding,
341
+ )
342
+ output_cabrillo_line(
343
+ f"MOpe1:",
344
+ "\r\n",
345
+ file_descriptor,
346
+ file_encoding,
347
+ )
348
+ output_cabrillo_line(
349
+ f"MOpe2:",
350
+ "\r\n",
351
+ file_descriptor,
352
+ file_encoding,
353
+ )
354
+ output_cabrillo_line(
355
+ f"STXEq:{self.station.get('stationtxrx', '')}",
356
+ "\r\n",
357
+ file_descriptor,
358
+ file_encoding,
359
+ )
360
+ output_cabrillo_line(
361
+ f"SPowe:{self.contest_settings.get('PowerCategory','')}",
362
+ "\r\n",
363
+ file_descriptor,
364
+ file_encoding,
365
+ )
366
+ output_cabrillo_line(
367
+ f"SRXEq:",
368
+ "\r\n",
369
+ file_descriptor,
370
+ file_encoding,
371
+ )
372
+ output_cabrillo_line(
373
+ f"SAnte:{self.station.get('SAnte', '')}",
374
+ "\r\n",
375
+ file_descriptor,
376
+ file_encoding,
377
+ )
378
+ output_cabrillo_line(
379
+ f"SAntH:{self.station.get('SAntH1', '')}",
380
+ "\r\n",
381
+ file_descriptor,
382
+ file_encoding,
383
+ )
384
+ NumberOfQsos = show_qso(self)
385
+ output_cabrillo_line(
386
+ f"CQSOs:{NumberOfQsos};1",
387
+ "\r\n",
388
+ file_descriptor,
389
+ file_encoding,
390
+ )
391
+ output_cabrillo_line(
392
+ f"CQSOP:{calc_score(self)}",
393
+ "\r\n",
394
+ file_descriptor,
395
+ file_encoding,
396
+ )
397
+ output_cabrillo_line(
398
+ f"CWWLs:0;0;1",
399
+ "\r\n",
400
+ file_descriptor,
401
+ file_encoding,
402
+ )
403
+ output_cabrillo_line(
404
+ f"CWWLB:0",
405
+ "\r\n",
406
+ file_descriptor,
407
+ file_encoding,
408
+ )
409
+ output_cabrillo_line(
410
+ f"CExcs:0;0;1",
411
+ "\r\n",
412
+ file_descriptor,
413
+ file_encoding,
414
+ )
415
+ output_cabrillo_line(
416
+ f"CExcB:0",
417
+ "\r\n",
418
+ file_descriptor,
419
+ file_encoding,
420
+ )
421
+ output_cabrillo_line(
422
+ f"CDXCs:0;0;1",
423
+ "\r\n",
424
+ file_descriptor,
425
+ file_encoding,
426
+ )
427
+ output_cabrillo_line(
428
+ f"CDXCB:0",
429
+ "\r\n",
430
+ file_descriptor,
431
+ file_encoding,
432
+ )
433
+ output_cabrillo_line(
434
+ f"CToSc:{calc_score(self)}",
435
+ "\r\n",
436
+ file_descriptor,
437
+ file_encoding,
438
+ )
439
+ output_cabrillo_line(
440
+ f"CODXC:",
441
+ "\r\n",
442
+ file_descriptor,
443
+ file_encoding,
444
+ )
445
+ output_cabrillo_line(
446
+ f"[Remarks]",
447
+ "\r\n",
448
+ file_descriptor,
449
+ file_encoding,
450
+ )
451
+ output_cabrillo_line(
452
+ f"[QSORecords;{NumberOfQsos}]",
453
+ "\r\n",
454
+ file_descriptor,
455
+ file_encoding,
456
+ )
457
+ for contact in log:
458
+ the_date_and_time = contact.get("TS", "")
459
+ themode = contact.get("Mode", "")
460
+ modeCode=0
461
+ if themode == "LSB" or themode == "USB" or themode=="SSB":
462
+ modeCode = 1
463
+ if themode == "CW" or themode == "CWL" or themode=="CWU":
464
+ modeCode = 2
465
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
466
+ loggedyear = the_date_and_time[2:4]
467
+ loggedmonth = the_date_and_time[5:7]
468
+ loggedday = the_date_and_time[8:10]
469
+ loggeddate = loggedyear + loggedmonth +loggedday
470
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
471
+ NumberSend = contact.get('SentNr', '')
472
+ NumberReceived = contact.get('NR', '')
473
+ output_cabrillo_line(
474
+ f"{loggeddate};"
475
+ f"{loggedtime};"
476
+ f"{contact.get('Call', '')};"
477
+ f"{modeCode};"
478
+ f"{str(contact.get('SNT', ''))};"
479
+ f"{NumberSend:03d};"
480
+ f"{str(contact.get('RCV', ''))};"
481
+ f"{NumberReceived:03d};"
482
+ f";"
483
+ f"{str(contact.get('Exchange1', ''))};"
484
+ f"{str(contact.get('Points', ''))};"
485
+ f"; ; ; ",
486
+ "\r\n",
487
+ file_descriptor,
488
+ file_encoding,
489
+ )
490
+ self.show_message_box(f"EDI saved to: {filename}")
491
+ except IOError as exception:
492
+ logger.critical("EDI: IO error: %s, writing to %s", exception, filename)
493
+ self.show_message_box(f"Error saving EDI: {exception} {filename}")
494
+ return
495
+
496
+
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}")
506
+
507
+
508
+ def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
509
+ """"""
510
+ print(
511
+ line_to_output.encode(file_encoding, errors="ignore").decode(),
512
+ end=ending,
513
+ file=file_descriptor,
514
+ )
515
+
516
+
517
+ def cabrillo(self, file_encoding):
518
+ """Generates Cabrillo file. Maybe."""
519
+ # https://www.cqwpx.com/cabrillo.htm
520
+ logger.debug("******Cabrillo*****")
521
+ logger.debug("Station: %s", f"{self.station}")
522
+ logger.debug("Contest: %s", f"{self.contest_settings}")
523
+ now = datetime.datetime.now()
524
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
525
+ filename = (
526
+ str(Path.home())
527
+ + "/"
528
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
529
+ )
530
+ logger.debug("%s", filename)
531
+ log = self.database.fetch_all_contacts_asc()
532
+ try:
533
+ with open(filename, "w", encoding=file_encoding) as file_descriptor:
534
+ output_cabrillo_line(
535
+ "START-OF-LOG: 3.0",
536
+ "\r\n",
537
+ file_descriptor,
538
+ file_encoding,
539
+ )
540
+ output_cabrillo_line(
541
+ f"CREATED-BY: Not1MM v{__version__}",
542
+ "\r\n",
543
+ file_descriptor,
544
+ file_encoding,
545
+ )
546
+ output_cabrillo_line(
547
+ f"CONTEST: {cabrillo_name}",
548
+ "\r\n",
549
+ file_descriptor,
550
+ file_encoding,
551
+ )
552
+ if self.station.get("Club", ""):
553
+ output_cabrillo_line(
554
+ f"CLUB: {self.station.get('Club', '').upper()}",
555
+ "\r\n",
556
+ file_descriptor,
557
+ file_encoding,
558
+ )
559
+ output_cabrillo_line(
560
+ f"CALLSIGN: {self.station.get('Call','')}",
561
+ "\r\n",
562
+ file_descriptor,
563
+ file_encoding,
564
+ )
565
+ output_cabrillo_line(
566
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
567
+ "\r\n",
568
+ file_descriptor,
569
+ file_encoding,
570
+ )
571
+ output_cabrillo_line(
572
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
573
+ "\r\n",
574
+ file_descriptor,
575
+ file_encoding,
576
+ )
577
+ output_cabrillo_line(
578
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
579
+ "\r\n",
580
+ file_descriptor,
581
+ file_encoding,
582
+ )
583
+ output_cabrillo_line(
584
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
585
+ "\r\n",
586
+ file_descriptor,
587
+ file_encoding,
588
+ )
589
+ mode = self.contest_settings.get("ModeCategory", "")
590
+ if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
591
+ mode = "MIXED"
592
+ output_cabrillo_line(
593
+ f"CATEGORY-MODE: {mode}",
594
+ "\r\n",
595
+ file_descriptor,
596
+ file_encoding,
597
+ )
598
+ output_cabrillo_line(
599
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
600
+ "\r\n",
601
+ file_descriptor,
602
+ file_encoding,
603
+ )
604
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
605
+ output_cabrillo_line(
606
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
607
+ "\r\n",
608
+ file_descriptor,
609
+ file_encoding,
610
+ )
611
+ output_cabrillo_line(
612
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
613
+ "\r\n",
614
+ file_descriptor,
615
+ file_encoding,
616
+ )
617
+ output_cabrillo_line(
618
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
619
+ "\r\n",
620
+ file_descriptor,
621
+ file_encoding,
622
+ )
623
+
624
+ output_cabrillo_line(
625
+ f"CLAIMED-SCORE: {calc_score(self)}",
626
+ "\r\n",
627
+ file_descriptor,
628
+ file_encoding,
629
+ )
630
+ ops = f"@{self.station.get('Call','')}"
631
+ list_of_ops = self.database.get_ops()
632
+ for op in list_of_ops:
633
+ ops += f", {op.get('Operator', '')}"
634
+ output_cabrillo_line(
635
+ f"OPERATORS: {ops}",
636
+ "\r\n",
637
+ file_descriptor,
638
+ file_encoding,
639
+ )
640
+ output_cabrillo_line(
641
+ f"NAME: {self.station.get('Name', '')}",
642
+ "\r\n",
643
+ file_descriptor,
644
+ file_encoding,
645
+ )
646
+ output_cabrillo_line(
647
+ f"ADDRESS: {self.station.get('Street1', '')}",
648
+ "\r\n",
649
+ file_descriptor,
650
+ file_encoding,
651
+ )
652
+ output_cabrillo_line(
653
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
654
+ "\r\n",
655
+ file_descriptor,
656
+ file_encoding,
657
+ )
658
+ output_cabrillo_line(
659
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
660
+ "\r\n",
661
+ file_descriptor,
662
+ file_encoding,
663
+ )
664
+ output_cabrillo_line(
665
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
666
+ "\r\n",
667
+ file_descriptor,
668
+ file_encoding,
669
+ )
670
+ output_cabrillo_line(
671
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
672
+ "\r\n",
673
+ file_descriptor,
674
+ file_encoding,
675
+ )
676
+ output_cabrillo_line(
677
+ f"EMAIL: {self.station.get('Email', '')}",
678
+ "\r\n",
679
+ file_descriptor,
680
+ file_encoding,
681
+ )
682
+ for contact in log:
683
+ the_date_and_time = contact.get("TS", "")
684
+ themode = contact.get("Mode", "")
685
+ if themode == "LSB" or themode == "USB":
686
+ themode = "PH"
687
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
688
+
689
+ loggeddate = the_date_and_time[:10]
690
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
691
+ output_cabrillo_line(
692
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
693
+ f"{contact.get('StationPrefix', '').ljust(13)} "
694
+ f"{str(contact.get('SNT', '')).ljust(3)} "
695
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
696
+ f"{contact.get('Call', '').ljust(13)} "
697
+ f"{str(contact.get('RCV', '')).ljust(3)} "
698
+ f"{str(contact.get('NR', '')).ljust(6)}",
699
+ "\r\n",
700
+ file_descriptor,
701
+ file_encoding,
702
+ )
703
+ output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
704
+ self.show_message_box(f"Cabrillo saved to: {filename}")
705
+ except IOError as exception:
706
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
707
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
708
+ return
709
+
710
+
711
+ def recalculate_mults(self):
712
+ """Recalculates multipliers after change in logged qso."""
713
+
714
+ all_contacts = self.database.fetch_all_contacts_asc()
715
+ for contact in all_contacts:
716
+ # recalculate points
717
+ _their_grid = contact.get("Exchange1") .upper()
718
+ _kilometers = distance(self.station.get("GridSquare", ""), _their_grid)
719
+ _points = max(1,_kilometers)
720
+ contact["Points"] = _points
721
+
722
+ self.database.change_contact(contact)
723
+
724
+
725
+ def process_esm(self, new_focused_widget=None, with_enter=False):
726
+ """ESM State Machine"""
727
+
728
+ # self.pref["run_state"]
729
+
730
+ # -----===== Assigned F-Keys =====-----
731
+ # self.esm_dict["CQ"]
732
+ # self.esm_dict["EXCH"]
733
+ # self.esm_dict["QRZ"]
734
+ # self.esm_dict["AGN"]
735
+ # self.esm_dict["HISCALL"]
736
+ # self.esm_dict["MYCALL"]
737
+ # self.esm_dict["QSOB4"]
738
+
739
+ # ----==== text fields ====----
740
+ # self.callsign
741
+ # self.sent
742
+ # self.receive
743
+ # self.other_1
744
+ # self.other_2
745
+
746
+ if new_focused_widget is not None:
747
+ self.current_widget = self.inputs_dict.get(new_focused_widget)
748
+
749
+ # print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
750
+
751
+ for a_button in [
752
+ self.F1,
753
+ self.F2,
754
+ self.F3,
755
+ self.F4,
756
+ self.F5,
757
+ self.F6,
758
+ self.F7,
759
+ self.F8,
760
+ self.F9,
761
+ self.F10,
762
+ self.F11,
763
+ self.F12,
764
+ ]:
765
+ self.restore_button_color(a_button)
766
+
767
+ buttons_to_send = []
768
+
769
+ if self.pref.get("run_state"):
770
+ if self.current_widget == "callsign":
771
+ if len(self.callsign.text()) < 3:
772
+ self.make_button_green(self.esm_dict["CQ"])
773
+ buttons_to_send.append(self.esm_dict["CQ"])
774
+ elif len(self.callsign.text()) > 2:
775
+ self.make_button_green(self.esm_dict["HISCALL"])
776
+ self.make_button_green(self.esm_dict["EXCH"])
777
+ buttons_to_send.append(self.esm_dict["HISCALL"])
778
+ buttons_to_send.append(self.esm_dict["EXCH"])
779
+
780
+ elif self.current_widget in ["other_1", "other_2"]:
781
+ if self.other_2.text() == "" or self.other_1.text() == "":
782
+ self.make_button_green(self.esm_dict["AGN"])
783
+ buttons_to_send.append(self.esm_dict["AGN"])
784
+ else:
785
+ self.make_button_green(self.esm_dict["QRZ"])
786
+ buttons_to_send.append(self.esm_dict["QRZ"])
787
+ buttons_to_send.append("LOGIT")
788
+
789
+ if with_enter is True and bool(len(buttons_to_send)):
790
+ for button in buttons_to_send:
791
+ if button:
792
+ if button == "LOGIT":
793
+ self.save_contact()
794
+ continue
795
+ self.process_function_key(button)
796
+ else:
797
+ if self.current_widget == "callsign":
798
+ if len(self.callsign.text()) > 2:
799
+ self.make_button_green(self.esm_dict["MYCALL"])
800
+ buttons_to_send.append(self.esm_dict["MYCALL"])
801
+
802
+ elif self.current_widget in ["other_1", "other_2"]:
803
+ if self.other_2.text() == "" or self.other_1.text() == "":
804
+ self.make_button_green(self.esm_dict["AGN"])
805
+ buttons_to_send.append(self.esm_dict["AGN"])
806
+ else:
807
+ self.make_button_green(self.esm_dict["EXCH"])
808
+ buttons_to_send.append(self.esm_dict["EXCH"])
809
+ buttons_to_send.append("LOGIT")
810
+
811
+ if with_enter is True and bool(len(buttons_to_send)):
812
+ for button in buttons_to_send:
813
+ if button:
814
+ if button == "LOGIT":
815
+ self.save_contact()
816
+ continue
817
+ self.process_function_key(button)
818
+
819
+
820
+ def populate_history_info_line(self):
821
+ result = self.database.fetch_call_history(self.callsign.text())
822
+ if result:
823
+ self.history_info.setText(
824
+ f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('Exch1', '')}, {result.get('UserText','...')}"
825
+ )
826
+ else:
827
+ self.history_info.setText("")
828
+
829
+
830
+ def check_call_history(self):
831
+ """"""
832
+ result = self.database.fetch_call_history(self.callsign.text())
833
+ if result:
834
+ self.history_info.setText(f"{result.get('UserText','')}")
835
+ if self.other_1.text() == "":
836
+ self.other_1.setText(f"{result.get('Exch1', '')}")
837
+
838
+
839
+ def get_mults(self):
840
+ """Get mults for RTC XML"""
841
+ mults = {}
842
+ mults["state"], mults["wpxprefix"] = show_mults(self, rtc=True)
843
+ return mults
844
+
845
+
846
+ def just_points(self):
847
+ """Get points for RTC XML"""
848
+ return get_points(self)
@@ -272,7 +272,7 @@ def calc_score(self) -> int:
272
272
 
273
273
  def adif(self) -> None:
274
274
  """Call the generate ADIF function"""
275
- gen_adif(self, cabrillo_name)
275
+ gen_adif(self, cabrillo_name, contest_id=cabrillo_name)
276
276
 
277
277
 
278
278
  def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: not1mm
3
- Version: 25.3.18
3
+ Version: 25.3.19
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
@@ -222,6 +222,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
222
222
  - CQ World Wide CW, RTTY, SSB
223
223
  - CWOps CWT
224
224
  - DARC Xmas
225
+ - DARC VHF
225
226
  - EA Majistad CW
226
227
  - EA RTTY
227
228
  - Helvetia
@@ -244,6 +245,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
244
245
 
245
246
  ## Recent Changes
246
247
 
248
+ - [25-3-19] Merged PR from @DD5ML Adding DARC VHF.
247
249
  - [25-3-18] Add His Maj King of Spain CW
248
250
  - [25-3-17] Add EA RTTY contest.
249
251
  - [25-3-14] Add call history support to ARR Field Day.
@@ -1,5 +1,5 @@
1
1
  not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- not1mm/__main__.py,sha256=wAXxJ1iEt-sQWOY7ULvrbmBucI_u4sdAXlmJb-3lbUc,148992
2
+ not1mm/__main__.py,sha256=SiXK9Vyxo-gNMy2cDz2KbN21ho5AhkahDavI0KmIiUQ,149512
3
3
  not1mm/bandmap.py,sha256=mdSK6oj8plEmr6WVYkzPTCfsHWKl9lea3R14cmRsAI4,31531
4
4
  not1mm/checkwindow.py,sha256=VFAcKYTcoWhmIf91chwY6tyao9FQMWPiUkgDDkkWaog,9670
5
5
  not1mm/fsutils.py,sha256=ukHKxKTeNKxKwqRaJjtzRShL4X5Xl0jRBbADyy3Ifp8,1701
@@ -32,8 +32,8 @@ not1mm/data/k6gte.not1mm-32.png,sha256=XdTsCa3xqwTfn26Ga7RwO_Vlbg_77RKkSc8bMxVcC
32
32
  not1mm/data/k6gte.not1mm-64.png,sha256=6ku45Gq1g5ezh04F07osoKRtanb3e4kbx5XdIEh3N90,2925
33
33
  not1mm/data/logwindow.ui,sha256=f7vULj96tHIQuR1nJMyvPHHcmVgzkhv9D1isyojsnFU,1458
34
34
  not1mm/data/logwindowx.ui,sha256=CwpI-h7cI1yqyldH9quKftsdHL5lTyL9ABOcf80nfqc,1632
35
- not1mm/data/main.ui,sha256=cYy2Zk0bDNK2cJOANivXheML4_y27CAmO7DR_yscNT0,62814
36
- not1mm/data/new_contest.ui,sha256=VyYECvpLj2VRX5KkfY8w2o7XCEr62UYVSjUmn3HukZE,24385
35
+ not1mm/data/main.ui,sha256=k7qmK-rnAN62t_YWyN5ZKK3-p1a3KREAVqU-SzKxEG8,63389
36
+ not1mm/data/new_contest.ui,sha256=_Eznl2rS830YHDH2rsGKGsKGaiLCcercQqe8GYJPmvw,24490
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=CR6tCOYIHJMwfisRcp1VgLJ1TE_lLHHfLZf98TqRqOM,48
119
+ not1mm/lib/version.py,sha256=xxIOV5hNtkeAby6sRH2WKMLOsJnak7kyLYV_w52eU_8,48
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,8 +144,9 @@ 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
148
  not1mm/plugins/darc_xmas.py,sha256=KmpFXWS1jKegPCvk8XZWlzUCshhtDww2AgTGtauricQ,18919
148
- not1mm/plugins/ea_majistad_cw.py,sha256=xLqEX5Q7FWoqm-59Vvx3ZA4dUHEKhQOjRzIf7HRLPg0,23275
149
+ not1mm/plugins/ea_majistad_cw.py,sha256=YBTfe9cNjz5dve8X1-h_DcUW4S77EzJDBtgr5jnIeP8,23301
149
150
  not1mm/plugins/ea_rtty.py,sha256=RBaavcn2CRcH3NuSx5YAPsChYY2BCKpES-8YT9FtS0E,23178
150
151
  not1mm/plugins/general_logging.py,sha256=eQuna-LnrWpf93LmHTTo6956GWoGocVfeYnzY5cyTmw,9600
151
152
  not1mm/plugins/helvetia.py,sha256=-aL4GYn3boRMJWVWqqS3xvXUgehB58-5cTs1jWTsnxE,20027
@@ -169,9 +170,9 @@ not1mm/plugins/ref_ssb.py,sha256=tGK5XeFrc3z7l8OViG9DM3rc4HLUBF9S3SUkaAPrjQk,215
169
170
  not1mm/plugins/stew_perry_topband.py,sha256=LHt0WnWMRS_m5nO9BOIQs0kO38M6x-k4eaA4nbEqDVA,15353
170
171
  not1mm/plugins/weekly_rtty.py,sha256=4gfFg25KGkU9tKmwslHLc38qPAXuRGWNX48n582NC7w,20078
171
172
  not1mm/plugins/winter_field_day.py,sha256=jLgEr95hJCZoc3Fi95PiNeB06thPQHFI3zOHmR6NprE,15234
172
- not1mm-25.3.18.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
173
- not1mm-25.3.18.dist-info/METADATA,sha256=94zc9FQxHCXcFQ1ZWuQbOZR5ZM2F_DQQn3a7Ax5qjBk,37096
174
- not1mm-25.3.18.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
175
- not1mm-25.3.18.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
176
- not1mm-25.3.18.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
177
- not1mm-25.3.18.dist-info/RECORD,,
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,,