not1mm 24.9.8__py3-none-any.whl → 24.9.9__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.
@@ -307,6 +307,16 @@
307
307
  <string>ICWC MST</string>
308
308
  </property>
309
309
  </item>
310
+ <item>
311
+ <property name="text">
312
+ <string>IARU FIELDDAY R1 CW</string>
313
+ </property>
314
+ </item>
315
+ <item>
316
+ <property name="text">
317
+ <string>IARU FIELDDAY R1 SSB</string>
318
+ </property>
319
+ </item>
310
320
  <item>
311
321
  <property name="text">
312
322
  <string>IARU HF</string>
@@ -364,9 +374,26 @@
364
374
  <property name="accessibleName">
365
375
  <string>Start of contest Date and U T C Time</string>
366
376
  </property>
377
+ <property name="dateTime">
378
+ <datetime>
379
+ <hour>8</hour>
380
+ <minute>0</minute>
381
+ <second>0</second>
382
+ <year>2024</year>
383
+ <month>1</month>
384
+ <day>1</day>
385
+ </datetime>
386
+ </property>
387
+ <property name="date">
388
+ <date>
389
+ <year>2024</year>
390
+ <month>1</month>
391
+ <day>1</day>
392
+ </date>
393
+ </property>
367
394
  <property name="time">
368
395
  <time>
369
- <hour>0</hour>
396
+ <hour>8</hour>
370
397
  <minute>0</minute>
371
398
  <second>0</second>
372
399
  </time>
not1mm/lib/database.py CHANGED
@@ -725,6 +725,34 @@ class DataBase:
725
725
  logger.debug("%s", exception)
726
726
  return {}
727
727
 
728
+ def fetch_dxcc_exists(self, dxcc) -> dict:
729
+ """returns the dict dxcc_count of dxcc existing in current contest."""
730
+ try:
731
+ with sqlite3.connect(self.database) as conn:
732
+ conn.row_factory = self.row_factory
733
+ cursor = conn.cursor()
734
+ cursor.execute(
735
+ f"select count(*) as dxcc_count from dxlog where CountryPrefix = '{dxcc}' and ContestNR = {self.current_contest};"
736
+ )
737
+ return cursor.fetchone()
738
+ except sqlite3.OperationalError as exception:
739
+ logger.debug("%s", exception)
740
+ return {}
741
+
742
+ def fetch_dxcc_exists_before_me(self, dxcc, time_stamp) -> dict:
743
+ """returns the dict dxcc_count of dxcc existing in current contest."""
744
+ try:
745
+ with sqlite3.connect(self.database) as conn:
746
+ conn.row_factory = self.row_factory
747
+ cursor = conn.cursor()
748
+ cursor.execute(
749
+ f"select count(*) as dxcc_count from dxlog where TS < '{time_stamp}' and CountryPrefix = '{dxcc}' and ContestNR = {self.current_contest};"
750
+ )
751
+ return cursor.fetchone()
752
+ except sqlite3.OperationalError as exception:
753
+ logger.debug("%s", exception)
754
+ return {}
755
+
728
756
  def fetch_wpx_exists(self, wpx) -> dict:
729
757
  """returns a dict key of wpx_count"""
730
758
  try:
