not1mm 23.3.25__py3-none-any.whl → 23.3.27__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
@@ -663,7 +663,7 @@ class MainWindow(QtWidgets.QMainWindow):
663
663
 
664
664
  def select_contest(self):
665
665
  """Load contest"""
666
- self.contest = doimp("cq_wpx_ssb")
666
+ self.contest = doimp("cq_wpx_cw")
667
667
  logger.debug("Loaded Contest Name = %s", self.contest.name)
668
668
  self.contest.init_contest(self)
669
669
 
@@ -984,10 +984,12 @@ class MainWindow(QtWidgets.QMainWindow):
984
984
  """Called when text in the callsign field has changed"""
985
985
  text = self.callsign.text()
986
986
  text = text.upper()
987
- stripped_text = text.strip()
987
+ position = self.callsign.cursorPosition()
988
+ stripped_text = text.strip().replace(" ", "")
988
989
  self.callsign.setText(stripped_text)
990
+ self.callsign.setCursorPosition(position)
989
991
 
990
- if text[-1:] == " ":
992
+ if " " in text:
991
993
  if stripped_text == "CW":
992
994
  self.setmode("CW")
993
995
  self.radio_state["mode"] = "CW"
@@ -1113,9 +1115,18 @@ class MainWindow(QtWidgets.QMainWindow):
1113
1115
  """Checks if a callsign is a dupe on current band/mode."""
1114
1116
  band = float(get_logged_band(str(self.radio_state.get("vfoa", 0.0))))
1115
1117
  mode = self.radio_state.get("mode", "")
1116
- debugline = f"Call: {call} Band: {band} Mode: {mode}"
1118
+ debugline = (
1119
+ f"Call: {call} Band: {band} Mode: {mode} Dupetype: {self.contest.dupe_type}"
1120
+ )
1117
1121
  logger.debug("%s", debugline)
1118
- result = self.database.check_dupe_on_band_mode(call, band, mode)
1122
+ if self.contest.dupe_type == 1:
1123
+ result = self.database.check_dupe(call)
1124
+ if self.contest.dupe_type == 2:
1125
+ result = self.database.check_dupe_on_band(call, band)
1126
+ if self.contest.dupe_type == 3:
1127
+ result = self.database.check_dupe_on_band_mode(call, band, mode)
1128
+ if self.contest.dupe_type == 4:
1129
+ result = {"isdupe": False}
1119
1130
  debugline = f"{result}"
1120
1131
  logger.debug("%s", debugline)
1121
1132
  return result.get("isdupe", False)
@@ -1242,126 +1253,7 @@ class MainWindow(QtWidgets.QMainWindow):
1242
1253
  """Generates Cabrillo file. Maybe."""
1243
1254
  # https://www.cqwpx.com/cabrillo.htm
1244
1255
  logger.debug("******Cabrillo*****")
