not1mm 24.8.17.1__py3-none-any.whl → 24.8.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 +16 -4
- not1mm/data/new_contest.ui +11 -1
- not1mm/data/splash.png +0 -0
- not1mm/lib/database.py +32 -1
- not1mm/lib/ham_utility.py +26 -0
- not1mm/lib/plugin_common.py +19 -12
- not1mm/lib/version.py +1 -1
- not1mm/plugins/helvetia.py +497 -0
- not1mm/plugins/k1usn_sst.py +6 -6
- not1mm/{playsoundtest.py → test.py} +3 -5
- {not1mm-24.8.17.1.dist-info → not1mm-24.8.27.dist-info}/METADATA +34 -4
- {not1mm-24.8.17.1.dist-info → not1mm-24.8.27.dist-info}/RECORD +16 -14
- {not1mm-24.8.17.1.dist-info → not1mm-24.8.27.dist-info}/WHEEL +1 -1
- {not1mm-24.8.17.1.dist-info → not1mm-24.8.27.dist-info}/LICENSE +0 -0
- {not1mm-24.8.17.1.dist-info → not1mm-24.8.27.dist-info}/entry_points.txt +0 -0
- {not1mm-24.8.17.1.dist-info → not1mm-24.8.27.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -35,9 +35,9 @@ except OSError as exception:
|
|
35
35
|
print("portaudio is not installed")
|
36
36
|
sd = None
|
37
37
|
from PyQt6 import QtCore, QtGui, QtWidgets, uic
|
38
|
-
from PyQt6.QtCore import QDir, Qt, QThread, QSettings
|
39
|
-
from PyQt6.QtGui import QFontDatabase, QColorConstants, QPalette, QColor
|
40
|
-
from PyQt6.QtWidgets import QFileDialog
|
38
|
+
from PyQt6.QtCore import QDir, Qt, QThread, QSettings, QCoreApplication
|
39
|
+
from PyQt6.QtGui import QFontDatabase, QColorConstants, QPalette, QColor, QPixmap
|
40
|
+
from PyQt6.QtWidgets import QFileDialog, QSplashScreen
|
41
41
|
|
42
42
|
from not1mm.lib.about import About
|
43
43
|
from not1mm.lib.cwinterface import CW
|
@@ -3398,12 +3398,24 @@ logging.basicConfig(
|
|
3398
3398
|
logging.getLogger("PyQt6.uic.uiparser").setLevel("INFO")
|
3399
3399
|
logging.getLogger("PyQt6.uic.properties").setLevel("INFO")
|
3400
3400
|
app = QtWidgets.QApplication(sys.argv)
|
3401
|
+
|
3402
|
+
pixmap = QPixmap(f"{os.fspath(fsutils.APP_DATA_PATH)}/splash.png")
|
3403
|
+
splash = QSplashScreen(pixmap)
|
3404
|
+
splash.show()
|
3405
|
+
app.processEvents()
|
3406
|
+
splash.showMessage(
|
3407
|
+
"Starting Up",
|
3408
|
+
alignment=Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignCenter,
|
3409
|
+
color=QColor(255, 255, 0),
|
3410
|
+
)
|
3411
|
+
QCoreApplication.processEvents()
|
3412
|
+
|
3401
3413
|
families = load_fonts_from_dir(os.fspath(fsutils.APP_DATA_PATH))
|
3402
3414
|
logger.info(f"font families {families}")
|
3403
3415
|
window = MainWindow()
|
3404
3416
|
window.callsign.setFocus()
|
3405
3417
|
window.show()
|
3406
|
-
|
3418
|
+
splash.finish(window)
|
3407
3419
|
|
3408
3420
|
if __name__ == "__main__":
|
3409
3421
|
run()
|
not1mm/data/new_contest.ui
CHANGED
@@ -297,6 +297,11 @@
|
|
297
297
|
<string>CWT</string>
|
298
298
|
</property>
|
299
299
|
</item>
|
300
|
+
<item>
|
301
|
+
<property name="text">
|
302
|
+
<string>HELVETIA</string>
|
303
|
+
</property>
|
304
|
+
</item>
|
300
305
|
<item>
|
301
306
|
<property name="text">
|
302
307
|
<string>ICWC MST</string>
|
@@ -317,6 +322,11 @@
|
|
317
322
|
<string>JIDX PH</string>
|
318
323
|
</property>
|
319
324
|
</item>
|
325
|
+
<item>
|
326
|
+
<property name="text">
|
327
|
+
<string>K1USN SST</string>
|
328
|
+
</property>
|
329
|
+
</item>
|
320
330
|
<item>
|
321
331
|
<property name="text">
|
322
332
|
<string>NAQP CW</string>
|
@@ -351,7 +361,7 @@
|
|
351
361
|
</property>
|
352
362
|
<property name="time">
|
353
363
|
<time>
|
354
|
-
<hour>
|
364
|
+
<hour>0</hour>
|
355
365
|
<minute>0</minute>
|
356
366
|
<second>0</second>
|
357
367
|
</time>
|
not1mm/data/splash.png
ADDED
Binary file
|
not1mm/lib/database.py
CHANGED
@@ -567,7 +567,7 @@ class DataBase:
|
|
567
567
|
def fetch_country_band_count(self) -> dict:
|
568
568
|
"""
|
569
569
|
returns dict with count of unique NR.
|
570
|
-
{
|
570
|
+
{cb_count: count}
|
571
571
|
"""
|
572
572
|
try:
|
573
573
|
with sqlite3.connect(self.database) as conn:
|
@@ -581,6 +581,23 @@ class DataBase:
|
|
581
581
|
logger.debug("%s", exception)
|
582
582
|
return {}
|
583
583
|
|
584
|
+
def fetch_country_count(self) -> dict:
|
585
|
+
"""
|
586
|
+
Fetch count of unique countries
|
587
|
+
{dxcc_count: count}
|
588
|
+
"""
|
589
|
+
try:
|
590
|
+
with sqlite3.connect(self.database) as conn:
|
591
|
+
conn.row_factory = self.row_factory
|
592
|
+
cursor = conn.cursor()
|
593
|
+
cursor.execute(
|
594
|
+
f"select count(DISTINCT(CountryPrefix)) as dxcc_count from dxlog where ContestNR = {self.current_contest};"
|
595
|
+
)
|
596
|
+
return cursor.fetchone()
|
597
|
+
except sqlite3.OperationalError as exception:
|
598
|
+
logger.debug("%s", exception)
|
599
|
+
return {}
|
600
|
+
|
584
601
|
def fetch_arrldx_country_band_count(self) -> dict:
|
585
602
|
"""
|
586
603
|
returns dict with count of unique NR.
|
@@ -883,6 +900,20 @@ class DataBase:
|
|
883
900
|
logger.debug("%s", exception)
|
884
901
|
return {}
|
885
902
|
|
903
|
+
def fetch_mult2_count(self) -> dict:
|
904
|
+
"""return QSO count"""
|
905
|
+
try:
|
906
|
+
with sqlite3.connect(self.database) as conn:
|
907
|
+
conn.row_factory = self.row_factory
|
908
|
+
cursor = conn.cursor()
|
909
|
+
cursor.execute(
|
910
|
+
f"select count(*) as count from dxlog where IsMultiplier2 = 1 and ContestNR = {self.current_contest};"
|
911
|
+
)
|
912
|
+
return cursor.fetchone()
|
913
|
+
except sqlite3.OperationalError as exception:
|
914
|
+
logger.debug("%s", exception)
|
915
|
+
return {}
|
916
|
+
|
886
917
|
def fetch_qso_count(self) -> dict:
|
887
918
|
"""return QSO count"""
|
888
919
|
try:
|
not1mm/lib/ham_utility.py
CHANGED
@@ -373,3 +373,29 @@ def distance_with_latlon(grid1: str, lat2: float, lon2: float) -> float:
|
|
373
373
|
logger.debug("lat1:%d lon1:%d lat2:%d lon2:%d", lat1, lon1, lat2, lon2)
|
374
374
|
# lat2, lon2 = gridtolatlon(grid2)
|
375
375
|
return round(haversine(lon1, lat1, lon2, lat2))
|
376
|
+
|
377
|
+
|
378
|
+
def parse_udc(filename: str) -> dict:
|
379
|
+
"""
|
380
|
+
simply parses a n1mm style udc file and returns a dict with key value pairs.
|
381
|
+
"""
|
382
|
+
|
383
|
+
udc_contest = {}
|
384
|
+
the_good_stuff = False
|
385
|
+
|
386
|
+
try:
|
387
|
+
with open(filename, "r", encoding="utf-8") as file_descriptor:
|
388
|
+
for line in file_descriptor:
|
389
|
+
if "[CONTEST]" in line.upper():
|
390
|
+
the_good_stuff = True
|
391
|
+
continue
|
392
|
+
if "=" in line and the_good_stuff is True:
|
393
|
+
try:
|
394
|
+
key, value = line.split("=")
|
395
|
+
udc_contest[key.strip()] = value.strip()
|
396
|
+
except ValueError:
|
397
|
+
...
|
398
|
+
except FileNotFoundError:
|
399
|
+
logger.debug("UDC file not found.")
|
400
|
+
return {}
|
401
|
+
return udc_contest
|
not1mm/lib/plugin_common.py
CHANGED
@@ -158,7 +158,9 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
158
158
|
except TypeError:
|
159
159
|
...
|
160
160
|
|
161
|
+
# SRX STRING, Contest dependent
|
161
162
|
try:
|
163
|
+
# ----------Field Days------------
|
162
164
|
if cabrillo_name in ("WFD", "ARRL-FD"):
|
163
165
|
rcv = (
|
164
166
|
f"{contact.get('Exchange1', '')} {contact.get('Sect', '')}"
|
@@ -169,18 +171,8 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
169
171
|
end="\r\n",
|
170
172
|
file=file_descriptor,
|
171
173
|
)
|
172
|
-
|
173
|
-
|
174
|
-
f"<SRX_STRING:{len(rcvnr)}>{rcvnr}",
|
175
|
-
end="\r\n",
|
176
|
-
file=file_descriptor,
|
177
|
-
)
|
178
|
-
except TypeError:
|
179
|
-
...
|
180
|
-
|
181
|
-
# cabrillo_name = "CQ-160-CW"
|
182
|
-
try:
|
183
|
-
if cabrillo_name in ("CQ-160-CW", "CQ-160-SSB"):
|
174
|
+
# ------------CQ 160---------------
|
175
|
+
elif cabrillo_name in ("CQ-160-CW", "CQ-160-SSB"):
|
184
176
|
rcv = f"{contact.get('Exchange1', '')}"
|
185
177
|
if len(rcv) > 1:
|
186
178
|
print(
|
@@ -188,6 +180,21 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
188
180
|
end="\r\n",
|
189
181
|
file=file_descriptor,
|
190
182
|
)
|
183
|
+
# --------------K1USN-SST-----------
|
184
|
+
elif cabrillo_name == "K1USN-SST":
|
185
|
+
rcv = f"{contact.get('Name', '')} {contact.get('Sect', '')}"
|
186
|
+
if len(rcv) > 1:
|
187
|
+
print(
|
188
|
+
f"<SRX_STRING:{len(rcv)}>{rcv.upper()}",
|
189
|
+
end="\r\n",
|
190
|
+
file=file_descriptor,
|
191
|
+
)
|
192
|
+
elif rcvnr != "0":
|
193
|
+
print(
|
194
|
+
f"<SRX_STRING:{len(rcvnr)}>{rcvnr}",
|
195
|
+
end="\r\n",
|
196
|
+
file=file_descriptor,
|
197
|
+
)
|
191
198
|
except TypeError:
|
192
199
|
...
|
193
200
|
|
not1mm/lib/version.py
CHANGED
@@ -0,0 +1,497 @@
|
|
1
|
+
"""
|
2
|
+
Helvetica
|
3
|
+
-------------------------------------------------
|
4
|
+
Status: Active
|
5
|
+
Geographic Focus: Switzerland
|
6
|
+
Participation: Worldwide
|
7
|
+
Mode: CW, SSB, Digital
|
8
|
+
Bands: 160, 80, 40, 20, 15, 10m
|
9
|
+
Classes: Single Op (CW/SSB) High
|
10
|
+
Single Op Mixed (QRP/Low/High)
|
11
|
+
Multi-Op (CW/SSB/Mixed) High
|
12
|
+
SWL
|
13
|
+
Max operating hours: 18 with a maximum of two rest periods of any length
|
14
|
+
Max power: HP: >100 watts
|
15
|
+
LP: 100 watts
|
16
|
+
QRP: 5 watts (CW/Digital) or 10 watts (SSB)
|
17
|
+
Exchange: HB: RS(T) + 2-letter canton
|
18
|
+
non-HB: RS(T) + Serial No.
|
19
|
+
Work stations: Once per band per mode
|
20
|
+
|
21
|
+
Scoring:
|
22
|
+
Contact with a station in Switzerland: 10 points
|
23
|
+
Contact with a station within the same continent: 1 point
|
24
|
+
Contact with a station outside the operator’s continent: 3 points
|
25
|
+
|
26
|
+
Multipliers: Canton and DXCC country (including Switzerland) per band: 1 point
|
27
|
+
|
28
|
+
Score Calculation: Total score = total QSO points x total mults
|
29
|
+
E-mail logs to: contest[at]uska[dot]ch
|
30
|
+
Mail logs to: (none)
|
31
|
+
Find rules at: https://www.uska.ch/events/uska-helvetia-contest-concours-helvetia-hf/
|
32
|
+
Cabrillo name: HELVETIA
|
33
|
+
"""
|
34
|
+
|
35
|
+
import datetime
|
36
|
+
import logging
|
37
|
+
import platform
|
38
|
+
|
39
|
+
from pathlib import Path
|
40
|
+
|
41
|
+
from PyQt6 import QtWidgets
|
42
|
+
|
43
|
+
from not1mm.lib.plugin_common import gen_adif, get_points
|
44
|
+
|
45
|
+
from not1mm.lib.version import __version__
|
46
|
+
|
47
|
+
logger = logging.getLogger(__name__)
|
48
|
+
|
49
|
+
EXCHANGE_HINT = "Canton or #"
|
50
|
+
|
51
|
+
name = "HELVETIA"
|
52
|
+
cabrillo_name = "HELVETIA"
|
53
|
+
mode = "BOTH" # CW SSB BOTH RTTY
|
54
|
+
|
55
|
+
columns = [
|
56
|
+
"YYYY-MM-DD HH:MM:SS",
|
57
|
+
"Call",
|
58
|
+
"Freq",
|
59
|
+
"Mode",
|
60
|
+
"Snt",
|
61
|
+
"Rcv",
|
62
|
+
"SentNr",
|
63
|
+
"RcvNr",
|
64
|
+
"M1",
|
65
|
+
"M2",
|
66
|
+
"PTS",
|
67
|
+
]
|
68
|
+
|
69
|
+
advance_on_space = [True, True, True, True, True]
|
70
|
+
|
71
|
+
# 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
|
72
|
+
dupe_type = 3
|
73
|
+
|
74
|
+
cantons = [
|
75
|
+
"AG",
|
76
|
+
"AI",
|
77
|
+
"AR",
|
78
|
+
"BE",
|
79
|
+
"BL",
|
80
|
+
"BS",
|
81
|
+
"CH",
|
82
|
+
"FR",
|
83
|
+
"GE",
|
84
|
+
"GL",
|
85
|
+
"GR",
|
86
|
+
"JU",
|
87
|
+
"LU",
|
88
|
+
"NE",
|
89
|
+
"NW",
|
90
|
+
"OW",
|
91
|
+
"SG",
|
92
|
+
"SH",
|
93
|
+
"SO",
|
94
|
+
"SZ",
|
95
|
+
"TG",
|
96
|
+
"TI",
|
97
|
+
"UR",
|
98
|
+
"VD",
|
99
|
+
"VS",
|
100
|
+
"ZG",
|
101
|
+
"ZH",
|
102
|
+
]
|
103
|
+
|
104
|
+
|
105
|
+
def init_contest(self):
|
106
|
+
"""setup plugin"""
|
107
|
+
set_tab_next(self)
|
108
|
+
set_tab_prev(self)
|
109
|
+
interface(self)
|
110
|
+
self.next_field = self.other_2
|
111
|
+
|
112
|
+
|
113
|
+
def interface(self):
|
114
|
+
"""Setup user interface"""
|
115
|
+
self.field1.show()
|
116
|
+
self.field2.show()
|
117
|
+
self.field3.show()
|
118
|
+
self.field4.show()
|
119
|
+
label = self.field3.findChild(QtWidgets.QLabel)
|
120
|
+
label.setText("Sent")
|
121
|
+
self.field3.setAccessibleName("Sent")
|
122
|
+
label = self.field4.findChild(QtWidgets.QLabel)
|
123
|
+
label.setText("Canton/SN")
|
124
|
+
self.field4.setAccessibleName("Canton or SN")
|
125
|
+
|
126
|
+
|
127
|
+
def reset_label(self):
|
128
|
+
"""reset label after field cleared"""
|
129
|
+
|
130
|
+
|
131
|
+
def set_tab_next(self):
|
132
|
+
"""Set TAB Advances"""
|
133
|
+
self.tab_next = {
|
134
|
+
self.callsign: self.field3.findChild(QtWidgets.QLineEdit),
|
135
|
+
self.field1.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
136
|
+
QtWidgets.QLineEdit
|
137
|
+
),
|
138
|
+
self.field2.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
139
|
+
QtWidgets.QLineEdit
|
140
|
+
),
|
141
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.field4.findChild(
|
142
|
+
QtWidgets.QLineEdit
|
143
|
+
),
|
144
|
+
self.field4.findChild(QtWidgets.QLineEdit): self.callsign,
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
def set_tab_prev(self):
|
149
|
+
"""Set TAB Advances"""
|
150
|
+
self.tab_prev = {
|
151
|
+
self.callsign: self.field4.findChild(QtWidgets.QLineEdit),
|
152
|
+
self.field1.findChild(QtWidgets.QLineEdit): self.callsign,
|
153
|
+
self.field2.findChild(QtWidgets.QLineEdit): self.callsign,
|
154
|
+
self.field3.findChild(QtWidgets.QLineEdit): self.callsign,
|
155
|
+
self.field4.findChild(QtWidgets.QLineEdit): self.field3.findChild(
|
156
|
+
QtWidgets.QLineEdit
|
157
|
+
),
|
158
|
+
}
|
159
|
+
|
160
|
+
|
161
|
+
def set_contact_vars(self):
|
162
|
+
"""Contest Specific"""
|
163
|
+
self.contact["SNT"] = self.sent.text()
|
164
|
+
self.contact["RCV"] = self.receive.text()
|
165
|
+
self.contact["SentNr"] = self.other_1.text().upper()
|
166
|
+
self.contact["NR"] = self.other_2.text().upper()
|
167
|
+
|
168
|
+
self.contact["IsMultiplier1"] = 0
|
169
|
+
self.contact["IsMultiplier2"] = 0
|
170
|
+
|
171
|
+
if (
|
172
|
+
self.contact.get("CountryPrefix", "") == "HB"
|
173
|
+
and self.contact.get("NR", "").isalpha()
|
174
|
+
):
|
175
|
+
canton = self.contact.get("NR", "").upper()
|
176
|
+
band = self.contact.get("Band", "")
|
177
|
+
query = (
|
178
|
+
f"select count(*) as canton_count from dxlog where "
|
179
|
+
f"NR = '{canton}' "
|
180
|
+
f"and Band = '{band}' "
|
181
|
+
f"and ContestNR = {self.pref.get('contest', '1')};"
|
182
|
+
)
|
183
|
+
result = self.database.exec_sql(query)
|
184
|
+
count = int(result.get("canton_count", 0))
|
185
|
+
if count == 0:
|
186
|
+
self.contact["IsMultiplier1"] = 1
|
187
|
+
|
188
|
+
if self.contact.get("CountryPrefix", ""):
|
189
|
+
dxcc = self.contact.get("CountryPrefix", "")
|
190
|
+
band = self.contact.get("Band", "")
|
191
|
+
query = (
|
192
|
+
f"select count(*) as dxcc_count from dxlog where "
|
193
|
+
f"CountryPrefix = '{dxcc}' "
|
194
|
+
f"and Band = '{band}' "
|
195
|
+
f"and ContestNR = {self.pref.get('contest', '1')};"
|
196
|
+
)
|
197
|
+
result = self.database.exec_sql(query)
|
198
|
+
if not result.get("dxcc_count", ""):
|
199
|
+
self.contact["IsMultiplier2"] = 1
|
200
|
+
|
201
|
+
|
202
|
+
def predupe(self):
|
203
|
+
"""called after callsign entered"""
|
204
|
+
|
205
|
+
|
206
|
+
def prefill(self):
|
207
|
+
"""Fill SentNR"""
|
208
|
+
field = self.field3.findChild(QtWidgets.QLineEdit)
|
209
|
+
sent_sxchange_setting = self.contest_settings.get("SentExchange", "")
|
210
|
+
if sent_sxchange_setting.strip() == "#":
|
211
|
+
result = self.database.get_serial()
|
212
|
+
serial_nr = str(result.get("serial_nr", "1")).zfill(3)
|
213
|
+
if serial_nr == "None":
|
214
|
+
serial_nr = "001"
|
215
|
+
if len(field.text()) == 0:
|
216
|
+
field.setText(serial_nr)
|
217
|
+
else:
|
218
|
+
field.setText(sent_sxchange_setting)
|
219
|
+
|
220
|
+
|
221
|
+
def points(self):
|
222
|
+
"""
|
223
|
+
Scoring:
|
224
|
+
Contact with a station within the same continent: 1 point
|
225
|
+
Contact with a station outside the operator’s continent: 3 points
|
226
|
+
Contact with a station in Switzerland: 10 points
|
227
|
+
self.contact["CountryPrefix"]
|
228
|
+
self.contact["Continent"]
|
229
|
+
"""
|
230
|
+
result = self.cty_lookup(self.station.get("Call", ""))
|
231
|
+
if result:
|
232
|
+
for item in result.items():
|
233
|
+
my_continent = item[1].get("continent", "")
|
234
|
+
result = self.cty_lookup(self.contact.get("Call", ""))
|
235
|
+
if result:
|
236
|
+
for item in result.items():
|
237
|
+
their_country = item[1].get("entity", "")
|
238
|
+
their_continent = item[1].get("continent", "")
|
239
|
+
|
240
|
+
if their_country == "Switzerland":
|
241
|
+
return 10
|
242
|
+
|
243
|
+
if my_continent != their_continent:
|
244
|
+
return 3
|
245
|
+
|
246
|
+
return 1
|
247
|
+
# Something wrong
|
248
|
+
return 0
|
249
|
+
|
250
|
+
|
251
|
+
def show_mults(self):
|
252
|
+
"""Return display string for mults"""
|
253
|
+
return int(self.database.fetch_mult1_count().get("count", 0)) + int(
|
254
|
+
self.database.fetch_mult2_count().get("count", 0)
|
255
|
+
)
|
256
|
+
|
257
|
+
|
258
|
+
def show_qso(self):
|
259
|
+
"""Return qso count"""
|
260
|
+
result = self.database.fetch_qso_count()
|
261
|
+
if result:
|
262
|
+
return int(result.get("qsos", 0))
|
263
|
+
return 0
|
264
|
+
|
265
|
+
|
266
|
+
def calc_score(self):
|
267
|
+
"""Return calculated score"""
|
268
|
+
result = self.database.fetch_points()
|
269
|
+
if result is not None:
|
270
|
+
score = result.get("Points", "0")
|
271
|
+
if score is None:
|
272
|
+
score = "0"
|
273
|
+
contest_points = int(score)
|
274
|
+
mults = show_mults(self)
|
275
|
+
return contest_points * mults
|
276
|
+
return 0
|
277
|
+
|
278
|
+
|
279
|
+
def recalculate_mults(self):
|
280
|
+
"""Recalculates multipliers after change in logged qso."""
|
281
|
+
|
282
|
+
all_contacts = self.database.fetch_all_contacts_asc()
|
283
|
+
for contact in all_contacts:
|
284
|
+
|
285
|
+
contact["IsMultiplier1"] = 0
|
286
|
+
contact["IsMultiplier2"] = 0
|
287
|
+
|
288
|
+
time_stamp = contact.get("TS", "")
|
289
|
+
canton = contact.get("NR", "")
|
290
|
+
dxcc = contact.get("CountryPrefix", "")
|
291
|
+
band = contact.get("Band", "")
|
292
|
+
if dxcc == "HB" and canton.isalpha():
|
293
|
+
query = (
|
294
|
+
f"select count(*) as canton_count from dxlog where TS < '{time_stamp}' "
|
295
|
+
f"and NR = '{canton.upper()}' "
|
296
|
+
f"and Band = '{band}' "
|
297
|
+
f"and ContestNR = {self.pref.get('contest', '1')};"
|
298
|
+
)
|
299
|
+
result = self.database.exec_sql(query)
|
300
|
+
count = int(result.get("canton_count", 0))
|
301
|
+
if count == 0:
|
302
|
+
contact["IsMultiplier1"] = 1
|
303
|
+
|
304
|
+
if dxcc:
|
305
|
+
query = (
|
306
|
+
f"select count(*) as dxcc_count from dxlog where TS < '{time_stamp}' "
|
307
|
+
f"and CountryPrefix = '{dxcc}' "
|
308
|
+
f"and Band = '{band}' "
|
309
|
+
f"and ContestNR = {self.pref.get('contest', '1')};"
|
310
|
+
)
|
311
|
+
result = self.database.exec_sql(query)
|
312
|
+
if not result.get("dxcc_count", ""):
|
313
|
+
contact["IsMultiplier2"] = 1
|
314
|
+
|
315
|
+
self.database.change_contact(contact)
|
316
|
+
cmd = {}
|
317
|
+
cmd["cmd"] = "UPDATELOG"
|
318
|
+
cmd["station"] = platform.node()
|
319
|
+
self.multicast_interface.send_as_json(cmd)
|
320
|
+
|
321
|
+
|
322
|
+
def adif(self):
|
323
|
+
"""Call the generate ADIF function"""
|
324
|
+
gen_adif(self, cabrillo_name, "HELVETIA")
|
325
|
+
|
326
|
+
|
327
|
+
def cabrillo(self):
|
328
|
+
"""Generates Cabrillo file. Maybe."""
|
329
|
+
# https://www.cqwpx.com/cabrillo.htm
|
330
|
+
logger.debug("******Cabrillo*****")
|
331
|
+
logger.debug("Station: %s", f"{self.station}")
|
332
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
333
|
+
now = datetime.datetime.now()
|
334
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
335
|
+
filename = (
|
336
|
+
str(Path.home())
|
337
|
+
+ "/"
|
338
|
+
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
|
339
|
+
)
|
340
|
+
logger.debug("%s", filename)
|
341
|
+
log = self.database.fetch_all_contacts_asc()
|
342
|
+
try:
|
343
|
+
with open(filename, "w", encoding="ascii") as file_descriptor:
|
344
|
+
print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
|
345
|
+
print(
|
346
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
347
|
+
end="\r\n",
|
348
|
+
file=file_descriptor,
|
349
|
+
)
|
350
|
+
print(
|
351
|
+
f"CONTEST: {cabrillo_name}",
|
352
|
+
end="\r\n",
|
353
|
+
file=file_descriptor,
|
354
|
+
)
|
355
|
+
if self.station.get("Club", ""):
|
356
|
+
print(
|
357
|
+
f"CLUB: {self.station.get('Club', '').upper()}",
|
358
|
+
end="\r\n",
|
359
|
+
file=file_descriptor,
|
360
|
+
)
|
361
|
+
print(
|
362
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
363
|
+
end="\r\n",
|
364
|
+
file=file_descriptor,
|
365
|
+
)
|
366
|
+
print(
|
367
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
368
|
+
end="\r\n",
|
369
|
+
file=file_descriptor,
|
370
|
+
)
|
371
|
+
# print(
|
372
|
+
# f"ARRL-SECTION: {self.pref.get('section', '')}",
|
373
|
+
# end="\r\n",
|
374
|
+
# file=file_descriptor,
|
375
|
+
# )
|
376
|
+
print(
|
377
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
378
|
+
end="\r\n",
|
379
|
+
file=file_descriptor,
|
380
|
+
)
|
381
|
+
print(
|
382
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
383
|
+
end="\r\n",
|
384
|
+
file=file_descriptor,
|
385
|
+
)
|
386
|
+
print(
|
387
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
388
|
+
end="\r\n",
|
389
|
+
file=file_descriptor,
|
390
|
+
)
|
391
|
+
print(
|
392
|
+
f"CATEGORY-MODE: {self.contest_settings.get('ModeCategory','')}",
|
393
|
+
end="\r\n",
|
394
|
+
file=file_descriptor,
|
395
|
+
)
|
396
|
+
print(
|
397
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
398
|
+
end="\r\n",
|
399
|
+
file=file_descriptor,
|
400
|
+
)
|
401
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
402
|
+
print(
|
403
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
404
|
+
end="\r\n",
|
405
|
+
file=file_descriptor,
|
406
|
+
)
|
407
|
+
print(
|
408
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
409
|
+
end="\r\n",
|
410
|
+
file=file_descriptor,
|
411
|
+
)
|
412
|
+
# print(
|
413
|
+
# f"CATEGORY: {None}",
|
414
|
+
# end="\r\n",
|
415
|
+
# file=file_descriptor,
|
416
|
+
# )
|
417
|
+
print(
|
418
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
419
|
+
end="\r\n",
|
420
|
+
file=file_descriptor,
|
421
|
+
)
|
422
|
+
|
423
|
+
print(
|
424
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
425
|
+
end="\r\n",
|
426
|
+
file=file_descriptor,
|
427
|
+
)
|
428
|
+
ops = f"@{self.station.get('Call','')}"
|
429
|
+
list_of_ops = self.database.get_ops()
|
430
|
+
for op in list_of_ops:
|
431
|
+
ops += f", {op.get('Operator', '')}"
|
432
|
+
print(
|
433
|
+
f"OPERATORS: {ops}",
|
434
|
+
end="\r\n",
|
435
|
+
file=file_descriptor,
|
436
|
+
)
|
437
|
+
print(
|
438
|
+
f"NAME: {self.station.get('Name', '')}",
|
439
|
+
end="\r\n",
|
440
|
+
file=file_descriptor,
|
441
|
+
)
|
442
|
+
print(
|
443
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
444
|
+
end="\r\n",
|
445
|
+
file=file_descriptor,
|
446
|
+
)
|
447
|
+
print(
|
448
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
449
|
+
end="\r\n",
|
450
|
+
file=file_descriptor,
|
451
|
+
)
|
452
|
+
print(
|
453
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
454
|
+
end="\r\n",
|
455
|
+
file=file_descriptor,
|
456
|
+
)
|
457
|
+
print(
|
458
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
459
|
+
end="\r\n",
|
460
|
+
file=file_descriptor,
|
461
|
+
)
|
462
|
+
print(
|
463
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
464
|
+
end="\r\n",
|
465
|
+
file=file_descriptor,
|
466
|
+
)
|
467
|
+
print(
|
468
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
469
|
+
end="\r\n",
|
470
|
+
file=file_descriptor,
|
471
|
+
)
|
472
|
+
for contact in log:
|
473
|
+
the_date_and_time = contact.get("TS", "")
|
474
|
+
themode = contact.get("Mode", "")
|
475
|
+
if themode == "LSB" or themode == "USB":
|
476
|
+
themode = "PH"
|
477
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
478
|
+
|
479
|
+
loggeddate = the_date_and_time[:10]
|
480
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
481
|
+
print(
|
482
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
483
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
484
|
+
f"{str(contact.get('SNT', '')).ljust(3)} "
|
485
|
+
f"{str(contact.get('SentNr', '')).ljust(6)} "
|
486
|
+
f"{contact.get('Call', '').ljust(13)} "
|
487
|
+
f"{str(contact.get('RCV', '')).ljust(3)} "
|
488
|
+
f"{str(contact.get('NR', '')).ljust(6)}",
|
489
|
+
end="\r\n",
|
490
|
+
file=file_descriptor,
|
491
|
+
)
|
492
|
+
print("END-OF-LOG:", end="\r\n", file=file_descriptor)
|
493
|
+
self.show_message_box(f"Cabrillo saved to: {filename}")
|
494
|
+
except IOError as exception:
|
495
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
496
|
+
self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
|
497
|
+
return
|
not1mm/plugins/k1usn_sst.py
CHANGED
@@ -33,11 +33,11 @@ from not1mm.lib.version import __version__
|
|
33
33
|
|
34
34
|
logger = logging.getLogger(__name__)
|
35
35
|
|
36
|
-
EXCHANGE_HINT = "Name
|
36
|
+
EXCHANGE_HINT = "Name + SPC"
|
37
37
|
|
38
|
-
name = "
|
39
|
-
cabrillo_name = "
|
40
|
-
mode = "
|
38
|
+
name = "K1USN SLOW SPEED TEST"
|
39
|
+
cabrillo_name = "K1USN-SST"
|
40
|
+
mode = "CW" # CW SSB BOTH RTTY
|
41
41
|
# columns = [0, 1, 2, 3, 4, 10, 11, 14, 15]
|
42
42
|
columns = [
|
43
43
|
"YYYY-MM-DD HH:MM:SS",
|
@@ -73,8 +73,8 @@ def interface(self):
|
|
73
73
|
namefield.setText("Name")
|
74
74
|
self.field3.setAccessibleName("Name")
|
75
75
|
spc = self.field4.findChild(QtWidgets.QLabel)
|
76
|
-
spc.setText("
|
77
|
-
self.field4.setAccessibleName("
|
76
|
+
spc.setText("SPC")
|
77
|
+
self.field4.setAccessibleName("SPC")
|
78
78
|
|
79
79
|
|
80
80
|
def reset_label(self):
|
@@ -6,10 +6,8 @@ Purpose: test alternative sound playing interface
|
|
6
6
|
# pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines, no-name-in-module
|
7
7
|
# pylint: disable=logging-fstring-interpolation, logging-not-lazy, line-too-long, bare-except
|
8
8
|
|
9
|
-
from not1mm.lib.
|
9
|
+
from not1mm.lib.ham_utility import parse_udc
|
10
10
|
|
11
|
-
|
11
|
+
filename = "./testing/K1USNSSTOP.udc"
|
12
12
|
|
13
|
-
filename
|
14
|
-
|
15
|
-
playsound(filename, True)
|
13
|
+
print(f"{parse_udc(filename)}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version: 24.8.
|
3
|
+
Version: 24.8.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
|
@@ -69,6 +69,7 @@ Requires-Dist: Levenshtein
|
|
69
69
|
- [Fedora 38 \& 39](#fedora-38--39)
|
70
70
|
- [Fedora 40](#fedora-40)
|
71
71
|
- [Manjaro](#manjaro)
|
72
|
+
- [Mint](#mint)
|
72
73
|
- [Python, PyPI, pip and pipx](#python-pypi-pip-and-pipx)
|
73
74
|
- [Bootstrapping pipx](#bootstrapping-pipx)
|
74
75
|
- [Installing with pipx](#installing-with-pipx)
|
@@ -209,10 +210,12 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
209
210
|
- CQ World Wide CW
|
210
211
|
- CQ World Wide SSB
|
211
212
|
- CWOps CWT
|
213
|
+
- Helvetia
|
212
214
|
- IARU HF
|
213
215
|
- ICWC MST
|
214
216
|
- Japan International DX CW
|
215
217
|
- Japan International DX SSB
|
218
|
+
- K1USN Slow Speed Test
|
216
219
|
- NAQP CW
|
217
220
|
- NAQP SSB
|
218
221
|
- Phone Weekly Test
|
@@ -222,6 +225,9 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
222
225
|
|
223
226
|
## Recent Changes
|
224
227
|
|
228
|
+
- [24-8-27] Added Helvetia contest.
|
229
|
+
- [24-8-22] Add loading splash screen.
|
230
|
+
- [24-8-20] Added K1USN Slow Speed Test
|
225
231
|
- [24-8-17-1] Did an oops. Fixed the oops.
|
226
232
|
- [24-8-17] Removed some cruft. Made dockable widgets not floatable since Wayland breaks this.
|
227
233
|
|
@@ -238,8 +244,14 @@ clue me into the black magic needed to get it to work.
|
|
238
244
|
|
239
245
|
### Prerequisites
|
240
246
|
|
241
|
-
not1mm requires
|
242
|
-
|
247
|
+
not1mm requires:
|
248
|
+
|
249
|
+
- Python 3.9+
|
250
|
+
- PyQt6
|
251
|
+
- libportaudio2
|
252
|
+
- libxcb-cursor0 (maybe... Depends on the distro)
|
253
|
+
|
254
|
+
You should install these through your distribution's package manager before continuing.
|
243
255
|
|
244
256
|
### Common installation recipes for Ubuntu and Fedora
|
245
257
|
|
@@ -316,6 +328,22 @@ pip install not1mm
|
|
316
328
|
pamac build not1mm-git
|
317
329
|
```
|
318
330
|
|
331
|
+
</details>
|
332
|
+
|
333
|
+
<details>
|
334
|
+
|
335
|
+
<summary><b>Mint 22</b></summary>
|
336
|
+
|
337
|
+
#### Mint
|
338
|
+
|
339
|
+
```bash
|
340
|
+
sudo apt install python3-pip
|
341
|
+
sudo apt install pipx
|
342
|
+
sudo apt install libxcb-cursor0
|
343
|
+
pipx install not1mm
|
344
|
+
pipx ensurepath
|
345
|
+
```
|
346
|
+
|
319
347
|
</details>
|
320
348
|
<br>
|
321
349
|
|
@@ -427,7 +455,9 @@ qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it
|
|
427
455
|
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
|
428
456
|
```
|
429
457
|
|
430
|
-
|
458
|
+
You can use your package manager to load libxcb-cursor0.
|
459
|
+
|
460
|
+
If that's not an option, you can export an environment variable and launch the app like this:
|
431
461
|
|
432
462
|
`mbridak@vm:~$ export QT_QPA_PLATFORM=wayland; not1mm`
|
433
463
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=QJRnfWEcHEQ40ESeIeEtPB6lOwMySP8r6Ao-4TBqLoc,121832
|
3
3
|
not1mm/bandmap.py,sha256=1b5tXCfGTnpqqn6hPNt7zRA8SmuwSXzSwNHZXhCRt70,31434
|
4
4
|
not1mm/checkwindow.py,sha256=aI-nr8OF90IWV7R_XRdmitvBJ9M85evCs72HoU3Jnvc,10374
|
5
5
|
not1mm/fsutils.py,sha256=ukHKxKTeNKxKwqRaJjtzRShL4X5Xl0jRBbADyy3Ifp8,1701
|
6
6
|
not1mm/logwindow.py,sha256=pwhiwolmGnW01LF4sjlu3ywLsgfxL6KuGuKuYKYmgeY,44403
|
7
|
-
not1mm/playsoundtest.py,sha256=_kvvOfgs-u-H4kVSiSlnDtn9HWv0RiJQybkv24CEngc,464
|
8
7
|
not1mm/radio.py,sha256=eiB04LPMPBeMrBRI021Z7VXth66EOYb0Ujh11T9877c,3362
|
8
|
+
not1mm/test.py,sha256=ev_YgRFBurFw7_W1SXn509XyUkC6tWchLF5w_c8Z-ow,422
|
9
9
|
not1mm/vfo.py,sha256=IvmUQYMIPzLJw_BHQGis4J_IEW-vlBtdfxZLXPh7OzI,12335
|
10
10
|
not1mm/voice_keying.py,sha256=sA3gw5_k7kShTg2qhG7HkKDM5M6KheJVRkAc_C7mxDk,3006
|
11
11
|
not1mm/data/JetBrainsMono-Regular.ttf,sha256=UOHctAKY_PzCGh7zy-6f6egnCcSK0wzmF0csBqO9lDY,203952
|
@@ -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=
|
33
|
+
not1mm/data/new_contest.ui,sha256=6j4OYcTjSx-5ywvBf4GQfuAEaavCJVPVwzj_es5ajsc,22138
|
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
|
@@ -39,6 +39,7 @@ not1mm/data/radio_grey.png,sha256=9eOtMHDpQvRYY29D7_vPeacWbwotRXZTMm8EiHE9TW0,12
|
|
39
39
|
not1mm/data/radio_red.png,sha256=QvkMk7thd_hCEIyK5xGAG4xVVXivl39nwOfD8USDI20,957
|
40
40
|
not1mm/data/reddot.png,sha256=M33jEMoU8W4rQ4_MVyzzKxDPDte1ypKBch5VnUMNLKE,565
|
41
41
|
not1mm/data/settings.ui,sha256=xXvcL8nRIbGYU3tr9YjLAlTAYxFbMtRXjlZlv_CLg4A,40112
|
42
|
+
not1mm/data/splash.png,sha256=85_BQotR1q24uCthrKm4SB_6ZOMwRjR-Jdp1XBHSTyg,5368
|
42
43
|
not1mm/data/ssbmacros.txt,sha256=0Qccj4y0nlK-w5da9a9ti-jILkURtwztoDuL_D0pEJM,470
|
43
44
|
not1mm/data/vfo.ui,sha256=ixer0pVVr8o21j_AmBA3J1OEGd96EXVFhkoNhqIQG10,2054
|
44
45
|
not1mm/data/phonetics/0.wav,sha256=0OpYiR-3MK6fVHE6MB-HeOxSAPiDNMjqvx5JcIZtsQk,42590
|
@@ -93,23 +94,23 @@ not1mm/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
93
94
|
not1mm/lib/about.py,sha256=sWycfGcruN3SaEe4JmaJ61K6D8Itq0WxpUYT-lEcmYM,416
|
94
95
|
not1mm/lib/cat_interface.py,sha256=aazvNTSeZAROq3KL8gPx-I95iVez2IiIOSk22qeqVCQ,19502
|
95
96
|
not1mm/lib/cwinterface.py,sha256=Q8p3pScOHczZ8ptICfH1Yu6rCEwQJLgrNwYMN76B2i8,3389
|
96
|
-
not1mm/lib/database.py,sha256=
|
97
|
+
not1mm/lib/database.py,sha256=rX1wOoSiSuX7CCFghvD_yc4q8E0FHwZp1k7Z2iVNYv8,43680
|
97
98
|
not1mm/lib/edit_contact.py,sha256=Ki9bGPpqyQQBB1cU8VIBDCal3lbXeQ6qxhzklmhE2_w,353
|
98
99
|
not1mm/lib/edit_macro.py,sha256=raKWBwsHInj5EUKmvyLQ6gqc3ZFDlstsD3xqoM4PC8E,517
|
99
100
|
not1mm/lib/edit_opon.py,sha256=j3qJ1aBsQoIOnQ9yiBl3lyeISvKTP0I_rtBYBPAfgeI,359
|
100
101
|
not1mm/lib/edit_station.py,sha256=doL21Hs6jzIE43ohAopdFt_iqnRJZHFcqzcnCS0-iio,1965
|
101
102
|
not1mm/lib/ft8_watcher.py,sha256=ISfXjs-Mgbz_lE5SThEnFoCe8apNLElgSuECAMCH18I,4080
|
102
|
-
not1mm/lib/ham_utility.py,sha256=
|
103
|
+
not1mm/lib/ham_utility.py,sha256=uRErxCxZr8dfxzekPyett0e_BABDVOCvSUUTzXq6ctE,11790
|
103
104
|
not1mm/lib/lookup.py,sha256=F2fl5QkMxaGSxl1XMWnLUub3T9Mt7LhCX4acOlAsks4,13952
|
104
105
|
not1mm/lib/multicast.py,sha256=bnFUNHyy82GmIb3_88EPBVVssj7-HzkJPaH671cK8Qw,3249
|
105
106
|
not1mm/lib/n1mm.py,sha256=H54mpgJF0GAmKavM-nb5OAq2SJFWYkux4eMWWiSRxJc,6288
|
106
107
|
not1mm/lib/new_contest.py,sha256=IznTDMq7yXHB6zBoGUEC_WDYPCPpsSZW4wwMJi16zK0,816
|
107
108
|
not1mm/lib/playsound.py,sha256=kxkcitBFbZCXJ2wxQ1lxg4rBwfxiSpuNpJSXHOPCoXA,9241
|
108
|
-
not1mm/lib/plugin_common.py,sha256=
|
109
|
+
not1mm/lib/plugin_common.py,sha256=wuG7B0OJx9zYc5Gew3fdt_lNyan8Ul9KNlPQ7PDKGsU,9114
|
109
110
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
110
111
|
not1mm/lib/settings.py,sha256=MWiKXbasaFbzeHTjfzTaTqbCBrIijudP_-0a5jNmUAA,9265
|
111
112
|
not1mm/lib/super_check_partial.py,sha256=p5l3u2ZOCBtlWgbvskC50FpuoaIpR07tfC6zTdRWbh4,2334
|
112
|
-
not1mm/lib/version.py,sha256=
|
113
|
+
not1mm/lib/version.py,sha256=1KiLcfpXjS8-V6c6tXOR_NoOKat-5IpaUjb1wrD5Q8g,48
|
113
114
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
114
115
|
not1mm/plugins/10_10_fall_cw.py,sha256=IttjX1yy4nDdACGsiYlPteFG8eVseX_WtoFio6bqHE8,10953
|
115
116
|
not1mm/plugins/10_10_spring_cw.py,sha256=ThCptdM3dX4ywhoy2JRcOEyHSqcJolFaT7O_PYzM1Mg,10958
|
@@ -135,19 +136,20 @@ not1mm/plugins/cq_ww_cw.py,sha256=ltXFnSXabCOuW70s-WOydgghZTNpztX8TKLpVIV50B4,11
|
|
135
136
|
not1mm/plugins/cq_ww_ssb.py,sha256=kt-EQofmCbynX1iXFm9ehffi_TMW25ke8Qi9MiR69ZQ,11199
|
136
137
|
not1mm/plugins/cwt.py,sha256=4xdXN6ZJM5k-6gn0hJzNheWfFlGiqquC2p0ZMEe516M,12818
|
137
138
|
not1mm/plugins/general_logging.py,sha256=t02xtJs601qRICGdrvLs3G9y4GCG9H4AgQNkgA18CYs,3467
|
139
|
+
not1mm/plugins/helvetia.py,sha256=OtMTOw3-SavrhTNRb_lulTX9BEaNbQdK5lLufowKihY,15432
|
138
140
|
not1mm/plugins/iaru_hf.py,sha256=-ROUo2gBkw3xB89t8bd-4f7_1hROw2VXZXVHLFdB62s,11541
|
139
141
|
not1mm/plugins/icwc_mst.py,sha256=BaUP2kzrT2D27un_WLGT4HCTTi1e7CNYC4NHcC_9r74,11842
|
140
142
|
not1mm/plugins/jidx_cw.py,sha256=9oV4hDxMiGXa9wuYUNYOCsr-mz8LYB-4WMHBN8u2dFk,12153
|
141
143
|
not1mm/plugins/jidx_ph.py,sha256=T-V7-77SIwu-Jl55VIrbVFZlsBoc97mXtgbdde0GaiQ,11183
|
142
|
-
not1mm/plugins/k1usn_sst.py,sha256=
|
144
|
+
not1mm/plugins/k1usn_sst.py,sha256=2Nu7SRiQeUG3mL9CLKReRLh8vKsNbWcizMgv9MTLkrg,11671
|
143
145
|
not1mm/plugins/naqp_cw.py,sha256=c0MuKqfkIxiYFvv2z7vqrBz3m9FSnSYkPK3f-DdkTIA,12632
|
144
146
|
not1mm/plugins/naqp_ssb.py,sha256=VLWVrSzI0UP1AhSXYn61eZ7or1rz6a_pS_xCKfgS4Jw,11595
|
145
147
|
not1mm/plugins/phone_weekly_test.py,sha256=fLpMe03WB9_KgRl6vMgQQt_aktFdqfNt2Sw81CTRAUs,12325
|
146
148
|
not1mm/plugins/stew_perry_topband.py,sha256=CKBQbYl4ETxhXJd2dma4fg_C5pag_s7Nf61SCztZtqE,10668
|
147
149
|
not1mm/plugins/winter_field_day.py,sha256=4rcfRtobwjHO6BNL3WOTHzBmyyeuX79BNGBG8PfjrI8,10238
|
148
|
-
not1mm-24.8.
|
149
|
-
not1mm-24.8.
|
150
|
-
not1mm-24.8.
|
151
|
-
not1mm-24.8.
|
152
|
-
not1mm-24.8.
|
153
|
-
not1mm-24.8.
|
150
|
+
not1mm-24.8.27.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
151
|
+
not1mm-24.8.27.dist-info/METADATA,sha256=PC9MtwYLjp66VOkyLGbCkMNw4Eb1Z5PoF3AkrKQCh6I,29688
|
152
|
+
not1mm-24.8.27.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
153
|
+
not1mm-24.8.27.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
154
|
+
not1mm-24.8.27.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
155
|
+
not1mm-24.8.27.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|