not1mm/lib/version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.9.8"
3
+ __version__ = "24.9.9"
@@ -0,0 +1,421 @@
1
+ """IARU Region 1 Field Day"""
2
+
3
+ # pylint: disable=invalid-name, c-extension-no-member, unused-import
4
+
5
+ # Status: Active
6
+ # Geographic Focus: Europe
7
+ # Participation: Worldwide
8
+ # Mode: CW
9
+ # Bands: 160, 80, 40, 20, 15, 10m
10
+ # Classes: (see your national society rules)
11
+ # Exchange: RST + Serial No.
12
+ # E-mail logs to: (none)
13
+ # Upload log at: https://dxhf2.darc.de/~fdcwlog/upload.cgi?form=referat&lang=en
14
+ # Mail logs to: (none)
15
+ # Find rules at: https://www.darc.de/der-club/referate/conteste/iaru-region-1-fieldday/en/
16
+
17
+ # Scoring
18
+ # Fixed station to fixed station: 0 points
19
+
20
+ # For contacts with:
21
+
22
+ # fixed stations in Europe: 2 points
23
+ # fixed stations outside Europe: 3 points
24
+ # portable stations in Europe: 4 points
25
+ # portable stations outside Europe: 6 points
26
+
27
+ # Each station may be contacted only once per band.
28
+
29
+ # Portable stations only count as portable if they sign "/p", "/m", "/mm", or "/am",
30
+
31
+ # 10. Multipliers
32
+ # ONE for each WAE country / DXCC entity worked on each band
33
+
34
+
35
+ import datetime
36
+ import logging
37
+
38
+ from pathlib import Path
39
+
40
+ from PyQt6 import QtWidgets
41
+
42
+ from not1mm.lib.plugin_common import gen_adif, get_points
43
+ from not1mm.lib.version import __version__
44
+
45
+ logger = logging.getLogger(__name__)
46
+
47
+ EXCHANGE_HINT = "#"
48
+
49
+ name = "IARU FIELDDAY R1 DARC CW"
50
+ cabrillo_name = "IARU-FD-R1-DARC-CW"
51
+ mode = "CW" # CW SSB BOTH RTTY
52
+ # columns = [0, 1, 2, 3, 4, 5, 6, 9, 11, 15]
53
+ columns = [
54
+ "YYYY-MM-DD HH:MM:SS",
55
+ "Call",
56
+ "Freq",
57
+ "Snt",
58
+ "Rcv",
59
+ "SentNr",
60
+ "RcvNr",
61
+ "M1",
62
+ "PTS",
63
+ ]
64
+
65
+ advance_on_space = [True, True, True, True, True]
66
+
67
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
68
+ dupe_type = 2
69
+
70
+
71
+ def init_contest(self):
72
+ """setup plugin"""
73
+ set_tab_next(self)
74
+ set_tab_prev(self)
75
+ interface(self)
76
+ self.next_field = self.other_2
77
+
78
+
79
+ def interface(self):
80
+ """Setup user interface"""
81
+ self.field1.show()
82
+ self.field2.show()
83
+ self.field3.show()
84
+ self.field4.show()
85
+ self.snt_label.setText("SNT")
86
+ self.field1.setAccessibleName("RST Sent")
87
+ self.other_label.setText("SentNR")
88
+ self.field3.setAccessibleName("Sent Number")
89
+ self.exch_label.setText("RcvNR")
90
+ self.field4.setAccessibleName("Received Number")
91
+
92
+
93
+ def reset_label(self): # pylint: disable=unused-argument
94
+ """reset label after field cleared"""
95
+
96
+
97
+ def set_tab_next(self):
98
+ """Set TAB Advances"""
99
+ self.tab_next = {
100
+ self.callsign: self.field1.findChild(QtWidgets.QLineEdit),
101
+ self.field1.findChild(QtWidgets.QLineEdit): self.field2.findChild(
102
+ QtWidgets.QLineEdit
103
+ ),
104
+ self.field2.findChild(QtWidgets.QLineEdit): self.field3.findChild(
105
+ QtWidgets.QLineEdit
106
+ ),
107
+ self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
108
+ QtWidgets.QLineEdit
109
+ ),
110
+ self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
111
+ }
112
+
113
+
114
+ def set_tab_prev(self):
115
+ """Set TAB Advances"""
116
+ self.tab_prev = {
117
+ self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
118
+ self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
119
+ self.field2.findChild(QtWidgets.QLineEdit): self.field1.findChild(
120
+ QtWidgets.QLineEdit
121
+ ),
122
+ self.field3.findChild(QtWidgets.QLineEdit): self.field2.findChild(
123
+ QtWidgets.QLineEdit
124
+ ),
125
+ self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
126
+ QtWidgets.QLineEdit
127
+ ),
128
+ }
129
+
130
+
131
+ def set_contact_vars(self):
132
+ """Contest Specific"""
133
+ self.contact["SNT"] = self.sent.text()
134
+ self.contact["RCV"] = self.receive.text()
135
+ self.contact["SentNr"] = self.other_1.text()
136
+ self.contact["NR"] = self.other_2.text()
137
+ if self.contact.get("CountryPrefix", ""):
138
+ result = self.database.fetch_dxcc_exists(self.contact.get("CountryPrefix", ""))
139
+ if result.get("dxcc_count", ""):
140
+ self.contact["IsMultiplier1"] = 0
141
+ else:
142
+ self.contact["IsMultiplier1"] = 1
143
+
144
+
145
+ def predupe(self): # pylint: disable=unused-argument
146
+ """called after callsign entered"""
147
+
148
+
149
+ def prefill(self):
150
+ """Fill SentNR"""
151
+ result = self.database.get_serial()
152
+ serial_nr = str(result.get("serial_nr", "1")).zfill(3)
153
+ if serial_nr == "None":
154
+ serial_nr = "001"
155
+ field = self.field3.findChild(QtWidgets.QLineEdit)
156
+ if len(field.text()) == 0:
157
+ field.setText(serial_nr)
158
+
159
+
160
+ def points(self):
161
+ """
162
+ Calc point
163
+
164
+ # fixed stations in Europe: 2 points
165
+ # fixed stations outside Europe: 3 points
166
+ # portable stations in Europe: 4 points
167
+ # portable stations outside Europe: 6 points
168
+ """
169
+
170
+ their_portable = False
171
+ im_portable = False
172
+ their_continent = self.contact.get("Continent", "")
173
+ the_call = self.contact.get("Call", "").upper()
174
+
175
+ if the_call.endswith(("/P", "/M", "/MM", "/AM")):
176
+ their_portable = True
177
+ if self.station.get("Call", "").endswith(("/P", "/M", "/MM", "/AM")):
178
+ im_portable = True
179
+
180
+ if not im_portable and not their_portable:
181
+ return 0
182
+
183
+ if their_continent:
184
+ if their_portable:
185
+ if their_continent == "EU":
186
+ return 4
187
+ else:
188
+ return 6
189
+ else:
190
+ if their_continent == "EU":
191
+ return 2
192
+ else:
193
+ return 3
194
+
195
+ # Something wrong
196
+ return 0
197
+
198
+
199
+ def show_mults(self):
200
+ """Return display string for mults"""
201
+ result = self.database.fetch_mult_count(1)
202
+ if result:
203
+ return int(result.get("count", 0))
204
+ return 0
205
+
206
+
207
+ def show_qso(self):
208
+ """Return qso count"""
209
+ result = self.database.fetch_qso_count()
210
+ if result:
211
+ return int(result.get("qsos", 0))
212
+ return 0
213
+
214
+
215
+ def calc_score(self):
216
+ """Return calculated score"""
217
+ result = self.database.fetch_points()
218
+ if result is not None:
219
+ score = result.get("Points", "0")
220
+ if score is None:
221
+ score = "0"
222
+ contest_points = int(score)
223
+ result = self.database.fetch_mult_count(1)
224
+ mults = int(result.get("count", 0))
225
+ return contest_points * mults
226
+ return 0
227
+
228
+
229
+ def adif(self):
230
+ """Call the generate ADIF function"""
231
+ gen_adif(self, cabrillo_name, "IARU FIELDDAY R1 DARC CW")
232
+
233
+
234
+ def cabrillo(self):
235
+ """Generates Cabrillo file. Maybe."""
236
+ # https://www.cqwpx.com/cabrillo.htm
237
+ logger.debug("******Cabrillo*****")
238
+ logger.debug("Station: %s", f"{self.station}")
239
+ logger.debug("Contest: %s", f"{self.contest_settings}")
240
+ now = datetime.datetime.now()
241
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
242
+ filename = (
243
+ str(Path.home())
244
+ + "/"
245
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
246
+ )
247
+ logger.debug("%s", filename)
248
+ log = self.database.fetch_all_contacts_asc()
249
+ try:
250
+ with open(filename, "w", encoding="ascii") as file_descriptor:
251
+ print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
252
+ print(
253
+ f"CREATED-BY: Not1MM v{__version__}",
254
+ end="\r\n",
255
+ file=file_descriptor,
256
+ )
257
+ print(
258
+ f"CONTEST: {cabrillo_name}",
259
+ end="\r\n",
260
+ file=file_descriptor,
261
+ )
262
+ if self.station.get("Club", ""):
263
+ print(
264
+ f"CLUB: {self.station.get('Club', '').upper()}",
265
+ end="\r\n",
266
+ file=file_descriptor,
267
+ )
268
+ print(
269
+ f"CALLSIGN: {self.station.get('Call','')}",
270
+ end="\r\n",
271
+ file=file_descriptor,
272
+ )
273
+ print(
274
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
275
+ end="\r\n",
276
+ file=file_descriptor,
277
+ )
278
+ # print(
279
+ # f"ARRL-SECTION: {self.pref.get('section', '')}",
280
+ # end="\r\n",
281
+ # file=file_descriptor,
282
+ # )
283
+ print(
284
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
285
+ end="\r\n",
286
+ file=file_descriptor,
287
+ )
288
+ print(
289
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
290
+ end="\r\n",
291
+ file=file_descriptor,
292
+ )
293
+ print(
294
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
295
+ end="\r\n",
296
+ file=file_descriptor,
297
+ )
298
+ print(
299
+ f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
300
+ end="\r\n",
301
+ file=file_descriptor,
302
+ )
303
+ print(
304
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
305
+ end="\r\n",
306
+ file=file_descriptor,
307
+ )
308
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
309
+ print(
310
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
311
+ end="\r\n",
312
+ file=file_descriptor,
313
+ )
314
+ print(
315
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
316
+ end="\r\n",
317
+ file=file_descriptor,
318
+ )
319
+ # print(
320
+ # f"CATEGORY: {None}",
321
+ # end="\r\n",
322
+ # file=file_descriptor,
323
+ # )
324
+ print(
325
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
326
+ end="\r\n",
327
+ file=file_descriptor,
328
+ )
329
+
330
+ print(
331
+ f"CLAIMED-SCORE: {calc_score(self)}",
332
+ end="\r\n",
333
+ file=file_descriptor,
334
+ )
335
+ ops = f"@{self.station.get('Call','')}"
336
+ list_of_ops = self.database.get_ops()
337
+ for op in list_of_ops:
338
+ ops += f", {op.get('Operator', '')}"
339
+ print(
340
+ f"OPERATORS: {ops}",
341
+ end="\r\n",
342
+ file=file_descriptor,
343
+ )
344
+ print(
345
+ f"NAME: {self.station.get('Name', '')}",
346
+ end="\r\n",
347
+ file=file_descriptor,
348
+ )
349
+ print(
350
+ f"ADDRESS: {self.station.get('Street1', '')}",
351
+ end="\r\n",
352
+ file=file_descriptor,
353
+ )
354
+ print(
355
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
356
+ end="\r\n",
357
+ file=file_descriptor,
358
+ )
359
+ print(
360
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
361
+ end="\r\n",
362
+ file=file_descriptor,
363
+ )
364
+ print(
365
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
366
+ end="\r\n",
367
+ file=file_descriptor,
368
+ )
369
+ print(
370
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
371
+ end="\r\n",
372
+ file=file_descriptor,
373
+ )
374
+ print(
375
+ f"EMAIL: {self.station.get('Email', '')}",
376
+ end="\r\n",
377
+ file=file_descriptor,
378
+ )
379
+ for contact in log:
380
+ the_date_and_time = contact.get("TS", "")
381
+ themode = contact.get("Mode", "")
382
+ if themode == "LSB" or themode == "USB":
383
+ themode = "PH"
384
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
385
+
386
+ loggeddate = the_date_and_time[:10]
387
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
388
+ print(
389
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
390
+ f"{contact.get('StationPrefix', '').ljust(13)} "
391
+ f"{str(contact.get('SNT', '')).ljust(3)} "
392
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
393
+ f"{contact.get('Call', '').ljust(13)} "
394
+ f"{str(contact.get('RCV', '')).ljust(3)} "
395
+ f"{str(contact.get('NR', '')).ljust(6)}",
396
+ end="\r\n",
397
+ file=file_descriptor,
398
+ )
399
+ print("END-OF-LOG:", end="\r\n", file=file_descriptor)
400
+ self.show_message_box(f"Cabrillo saved to: {filename}")
401
+ except IOError as exception:
402
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
403
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
404
+ return
405
+
406
+
407
+ def recalculate_mults(self):
408
+ """Recalculates multipliers after change in logged qso."""
409
+ all_contacts = self.database.fetch_all_contacts_asc()
410
+ for contact in all_contacts:
411
+ self.contact = contact
412
+ contact["Points"] = points(self)
413
+ time_stamp = contact.get("TS", "")
414
+ dxcc = contact.get("CountryPrefix", "")
415
+ result = self.database.fetch_dxcc_exists_before_me(dxcc, time_stamp)
416
+ dxcc_count = result.get("dxcc_count", 1)
417
+ if dxcc_count == 0:
418
+ contact["IsMultiplier1"] = 1
419
+ else:
420
+ contact["IsMultiplier1"] = 0
421
+ self.database.change_contact(contact)
@@ -0,0 +1,421 @@
1
+ """IARU Region 1 Field Day"""
2
+
3
+ # pylint: disable=invalid-name, c-extension-no-member, unused-import
4
+
5
+ # Status: Active
6
+ # Geographic Focus: Europe
7
+ # Participation: Worldwide
8
+ # Mode: SSB
9
+ # Bands: 160, 80, 40, 20, 15, 10m
10
+ # Classes: (see your national society rules)
11
+ # Exchange: RST + Serial No.
12
+ # E-mail logs to: (none)
13
+ # Upload log at: https://dxhf2.darc.de/~fdcwlog/upload.cgi?form=referat&lang=en
14
+ # Mail logs to: (none)
15
+ # Find rules at: https://www.darc.de/der-club/referate/conteste/iaru-region-1-fieldday/en/
16
+
17
+ # Scoring
18
+ # Fixed station to fixed station: 0 points
19
+
20
+ # For contacts with:
21
+
22
+ # fixed stations in Europe: 2 points
23
+ # fixed stations outside Europe: 3 points
24
+ # portable stations in Europe: 4 points
25
+ # portable stations outside Europe: 6 points
26
+
27
+ # Each station may be contacted only once per band.
28
+
29
+ # Portable stations only count as portable if they sign "/p", "/m", "/mm", or "/am",
30
+
31
+ # 10. Multipliers
32
+ # ONE for each WAE country / DXCC entity worked on each band
33
+
34
+
35
+ import datetime
36
+ import logging
37
+
38
+ from pathlib import Path
39
+
40
+ from PyQt6 import QtWidgets
41
+
42
+ from not1mm.lib.plugin_common import gen_adif, get_points
43
+ from not1mm.lib.version import __version__
44
+
45
+ logger = logging.getLogger(__name__)
46
+
47
+ EXCHANGE_HINT = "#"
48
+
49
+ name = "IARU FIELDDAY R1 DARC SSB"
50
+ cabrillo_name = "IARU-FD-R1-DARC-SSB"
51
+ mode = "SSB" # CW SSB BOTH RTTY
52
+ # columns = [0, 1, 2, 3, 4, 5, 6, 9, 11, 15]
53
+ columns = [
54
+ "YYYY-MM-DD HH:MM:SS",
55
+ "Call",
56
+ "Freq",
57
+ "Snt",
58
+ "Rcv",
59
+ "SentNr",
60
+ "RcvNr",
61
+ "M1",
62
+ "PTS",
63
+ ]
64
+
65
+ advance_on_space = [True, True, True, True, True]
66
+
67
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
68
+ dupe_type = 2
69
+
70
+
71
+ def init_contest(self):
72
+ """setup plugin"""
73
+ set_tab_next(self)
74
+ set_tab_prev(self)
75
+ interface(self)
76
+ self.next_field = self.other_2
77
+
78
+
79
+ def interface(self):
80
+ """Setup user interface"""
81
+ self.field1.show()
82
+ self.field2.show()
83
+ self.field3.show()
84
+ self.field4.show()
85
+ self.snt_label.setText("SNT")
86
+ self.field1.setAccessibleName("RST Sent")
87
+ self.other_label.setText("SentNR")
88
+ self.field3.setAccessibleName("Sent Number")
89
+ self.exch_label.setText("RcvNR")
90
+ self.field4.setAccessibleName("Received Number")
91
+
92
+
93
+ def reset_label(self): # pylint: disable=unused-argument
94
+ """reset label after field cleared"""
95
+
96
+
97
+ def set_tab_next(self):
98
+ """Set TAB Advances"""
99
+ self.tab_next = {
100
+ self.callsign: self.field1.findChild(QtWidgets.QLineEdit),
101
+ self.field1.findChild(QtWidgets.QLineEdit): self.field2.findChild(
102
+ QtWidgets.QLineEdit
103
+ ),
104
+ self.field2.findChild(QtWidgets.QLineEdit): self.field3.findChild(
105
+ QtWidgets.QLineEdit
106
+ ),
107
+ self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
108
+ QtWidgets.QLineEdit
109
+ ),
110
+ self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
111
+ }
112
+
113
+
114
+ def set_tab_prev(self):
115
+ """Set TAB Advances"""
116
+ self.tab_prev = {
117
+ self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
118
+ self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
119
+ self.field2.findChild(QtWidgets.QLineEdit): self.field1.findChild(
120
+ QtWidgets.QLineEdit
121
+ ),
122
+ self.field3.findChild(QtWidgets.QLineEdit): self.field2.findChild(
123
+ QtWidgets.QLineEdit
124
+ ),
125
+ self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
126
+ QtWidgets.QLineEdit
127
+ ),
128
+ }
129
+
130
+
131
+ def set_contact_vars(self):
132
+ """Contest Specific"""
133
+ self.contact["SNT"] = self.sent.text()
134
+ self.contact["RCV"] = self.receive.text()
135
+ self.contact["SentNr"] = self.other_1.text()
136
+ self.contact["NR"] = self.other_2.text()
137
+ if self.contact.get("CountryPrefix", ""):
138
+ result = self.database.fetch_dxcc_exists(self.contact.get("CountryPrefix", ""))
139
+ if result.get("dxcc_count", ""):
140
+ self.contact["IsMultiplier1"] = 0
141
+ else:
142
+ self.contact["IsMultiplier1"] = 1
143
+
144
+
145
+ def predupe(self): # pylint: disable=unused-argument
146
+ """called after callsign entered"""
147
+
148
+
149
+ def prefill(self):
150
+ """Fill SentNR"""
151
+ result = self.database.get_serial()
152
+ serial_nr = str(result.get("serial_nr", "1")).zfill(3)
153
+ if serial_nr == "None":
154
+ serial_nr = "001"
155
+ field = self.field3.findChild(QtWidgets.QLineEdit)
156
+ if len(field.text()) == 0:
157
+ field.setText(serial_nr)
158
+
159
+
160
+ def points(self):
161
+ """
162
+ Calc point
163
+
164
+ # fixed stations in Europe: 2 points
165
+ # fixed stations outside Europe: 3 points
166
+ # portable stations in Europe: 4 points
167
+ # portable stations outside Europe: 6 points
168
+ """
169
+
170
+ their_portable = False
171
+ im_portable = False
172
+ their_continent = self.contact.get("Continent", "")
173
+ the_call = self.contact.get("Call", "").upper()
174
+
175
+ if the_call.endswith(("/P", "/M", "/MM", "/AM")):
176
+ their_portable = True
177
+ if self.station.get("Call", "").endswith(("/P", "/M", "/MM", "/AM")):
178
+ im_portable = True
179
+
180
+ if not im_portable and not their_portable:
181
+ return 0
182
+
183
+ if their_continent:
184
+ if their_portable:
185
+ if their_continent == "EU":
186
+ return 4
187
+ else:
188
+ return 6
189
+ else:
190
+ if their_continent == "EU":
191
+ return 2
192
+ else:
193
+ return 3
194
+
195
+ # Something wrong
196
+ return 0
197
+
198
+
199
+ def show_mults(self):
200
+ """Return display string for mults"""
201
+ result = self.database.fetch_mult_count(1)
202
+ if result:
203
+ return int(result.get("count", 0))
204
+ return 0
205
+
206
+
207
+ def show_qso(self):
208
+ """Return qso count"""
209
+ result = self.database.fetch_qso_count()
210
+ if result:
211
+ return int(result.get("qsos", 0))
212
+ return 0
213
+
214
+
215
+ def calc_score(self):
216
+ """Return calculated score"""
217
+ result = self.database.fetch_points()
218
+ if result is not None:
219
+ score = result.get("Points", "0")
220
+ if score is None:
221
+ score = "0"
222
+ contest_points = int(score)
223
+ result = self.database.fetch_mult_count(1)
224
+ mults = int(result.get("count", 0))
225
+ return contest_points * mults
226
+ return 0
227
+
228
+
229
+ def adif(self):
230
+ """Call the generate ADIF function"""
231
+ gen_adif(self, cabrillo_name, "IARU FIELDDAY R1 DARC SSB")
232
+
233
+
234
+ def cabrillo(self):
235
+ """Generates Cabrillo file. Maybe."""
236
+ # https://www.cqwpx.com/cabrillo.htm
237
+ logger.debug("******Cabrillo*****")
238
+ logger.debug("Station: %s", f"{self.station}")
239
+ logger.debug("Contest: %s", f"{self.contest_settings}")
240
+ now = datetime.datetime.now()
241
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
242
+ filename = (
243
+ str(Path.home())
244
+ + "/"
245
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
246
+ )
247
+ logger.debug("%s", filename)
248
+ log = self.database.fetch_all_contacts_asc()
249
+ try:
250
+ with open(filename, "w", encoding="ascii") as file_descriptor:
251
+ print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
252
+ print(
253
+ f"CREATED-BY: Not1MM v{__version__}",
254
+ end="\r\n",
255
+ file=file_descriptor,
256
+ )
257
+ print(
258
+ f"CONTEST: {cabrillo_name}",
259
+ end="\r\n",
260
+ file=file_descriptor,
261
+ )
262
+ if self.station.get("Club", ""):
263
+ print(
264
+ f"CLUB: {self.station.get('Club', '').upper()}",
265
+ end="\r\n",
266
+ file=file_descriptor,
267
+ )
268
+ print(
269
+ f"CALLSIGN: {self.station.get('Call','')}",
270
+ end="\r\n",
271
+ file=file_descriptor,
272
+ )
273
+ print(
274
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
275
+ end="\r\n",
276
+ file=file_descriptor,
277
+ )
278
+ # print(
279
+ # f"ARRL-SECTION: {self.pref.get('section', '')}",
280
+ # end="\r\n",
281
+ # file=file_descriptor,
282
+ # )
283
+ print(
284
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
285
+ end="\r\n",
286
+ file=file_descriptor,
287
+ )
288
+ print(
289
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
290
+ end="\r\n",
291
+ file=file_descriptor,
292
+ )
293
+ print(
294
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
295
+ end="\r\n",
296
+ file=file_descriptor,
297
+ )
298
+ print(
299
+ f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
300
+ end="\r\n",
301
+ file=file_descriptor,
302
+ )
303
+ print(
304
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
305
+ end="\r\n",
306
+ file=file_descriptor,
307
+ )
308
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
309
+ print(
310
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
311
+ end="\r\n",
312
+ file=file_descriptor,
313
+ )
314
+ print(
315
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
316
+ end="\r\n",
317
+ file=file_descriptor,
318
+ )
319
+ # print(
320
+ # f"CATEGORY: {None}",
321
+ # end="\r\n",
322
+ # file=file_descriptor,
323
+ # )
324
+ print(
325
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
326
+ end="\r\n",
327
+ file=file_descriptor,
328
+ )
329
+
330
+ print(
331
+ f"CLAIMED-SCORE: {calc_score(self)}",
332
+ end="\r\n",
333
+ file=file_descriptor,
334
+ )
335
+ ops = f"@{self.station.get('Call','')}"
336
+ list_of_ops = self.database.get_ops()
337
+ for op in list_of_ops:
338
+ ops += f", {op.get('Operator', '')}"
339
+ print(
340
+ f"OPERATORS: {ops}",
341
+ end="\r\n",
342
+ file=file_descriptor,
343
+ )
344
+ print(
345
+ f"NAME: {self.station.get('Name', '')}",
346
+ end="\r\n",
347
+ file=file_descriptor,
348
+ )
349
+ print(
350
+ f"ADDRESS: {self.station.get('Street1', '')}",
351
+ end="\r\n",
352
+ file=file_descriptor,
353
+ )
354
+ print(
355
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
356
+ end="\r\n",
357
+ file=file_descriptor,
358
+ )
359
+ print(
360
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
361
+ end="\r\n",
362
+ file=file_descriptor,
363
+ )
364
+ print(
365
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
366
+ end="\r\n",
367
+ file=file_descriptor,
368
+ )
369
+ print(
370
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
371
+ end="\r\n",
372
+ file=file_descriptor,
373
+ )
374
+ print(
375
+ f"EMAIL: {self.station.get('Email', '')}",
376
+ end="\r\n",
377
+ file=file_descriptor,
378
+ )
379
+ for contact in log:
380
+ the_date_and_time = contact.get("TS", "")
381
+ themode = contact.get("Mode", "")
382
+ if themode == "LSB" or themode == "USB":
383
+ themode = "PH"
384
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
385
+
386
+ loggeddate = the_date_and_time[:10]
387
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
388
+ print(
389
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
390
+ f"{contact.get('StationPrefix', '').ljust(13)} "
391
+ f"{str(contact.get('SNT', '')).ljust(3)} "
392
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
393
+ f"{contact.get('Call', '').ljust(13)} "
394
+ f"{str(contact.get('RCV', '')).ljust(3)} "
395
+ f"{str(contact.get('NR', '')).ljust(6)}",
396
+ end="\r\n",
397
+ file=file_descriptor,
398
+ )
399
+ print("END-OF-LOG:", end="\r\n", file=file_descriptor)
400
+ self.show_message_box(f"Cabrillo saved to: {filename}")
401
+ except IOError as exception:
402
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
403
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
404
+ return
405
+
406
+
407
+ def recalculate_mults(self):
408
+ """Recalculates multipliers after change in logged qso."""
409
+ all_contacts = self.database.fetch_all_contacts_asc()
410
+ for contact in all_contacts:
411
+ self.contact = contact
412
+ contact["Points"] = points(self)
413
+ time_stamp = contact.get("TS", "")
414
+ dxcc = contact.get("CountryPrefix", "")
415
+ result = self.database.fetch_dxcc_exists_before_me(dxcc, time_stamp)
416
+ dxcc_count = result.get("dxcc_count", 1)
417
+ if dxcc_count == 0:
418
+ contact["IsMultiplier1"] = 1
419
+ else:
420
+ contact["IsMultiplier1"] = 0
421
+ self.database.change_contact(contact)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 24.9.8
3
+ Version: 24.9.9
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
@@ -212,6 +212,8 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
212
212
  - CQ World Wide SSB