1245
- filename = (
1246
- str(Path.home())
1247
- + "/"
1248
- + f"{self.pref.get('callsign').upper()}_{self.contest.cabrillo_name}.log"
1249
- )
1250
- logger.debug("%s", filename)
1251
- log = self.database.fetch_all_contacts_asc()
1252
- try:
1253
- with open(filename, "w", encoding="ascii") as file_descriptor:
1254
- print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
1255
- print(
1256
- f"CREATED-BY: Not1MM v{__version__}",
1257
- end="\r\n",
1258
- file=file_descriptor,
1259
- )
1260
- print(
1261
- f"CONTEST: {self.contest.cabrillo_name}",
1262
- end="\r\n",
1263
- file=file_descriptor,
1264
- )
1265
- print(
1266
- f"CALLSIGN: {self.pref.get('callsign','')}",
1267
- end="\r\n",
1268
- file=file_descriptor,
1269
- )
1270
- print(
1271
- f"LOCATION: {self.pref.get('section', '')}",
1272
- end="\r\n",
1273
- file=file_descriptor,
1274
- )
1275
- # print(
1276
- # f"ARRL-SECTION: {self.pref.get('section', '')}",
1277
- # end="\r\n",
1278
- # file=file_descriptor,
1279
- # )
1280
- # CATEGORY-OPERATOR: SINGLE-OP
1281
- # CATEGORY-ASSISTED: NON-ASSISTED
1282
- # CATEGORY-BAND: ALL
1283
- # CATEGORY-MODE: SSB
1284
- # CATEGORY-TRANSMITTER: ONE
1285
- # CATEGORY-OVERLAY: CLASSIC
1286
- # GRID-LOCATOR: DM13at
1287
- print(
1288
- f"CATEGORY: {None}",
1289
- end="\r\n",
1290
- file=file_descriptor,
1291
- )
1292
- print("CATEGORY-POWER: ", end="\r\n", file=file_descriptor)
1293
-
1294
- print(
1295
- f"CLAIMED-SCORE: {self.contest.calc_score(self)}",
1296
- end="\r\n",
1297
- file=file_descriptor,
1298
- )
1299
- print(
1300
- "OPERATORS: ",
1301
- end="\r\n",
1302
- file=file_descriptor,
1303
- )
1304
- print(
1305
- f"NAME: {self.pref.get('name', '')}",
1306
- end="\r\n",
1307
- file=file_descriptor,
1308
- )
1309
- print(
1310
- f"ADDRESS: {self.pref.get('address1', '')}",
1311
- end="\r\n",
1312
- file=file_descriptor,
1313
- )
1314
- print(
1315
- f"ADDRESS-CITY: {self.pref.get('city', '')}",
1316
- end="\r\n",
1317
- file=file_descriptor,
1318
- )
1319
- print(
1320
- f"ADDRESS-STATE-PROVINCE: {self.pref.get('state', '')}",
1321
- end="\r\n",
1322
- file=file_descriptor,
1323
- )
1324
- print(
1325
- f"ADDRESS-POSTALCODE: {self.pref.get('zip', '')}",
1326
- end="\r\n",
1327
- file=file_descriptor,
1328
- )
1329
- print(
1330
- f"ADDRESS-COUNTRY: {self.pref.get('country', '')}",
1331
- end="\r\n",
1332
- file=file_descriptor,
1333
- )
1334
- print(
1335
- f"EMAIL: {self.pref.get('email', '')}",
1336
- end="\r\n",
1337
- file=file_descriptor,
1338
- )
1339
- for contact in log:
1340
- the_date_and_time = contact.get("TS", "")
1341
- mode = contact.get("Mode", "")
1342
- if mode == "LSB" or mode == "USB":
1343
- mode = "PH"
1344
- frequency = str(int(contact.get("Freq", "0"))).rjust(5)
1345
-
1346
- loggeddate = the_date_and_time[:10]
1347
- loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
1348
- print(
1349
- f"QSO: {frequency} {mode} {loggeddate} {loggedtime} "
1350
- f"{contact.get('StationPrefix', '').ljust(13)} "
1351
- f"{str(contact.get('SNT', '')).ljust(3)} "
1352
- f"{str(contact.get('SentNr', '')).ljust(6)} "
1353
- f"{contact.get('Call', '').ljust(13)} "
1354
- f"{str(contact.get('RCV', '')).ljust(3)} "
1355
- f"{str(contact.get('NR', '')).ljust(6)}",
1356
- end="\r\n",
1357
- file=file_descriptor,
1358
- )
1359
- print("END-OF-LOG:", end="\r\n", file=file_descriptor)
1360
- except IOError as exception:
1361
- logger.critical(
1362
- "cabrillo: IO error: %s, writing to %s", exception, filename
1363
- )
1364
- return
1256
+ self.contest.cabrillo(self)
1365
1257
 
1366
1258
 
1367
1259
  def load_fonts_from_dir(directory: str) -> set:
not1mm/lib/database.py CHANGED
@@ -370,6 +370,30 @@ class DataBase:
370
370
  )
371
371
  return cursor.fetchone()
372
372
 
373
+ def check_dupe_on_band(self, call, band) -> dict:
374
+ """Checks if a call is dupe on band/mode"""
375
+ with sqlite3.connect(self.database) as conn:
376
+ conn.row_factory = self.row_factory
377
+ cursor = conn.cursor()
378
+ print(
379
+ f"select count(*) as isdupe from dxlog where Call = '{call}' and Band = '{band}';"
380
+ )
381
+ cursor.execute(
382
+ f"select count(*) as isdupe from dxlog where Call = '{call}' and Band = '{band}';"
383
+ )
384
+ return cursor.fetchone()
385
+
386
+ def check_dupe(self, call) -> dict:
387
+ """Checks if a call is dupe on band/mode"""
388
+ with sqlite3.connect(self.database) as conn:
389
+ conn.row_factory = self.row_factory
390
+ cursor = conn.cursor()
391
+ print(f"select count(*) as isdupe from dxlog where Call = '{call}';")
392
+ cursor.execute(
393
+ f"select count(*) as isdupe from dxlog where Call = '{call}';"
394
+ )
395
+ return cursor.fetchone()
396
+
373
397
  def fetch_points(self) -> dict:
374
398
  """return points"""
375
399
  with sqlite3.connect(self.database) as conn:
not1mm/lib/version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  """It's the version"""
2
- __version__ = "23.3.25"
2
+ __version__ = "23.3.27"
@@ -0,0 +1,389 @@
1
+ """CQ WPX CW plugin"""
2
+
3
+ # pylint: disable=invalid-name
4
+ import logging
5
+ from pathlib import Path
6
+
7
+ from PyQt5 import QtWidgets
8
+
9
+ from not1mm.lib.version import __version__
10
+
11
+ logger = logging.getLogger("__main__")
12
+
13
+ name = "CQ WPX CW"
14
+ cabrillo_name = "CQ-WPX-CW"
15
+ mode = "CW" # CW SSB BOTH RTTY
16
+
17
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
18
+ dupe_type = 2
19
+
20
+
21
+ def init_contest(self):
22
+ """setup plugin"""
23
+ set_tab_next(self)
24
+ set_tab_prev(self)
25
+ interface(self)
26
+ self.next_field = self.other_2
27
+
28
+
29
+ def interface(self):
30
+ """Setup user interface"""
31
+ self.field1.show()
32
+ self.field2.show()
33
+ self.field3.show()
34
+ self.field4.show()
35
+ label = self.field3.findChild(QtWidgets.QLabel)
36
+ label.setText("SentNR")
37
+ label = self.field4.findChild(QtWidgets.QLabel)
38
+ label.setText("RcvNR")
39
+
40
+
41
+ def set_tab_next(self):
42
+ """Set TAB Advances"""
43
+ self.tab_next = {
44
+ self.callsign: self.field1.findChild(QtWidgets.QLineEdit),
45
+ self.field1.findChild(QtWidgets.QLineEdit): self.field2.findChild(
46
+ QtWidgets.QLineEdit
47
+ ),
48
+ self.field2.findChild(QtWidgets.QLineEdit): self.field3.findChild(
49
+ QtWidgets.QLineEdit
50
+ ),
51
+ self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
52
+ QtWidgets.QLineEdit
53
+ ),
54
+ self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
55
+ }
56
+
57
+
58
+ def set_tab_prev(self):
59
+ """Set TAB Advances"""
60
+ self.tab_prev = {
61
+ self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
62
+ self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
63
+ self.field2.findChild(QtWidgets.QLineEdit): self.field1.findChild(
64
+ QtWidgets.QLineEdit
65
+ ),
66
+ self.field3.findChild(QtWidgets.QLineEdit): self.field2.findChild(
67
+ QtWidgets.QLineEdit
68
+ ),
69
+ self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
70
+ QtWidgets.QLineEdit
71
+ ),
72
+ }
73
+
74
+
75
+ def set_contact_vars(self):
76
+ """Contest Specific"""
77
+ self.contact["SNT"] = self.sent.text()
78
+ self.contact["RCV"] = self.receive.text()
79
+ self.contact["SentNr"] = self.other_1.text()
80
+ self.contact["NR"] = self.other_2.text()
81
+ if self.contact.get("WPXPrefix"):
82
+ result = self.database.fetch_wpx_exists(self.contact.get("WPXPrefix", ""))
83
+ if result.get("wpx_count"):
84
+ self.contact["IsMultiplier1"] = 0
85
+ else:
86
+ self.contact["IsMultiplier1"] = 1
87
+
88
+
89
+ def prefill(self):
90
+ """Fill SentNR"""
91
+ result = self.database.get_serial()
92
+ serial_nr = str(result.get("serial_nr", "1"))
93
+ if serial_nr == "None":
94
+ serial_nr = "1"
95
+ field = self.field3.findChild(QtWidgets.QLineEdit)
96
+ if len(field.text()) == 0:
97
+ field.setText(serial_nr)
98
+
99
+
100
+ def points(self):
101
+ """Calc point"""
102
+ result = self.cty_lookup(self.pref.get("callsign", ""))
103
+ if result:
104
+ for item in result.items():
105
+ mycountry = item[1].get("entity", "")
106
+ mycontinent = item[1].get("continent", "")
107
+ result = self.cty_lookup(self.contact.get("Call", ""))
108
+ band = int(int(float(self.contact.get("Freq"))) / 1000)
109
+ if result:
110
+ for item in result.items():
111
+ entity = item[1].get("entity", "")
112
+ continent = item[1].get("continent", "")
113
+ if mycountry.upper() == entity.upper():
114
+ return 1
115
+ if mycontinent and continent == "NA":
116
+ if band in [28, 21, 14]:
117
+ return 2
118
+ return 4
119
+ if mycontinent == continent:
120
+ if band in [28, 21, 14]:
121
+ return 1
122
+ return 2
123
+ if band in [28, 21, 14]:
124
+ return 3
125
+ return 6
126
+ return 0
127
+
128
+
129
+ def show_mults(self):
130
+ """Return display string for mults"""
131
+ result = self.database.fetch_wpx_count()
132
+ if result:
133
+ return int(result.get("wpx_count", 0))
134
+ return 0
135
+
136
+
137
+ def show_qso(self):
138
+ """Return qso count"""
139
+ result = self.database.fetch_qso_count()
140
+ if result:
141
+ return int(result.get("qsos", 0))
142
+ return 0
143
+
144
+
145
+ def get_points(self):
146
+ """Return raw points before mults"""
147
+ result = self.database.fetch_points()
148
+ if result:
149
+ return int(result.get("Points", 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
+ result = self.database.fetch_wpx_count()
162
+ mults = int(result.get("wpx_count", 0))
163
+ return contest_points * mults
164
+ return 0
165
+
166
+
167
+ def adif(self):
168
+ """
169
+ Creates an ADIF file of the contacts made.
170
+ """
171
+ filename = (
172
+ str(Path.home())
173
+ + "/"
174
+ + f"{self.pref.get('callsign').upper()}_{cabrillo_name}.adi"
175
+ )
176
+ log = self.database.fetch_all_contacts_asc()
177
+ try:
178
+ with open(filename, "w", encoding="utf-8") as file_descriptor:
179
+ print("<ADIF_VER:5>2.2.0", end="\r\n", file=file_descriptor)
180
+ print("<EOH>", end="\r\n", file=file_descriptor)
181
+ for contact in log:
182
+
183
+ hiscall = contact.get("Call", "")
184
+ the_date_and_time = contact.get("TS")
185
+ # band = contact.get("Band")
186
+ themode = contact.get("Mode")
187
+ frequency = str(contact.get("Freq", 0) / 1000)
188
+ sentrst = contact.get("SNT", "")
189
+ rcvrst = contact.get("RCV", "")
190
+ sentnr = str(contact.get("SentNr", "59"))
191
+ rcvnr = str(contact.get("NR", "59"))
192
+ grid = contact.get("GridSquare", "")
193
+ comment = contact.get("ContestName", "")
194
+ loggeddate = the_date_and_time[:10]
195
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
196
+ print(
197
+ f"<QSO_DATE:{len(''.join(loggeddate.split('-')))}:d>"
198
+ f"{''.join(loggeddate.split('-'))}",
199
+ end="\r\n",
200
+ file=file_descriptor,
201
+ )
202
+ print(
203
+ f"<TIME_ON:{len(loggedtime)}>{loggedtime}",
204
+ end="\r\n",
205
+ file=file_descriptor,
206
+ )
207
+ print(
208
+ f"<CALL:{len(hiscall)}>{hiscall}",
209
+ end="\r\n",
210
+ file=file_descriptor,
211
+ )
212
+ print(
213
+ f"<MODE:{len(themode)}>{themode}", end="\r\n", file=file_descriptor
214
+ )
215
+ # print(
216
+ # f"<BAND:{len(band + 'M')}>{band + 'M'}",
217
+ # end="\r\n",
218
+ # file=file_descriptor,
219
+ # )
220
+ try:
221
+ print(
222
+ f"<FREQ:{len(frequency)}>{frequency}",
223
+ end="\r\n",
224
+ file=file_descriptor,
225
+ )
226
+ except TypeError:
227
+ pass # This is bad form... I can't remember why this is in a try block
228
+
229
+ print(
230
+ f"<RST_SENT:{len(sentrst)}>{sentrst}",
231
+ end="\r\n",
232
+ file=file_descriptor,
233
+ )
234
+ print(
235
+ f"<RST_RCVD:{len(rcvrst)}>{rcvrst}",
236
+ end="\r\n",
237
+ file=file_descriptor,
238
+ )
239
+
240
+ print(
241
+ f"<STX_STRING:{len(sentnr)}>{sentnr}",
242
+ end="\r\n",
243
+ file=file_descriptor,
244
+ )
245
+ print(
246
+ f"<SRX_STRING:{len(rcvnr)}>{rcvnr}",
247
+ end="\r\n",
248
+ file=file_descriptor,
249
+ )
250
+ if len(grid) > 1:
251
+ print(
252
+ f"<GRIDSQUARE:{len(grid)}>{grid}",
253
+ end="\r\n",
254
+ file=file_descriptor,
255
+ )
256
+
257
+ print(
258
+ f"<COMMENT:{len(comment)}>{comment}",
259
+ end="\r\n",
260
+ file=file_descriptor,
261
+ )
262
+ print("<EOR>", end="\r\n", file=file_descriptor)
263
+ print("", end="\r\n", file=file_descriptor)
264
+ except IOError:
265
+ ...
266
+
267
+
268
+ def cabrillo(self):
269
+ """Generates Cabrillo file. Maybe."""
270
+ # https://www.cqwpx.com/cabrillo.htm
271
+ logger.debug("******Cabrillo*****")
272
+ filename = (
273
+ str(Path.home())
274
+ + "/"
275
+ + f"{self.pref.get('callsign').upper()}_{cabrillo_name}.log"
276
+ )
277
+ logger.debug("%s", filename)
278
+ log = self.database.fetch_all_contacts_asc()
279
+ try:
280
+ with open(filename, "w", encoding="ascii") as file_descriptor:
281
+ print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
282
+ print(
283
+ f"CREATED-BY: Not1MM v{__version__}",
284
+ end="\r\n",
285
+ file=file_descriptor,
286
+ )
287
+ print(
288
+ f"CONTEST: {cabrillo_name}",
289
+ end="\r\n",
290
+ file=file_descriptor,
291
+ )
292
+ print(
293
+ f"CALLSIGN: {self.pref.get('callsign','')}",
294
+ end="\r\n",
295
+ file=file_descriptor,
296
+ )
297
+ print(
298
+ f"LOCATION: {self.pref.get('section', '')}",
299
+ end="\r\n",
300
+ file=file_descriptor,
301
+ )
302
+ # print(
303
+ # f"ARRL-SECTION: {self.pref.get('section', '')}",
304
+ # end="\r\n",
305
+ # file=file_descriptor,
306
+ # )
307
+ # CATEGORY-OPERATOR: SINGLE-OP
308
+ # CATEGORY-ASSISTED: NON-ASSISTED
309
+ # CATEGORY-BAND: ALL
310
+ # CATEGORY-MODE: SSB
311
+ # CATEGORY-TRANSMITTER: ONE
312
+ # CATEGORY-OVERLAY: CLASSIC
313
+ # GRID-LOCATOR: DM13at
314
+ print(
315
+ f"CATEGORY: {None}",
316
+ end="\r\n",
317
+ file=file_descriptor,
318
+ )
319
+ print("CATEGORY-POWER: ", end="\r\n", file=file_descriptor)
320
+
321
+ print(
322
+ f"CLAIMED-SCORE: {calc_score(self)}",
323
+ end="\r\n",
324
+ file=file_descriptor,
325
+ )
326
+ print(
327
+ "OPERATORS: ",
328
+ end="\r\n",
329
+ file=file_descriptor,
330
+ )
331
+ print(
332
+ f"NAME: {self.pref.get('name', '')}",
333
+ end="\r\n",
334
+ file=file_descriptor,
335
+ )
336
+ print(
337
+ f"ADDRESS: {self.pref.get('address1', '')}",
338
+ end="\r\n",
339
+ file=file_descriptor,
340
+ )
341
+ print(
342
+ f"ADDRESS-CITY: {self.pref.get('city', '')}",
343
+ end="\r\n",
344
+ file=file_descriptor,
345
+ )
346
+ print(
347
+ f"ADDRESS-STATE-PROVINCE: {self.pref.get('state', '')}",
348
+ end="\r\n",
349
+ file=file_descriptor,
350
+ )
351
+ print(
352
+ f"ADDRESS-POSTALCODE: {self.pref.get('zip', '')}",
353
+ end="\r\n",
354
+ file=file_descriptor,
355
+ )
356
+ print(
357
+ f"ADDRESS-COUNTRY: {self.pref.get('country', '')}",
358
+ end="\r\n",
359
+ file=file_descriptor,
360
+ )
361
+ print(
362
+ f"EMAIL: {self.pref.get('email', '')}",
363
+ end="\r\n",
364
+ file=file_descriptor,
365
+ )
366
+ for contact in log:
367
+ the_date_and_time = contact.get("TS", "")
368
+ themode = contact.get("Mode", "")
369
+ if themode == "LSB" or themode == "USB":
370
+ themode = "PH"
371
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
372
+
373
+ loggeddate = the_date_and_time[:10]
374
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
375
+ print(
376
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
377
+ f"{contact.get('StationPrefix', '').ljust(13)} "
378
+ f"{str(contact.get('SNT', '')).ljust(3)} "
379
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
380
+ f"{contact.get('Call', '').ljust(13)} "
381
+ f"{str(contact.get('RCV', '')).ljust(3)} "
382
+ f"{str(contact.get('NR', '')).ljust(6)}",
383
+ end="\r\n",
384
+ file=file_descriptor,
385
+ )
386
+ print("END-OF-LOG:", end="\r\n", file=file_descriptor)
387
+ except IOError as exception:
388
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
389
+ return
@@ -1,15 +1,21 @@
1
1
  """CQ WPX SSB plugin"""
2
2
 
3
3
  # pylint: disable=invalid-name
4
+ import logging
5
+ from pathlib import Path
4
6
 
5
7
  from PyQt5 import QtWidgets
6
8
 
9
+ from not1mm.lib.version import __version__
10
+
11
+ logger = logging.getLogger("__main__")
12
+
7
13
  name = "CQ WPX SSB"
8
14
  cabrillo_name = "CQ-WPX-SSB"
9
15
  mode = "SSB" # CW SSB BOTH RTTY
10
16
 
11
17
  # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
12
- dupe_type = 4
18
+ dupe_type = 2
13
19
 
14
20
 
15
21
  def init_contest(self):
@@ -162,17 +168,21 @@ def adif(self):
162
168
  """
163
169
  Creates an ADIF file of the contacts made.
164
170
  """
165
- logname = "cqwpxssb.adi"
171
+ filename = (
172
+ str(Path.home())
173
+ + "/"
174
+ + f"{self.pref.get('callsign').upper()}_{cabrillo_name}.adi"
175
+ )
166
176
  log = self.database.fetch_all_contacts_asc()
167
177
  try:
168
- with open(logname, "w", encoding="utf-8") as file_descriptor:
178
+ with open(filename, "w", encoding="utf-8") as file_descriptor:
169
179
  print("<ADIF_VER:5>2.2.0", end="\r\n", file=file_descriptor)
170
180
  print("<EOH>", end="\r\n", file=file_descriptor)
171
181
  for contact in log:
172
182
 
173
183
  hiscall = contact.get("Call", "")
174
184
  the_date_and_time = contact.get("TS")
175
- band = contact.get("Band")
185
+ # band = contact.get("Band")
176
186
  themode = contact.get("Mode")
177
187
  frequency = str(contact.get("Freq", 0) / 1000)
178
188
  sentrst = contact.get("SNT", "")
@@ -253,3 +263,127 @@ def adif(self):
253
263
  print("", end="\r\n", file=file_descriptor)
254
264
  except IOError:
255
265
  ...
266
+
267
+
268
+ def cabrillo(self):
269
+ """Generates Cabrillo file. Maybe."""
270
+ # https://www.cqwpx.com/cabrillo.htm
271
+ logger.debug("******Cabrillo*****")
272
+ filename = (
273
+ str(Path.home())
274
+ + "/"
275
+ + f"{self.pref.get('callsign').upper()}_{cabrillo_name}.log"
276
+ )
277
+ logger.debug("%s", filename)
278
+ log = self.database.fetch_all_contacts_asc()
279
+ try:
280
+ with open(filename, "w", encoding="ascii") as file_descriptor:
281
+ print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
282
+ print(
283
+ f"CREATED-BY: Not1MM v{__version__}",
284
+ end="\r\n",
285
+ file=file_descriptor,
286
+ )
287
+ print(
288
+ f"CONTEST: {cabrillo_name}",
289
+ end="\r\n",
290
+ file=file_descriptor,
291
+ )
292
+ print(
293
+ f"CALLSIGN: {self.pref.get('callsign','')}",
294
+ end="\r\n",
295
+ file=file_descriptor,
296
+ )
297
+ print(
298
+ f"LOCATION: {self.pref.get('section', '')}",
299
+ end="\r\n",
300
+ file=file_descriptor,
301
+ )
302
+ # print(
303
+ # f"ARRL-SECTION: {self.pref.get('section', '')}",
304
+ # end="\r\n",
305
+ # file=file_descriptor,
306
+ # )
307
+ # CATEGORY-OPERATOR: SINGLE-OP
308
+ # CATEGORY-ASSISTED: NON-ASSISTED
309
+ # CATEGORY-BAND: ALL
310
+ # CATEGORY-MODE: SSB
311
+ # CATEGORY-TRANSMITTER: ONE
312
+ # CATEGORY-OVERLAY: CLASSIC
313
+ # GRID-LOCATOR: DM13at
314
+ print(
315
+ f"CATEGORY: {None}",
316
+ end="\r\n",
317
+ file=file_descriptor,
318
+ )
319
+ print("CATEGORY-POWER: ", end="\r\n", file=file_descriptor)
320
+
321
+ print(
322
+ f"CLAIMED-SCORE: {calc_score(self)}",
323
+ end="\r\n",
324
+ file=file_descriptor,
325
+ )
326
+ print(
327
+ "OPERATORS: ",
328
+ end="\r\n",
329
+ file=file_descriptor,
330
+ )
331
+ print(
332
+ f"NAME: {self.pref.get('name', '')}",
333
+ end="\r\n",
334
+ file=file_descriptor,
335
+ )
336
+ print(
337
+ f"ADDRESS: {self.pref.get('address1', '')}",
338
+ end="\r\n",
339
+ file=file_descriptor,
340
+ )
341
+ print(
342
+ f"ADDRESS-CITY: {self.pref.get('city', '')}",
343
+ end="\r\n",
344
+ file=file_descriptor,
345
+ )
346
+ print(
347
+ f"ADDRESS-STATE-PROVINCE: {self.pref.get('state', '')}",
348
+ end="\r\n",
349
+ file=file_descriptor,
350
+ )
351
+ print(
352
+ f"ADDRESS-POSTALCODE: {self.pref.get('zip', '')}",
353
+ end="\r\n",
354
+ file=file_descriptor,
355
+ )
356
+ print(
357
+ f"ADDRESS-COUNTRY: {self.pref.get('country', '')}",
358
+ end="\r\n",
359
+ file=file_descriptor,
360
+ )
361
+ print(
362
+ f"EMAIL: {self.pref.get('email', '')}",
363
+ end="\r\n",
364
+ file=file_descriptor,
365
+ )
366
+ for contact in log:
367
+ the_date_and_time = contact.get("TS", "")
368
+ themode = contact.get("Mode", "")
369
+ if themode == "LSB" or themode == "USB":
370
+ themode = "PH"
371
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
372
+
373
+ loggeddate = the_date_and_time[:10]
374
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
375
+ print(
376
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
377
+ f"{contact.get('StationPrefix', '').ljust(13)} "
378
+ f"{str(contact.get('SNT', '')).ljust(3)} "
379
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
380
+ f"{contact.get('Call', '').ljust(13)} "
381
+ f"{str(contact.get('RCV', '')).ljust(3)} "
382
+ f"{str(contact.get('NR', '')).ljust(6)}",
383
+ end="\r\n",
384
+ file=file_descriptor,
385
+ )
386
+ print("END-OF-LOG:", end="\r\n", file=file_descriptor)
387
+ except IOError as exception:
388
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
389
+ return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 23.3.25
3
+ Version: 23.3.27
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
@@ -44,6 +44,7 @@ Requires-Dist: xmltodict
44
44
  - [Log Display](#log-display)
45
45
  - [Editing a contact](#editing-a-contact)
46
46
  - [Cabrillo](#cabrillo)
47
+ - [ADIF](#adif)
47
48
  - [Dupe checking](#dupe-checking)
48
49
  - [CAT](#cat)
49
50
 
@@ -74,6 +75,7 @@ Feature complete.
74
75
 
75
76
  ## Changes of note
76
77
 
78
+ - [23-3-27] Fix cursor behaviour when editing text in callsign field.
77
79
  - [23-3-25] Fix minimum call length. Fix cabrillo tag. Add adif output.
78
80
  - [23-3-24] Added dupe checking. Added CAT check for flrig or rigctld. Added online flag for flrig.
79
81
  - [23-3-23] Added most of Cabrillo generation. Plan to test it this weekends CQ WPX SSB.
@@ -197,6 +199,14 @@ So for me it would be:
197
199
 
198
200
  K6GTE_CQ-WPX-SSB.log
199
201
 
202
+ ## ADIF
203
+
204
+ `File` > `Generate ADIF`
205
+
206
+ Boom... ADIF
207
+
208
+ `StationCall`_`ContestName`.adi
209
+
200
210
  ## Dupe checking
201
211
 
202
212
  Added dupe checking. Big Red 'Dupe' will appear if it's a dupe...
@@ -1,5 +1,5 @@
1
1
  not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- not1mm/__main__.py,sha256=Elky0MhRFYUqybtw7LDuLOq2LWu_KOpjlhanYMmK_wo,54824
2
+ not1mm/__main__.py,sha256=oVY2SStvSXwOb_kWCmKSUquEQ6etJluzKz4EpERvoJo,50566
3
3
  not1mm/logwindow.py,sha256=yjBaHKlAUA3nDeZdBIT6-IGsHi-PZGuV1Kgolxunurk,24930
4
4
  not1mm/test.py,sha256=sCAd6OZQlakGm2gMbjhwZ17UyI-Y5L2CCqsYymx7IPQ,3906
5
5
  not1mm/data/Combinear.qss,sha256=SKqM0g8GvNXay1ovgtwCw3Egt0eLfN5P3iTREInC1eE,16590
@@ -25,7 +25,7 @@ not1mm/data/use_qrz_dialog.ui,sha256=sXV1K1tsmYEF7K8nnV_t_UR3k1PzQp43CgvX4KSnR94
25
25
  not1mm/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  not1mm/lib/cat_interface.py,sha256=5EhVLWfMOvg-zLkLTGtNLJj2VohxG48uaMCelEdL1wg,10342
27
27
  not1mm/lib/cwinterface.py,sha256=77I7RFtrIljuuWna3mjkjxaPSM1kGaPV4duPkoiT8wA,1772
28
- not1mm/lib/database.py,sha256=HBGiZI4cHk8SLhqzzLEvBztvmbk5LI4jaiPS9quJTZQ,16105
28
+ not1mm/lib/database.py,sha256=SCr97eurpJfongb_mA_-UCNxkNiqCJsPSdTxsSK12Hs,17127
29
29
  not1mm/lib/edit_contact.py,sha256=YwuX-BuIa7AuPtLRENs4jTzxOrtk6MCxZj3BR_bDPW8,357
30
30
  not1mm/lib/edit_macro.py,sha256=lyToZb1nmcONNFh6W35NzYHLU48gbAs2_OsnuRQGHck,559
31
31
  not1mm/lib/edit_opon.py,sha256=GqAOJMiC265_4YRVbkT1PflBuCa4HiCNfRhq8-J6ZVY,363
@@ -35,7 +35,7 @@ not1mm/lib/lookup.py,sha256=4OiWZWc3smcB0lqLk4WTs1U3i2k8yZFsX_1OoCGlaWc,13916
35
35
  not1mm/lib/multicast.py,sha256=4-vesMxt5n_pDk2oYnL7R_exxLl9C197t569AM2lrD4,1954
36
36
  not1mm/lib/n1mm.py,sha256=bK5d21Yfn6xRpQcu2RdpL2zR8lOlRWOadD6Ai4_lFdc,4434
37
37
  not1mm/lib/qrz_dialog.py,sha256=fLFBkvQ9cuIqKk0-1yl5OFuQ40n904fNi_Vt23je99E,350
38
- not1mm/lib/version.py,sha256=lFtHjY0o2X2P460opiDclTNgfIXBtbZ-JODvJlsswNo,47
38
+ not1mm/lib/version.py,sha256=H3AM53QOlozSvTFVbi7jIqx9rOS1-MEL3_qaM4R7rKU,47
39
39
  not1mm/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  not1mm/plugins/arrl_dx_cw.py,sha256=VRP-H65SgEaCff6efF85DzU5KMoECkLQad4DraNgUec,1382
41
41
  not1mm/plugins/arrl_dx_phone.py,sha256=9uLZWogzTfLm0SjmcG149dTG_GjDbbVhdInl4Uz7Fck,1385
@@ -43,14 +43,15 @@ not1mm/plugins/arrl_field_day.py,sha256=GJhdpkX9pfm8imfIhKKSQh36PRpK4DrqDH3kcN5Z
43
43
  not1mm/plugins/arrl_rtty_ru.py,sha256=_cOuXmGTpQ2xbDOEzFVKuitmVlB_F2P5vP3x3fcsDa8,1390
44
44
  not1mm/plugins/arrl_ss_cw.py,sha256=Y0sYwcbzZGcR4843QkMCzZ8RBjXPtJFEa87TWyAGCBA,1391
45
45
  not1mm/plugins/arrl_ss_phone.py,sha256=4AY_S5wx-L0dC5pFLCDTX0FNdxTDFeg_YpaX-7z8nrY,1394
46
- not1mm/plugins/cq_wpx_ssb.py,sha256=hPQFvHYiS8chnFLWjen1HabqfEK6an1pkk7yNvdw2EY,8185
46
+ not1mm/plugins/cq_wpx_cw.py,sha256=rEWFFBfhudT8X3GP1Vn4L8Q6vKrX9jsh5_NkVkTY6SI,12822
47
+ not1mm/plugins/cq_wpx_ssb.py,sha256=3WHd_aUyG1yZLAF3IWEAvR92a0QlP_ss7rgLoqagv6s,12826
47
48
  not1mm/plugins/cqww_dx_cw.py,sha256=eKBIQ8WdJXlGtSTDds7BuoFPpn3odEoiiu_RIQQLHb8,2086
48
49
  not1mm/plugins/cqww_dx_ssb.py,sha256=7lPh-VH8nb-qQ-9wYx5pd6Es_qSbiL3ETHpibqhH_r0,2090
49
50
  not1mm/plugins/general_logging.py,sha256=UwHO3g84bghuIaa1JyqMeMFVfmMRvLgV3NQY3zZWW-w,2077
50
51
  not1mm/plugins/winter_field_day.py,sha256=L7co3YEoKt-jaAFJfGw_Y3-uK-G6eQNsOQSCEkT5U24,1631
51
- not1mm-23.3.25.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
52
- not1mm-23.3.25.dist-info/METADATA,sha256=19FcuYDaFc2X5PJXxRZ9FiDEjVMx2xDe5qGU2aZXQhQ,8930
53
- not1mm-23.3.25.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
54
- not1mm-23.3.25.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
55
- not1mm-23.3.25.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
56
- not1mm-23.3.25.dist-info/RECORD,,
52
+ not1mm-23.3.27.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
53
+ not1mm-23.3.27.dist-info/METADATA,sha256=auF7-fSveo2JxXCHcWeEsT6KntUfF1ZAs48GQ67-mxE,9100
54
+ not1mm-23.3.27.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
55
+ not1mm-23.3.27.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
56
+ not1mm-23.3.27.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
57
+ not1mm-23.3.27.dist-info/RECORD,,