213
213
  - CWOps CWT
214
214
  - Helvetia
215
+ - IARU Fieldday R1 CW
216
+ - IARU Fieldday R1 SSB
215
217
  - IARU HF
216
218
  - ICWC MST
217
219
  - Japan International DX CW
@@ -227,6 +229,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
227
229
 
228
230
  ## Recent Changes
229
231
 
232
+ - [24-9-9] Add IARU R1 Fieldday CW and SSB
230
233
  - [24-9-8] Correct n1mm contact packet info.
231
234
  - [24-9-6] Added the Weekly RTTY
232
235
  - [24-9-5] Added FlDigi support for Field Day.
@@ -30,7 +30,7 @@ not1mm/data/k6gte.not1mm-64.png,sha256=6ku45Gq1g5ezh04F07osoKRtanb3e4kbx5XdIEh3N
30
30
  not1mm/data/logwindow.ui,sha256=vfkNdzJgFs3tTOBKLDavF2zVMvNHWOZ82fAErRi6pQY,1436
31
31
  not1mm/data/logwindowx.ui,sha256=9FzDJtLRpagvAWcDjFdB9NnvNZ4bVxdTNHy1Jit2ido,1610
32
32
  not1mm/data/main.ui,sha256=Y8F0gOqMTcsxBmc3QvWkJMxhYFpxUJQl-btGiM1-31w,56506
33
- not1mm/data/new_contest.ui,sha256=x4KkVqbaqrv-808yC7BR5ZBpMal81GF6uzKCrod8ick,22278
33
+ not1mm/data/new_contest.ui,sha256=Zuw_xaizvBmZfJuDrO8kS-1yVUeRLpTlmtmEowVRO5Y,22879
34
34
  not1mm/data/not1mm.html,sha256=c9-mfjMwDt4f5pySUruz2gREW33CQ2_rCddM2z5CZQo,23273
35
35
  not1mm/data/opon.ui,sha256=mC4OhoVIfR1H9IqHAKXliPMm8VOVmxSEadpsFQ7XnS4,2247
36
36
  not1mm/data/pickcontest.ui,sha256=_9JFiJw4l-bRRgNDtVg1DpxreylYd_UqEq0wfcr9gJc,1600
@@ -94,7 +94,7 @@ not1mm/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  not1mm/lib/about.py,sha256=sWycfGcruN3SaEe4JmaJ61K6D8Itq0WxpUYT-lEcmYM,416
95
95
  not1mm/lib/cat_interface.py,sha256=aazvNTSeZAROq3KL8gPx-I95iVez2IiIOSk22qeqVCQ,19502
96
96
  not1mm/lib/cwinterface.py,sha256=Q8p3pScOHczZ8ptICfH1Yu6rCEwQJLgrNwYMN76B2i8,3389
97
- not1mm/lib/database.py,sha256=TZjMixyPACZginoJkemXOdA4kAYMdSirdodkmN0Fv10,43136
97
+ not1mm/lib/database.py,sha256=nUVG5H2Dy98PGp6Qdr3xU7zM8-8-IiyqRkXZWlWzIe8,44446
98
98
  not1mm/lib/edit_contact.py,sha256=Ki9bGPpqyQQBB1cU8VIBDCal3lbXeQ6qxhzklmhE2_w,353
99
99
  not1mm/lib/edit_macro.py,sha256=raKWBwsHInj5EUKmvyLQ6gqc3ZFDlstsD3xqoM4PC8E,517
100
100
  not1mm/lib/edit_opon.py,sha256=j3qJ1aBsQoIOnQ9yiBl3lyeISvKTP0I_rtBYBPAfgeI,359
@@ -111,7 +111,7 @@ not1mm/lib/plugin_common.py,sha256=yefvcX61fXSjs__OPssJqVlZyg1AlcV1VDkl2MQP6kk,9
111
111
  not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
112
112
  not1mm/lib/settings.py,sha256=MWiKXbasaFbzeHTjfzTaTqbCBrIijudP_-0a5jNmUAA,9265
113
113
  not1mm/lib/super_check_partial.py,sha256=p5l3u2ZOCBtlWgbvskC50FpuoaIpR07tfC6zTdRWbh4,2334
114
- not1mm/lib/version.py,sha256=5j2EOLjnhLXJzoesZbLU9w4RWqMYEr-RYE7LKFH1EDo,47
114
+ not1mm/lib/version.py,sha256=jmRaogjqkFIoWFk-DpGvDj1a1x9G-_OxjVkmWuUc1go,47
115
115
  not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
116
116
  not1mm/plugins/10_10_fall_cw.py,sha256=IttjX1yy4nDdACGsiYlPteFG8eVseX_WtoFio6bqHE8,10953
117
117
  not1mm/plugins/10_10_spring_cw.py,sha256=ThCptdM3dX4ywhoy2JRcOEyHSqcJolFaT7O_PYzM1Mg,10958
@@ -138,6 +138,8 @@ not1mm/plugins/cq_ww_ssb.py,sha256=kt-EQofmCbynX1iXFm9ehffi_TMW25ke8Qi9MiR69ZQ,1
138
138
  not1mm/plugins/cwt.py,sha256=4xdXN6ZJM5k-6gn0hJzNheWfFlGiqquC2p0ZMEe516M,12818
139
139
  not1mm/plugins/general_logging.py,sha256=t02xtJs601qRICGdrvLs3G9y4GCG9H4AgQNkgA18CYs,3467
140
140
  not1mm/plugins/helvetia.py,sha256=6aOO4uiLzFFgHA-A3xz6IRdCJpqPOAm0egKxP5Y_Ie0,15432
141
+ not1mm/plugins/iaru_fieldday_r1_cw.py,sha256=B_kh8d8LkC0va_iIiIzImOKAT8724yf9ceF-2eQdx1w,13301
142
+ not1mm/plugins/iaru_fieldday_r1_ssb.py,sha256=5hIL60cfGBzVlb70XFtI3OeGZT2966LoryTgKK6kDEc,13306
141
143
  not1mm/plugins/iaru_hf.py,sha256=-ROUo2gBkw3xB89t8bd-4f7_1hROw2VXZXVHLFdB62s,11541
142
144
  not1mm/plugins/icwc_mst.py,sha256=BaUP2kzrT2D27un_WLGT4HCTTi1e7CNYC4NHcC_9r74,11842
143
145
  not1mm/plugins/jidx_cw.py,sha256=9oV4hDxMiGXa9wuYUNYOCsr-mz8LYB-4WMHBN8u2dFk,12153
@@ -150,9 +152,9 @@ not1mm/plugins/ref_cw.py,sha256=aWjHHkqIKutjRUtzh09y5haFfnZK9poRQDWRQMDRxxU,1632
150
152
  not1mm/plugins/stew_perry_topband.py,sha256=CKBQbYl4ETxhXJd2dma4fg_C5pag_s7Nf61SCztZtqE,10668
151
153
  not1mm/plugins/weekly_rtty.py,sha256=DQcy3SY0Zn56EdlYGf3NxrRhTnkNa5IqRQPRQdKDSPs,14255
152
154
  not1mm/plugins/winter_field_day.py,sha256=4rcfRtobwjHO6BNL3WOTHzBmyyeuX79BNGBG8PfjrI8,10238
153
- not1mm-24.9.8.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
154
- not1mm-24.9.8.dist-info/METADATA,sha256=W-lMQ73MBag75TDiTgO4Xl-3OaHh-wfjh6XU8DVSci8,30461
155
- not1mm-24.9.8.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
156
- not1mm-24.9.8.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
157
- not1mm-24.9.8.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
158
- not1mm-24.9.8.dist-info/RECORD,,
155
+ not1mm-24.9.9.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
156
+ not1mm-24.9.9.dist-info/METADATA,sha256=pZXmWlQ6OoB-_y9z5Bq1odGRVo8fFs8_5jg-l6wQg4c,30549
157
+ not1mm-24.9.9.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
158
+ not1mm-24.9.9.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
159
+ not1mm-24.9.9.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
160
+ not1mm-24.9.9.dist-info/RECORD,,