not1mm 23.3.24.1__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 +24 -131
- not1mm/data/main.ui +6 -0
- not1mm/lib/database.py +24 -0
- not1mm/lib/version.py +1 -1
- not1mm/plugins/cq_wpx_cw.py +389 -0
- not1mm/plugins/cq_wpx_ssb.py +232 -1
- {not1mm-23.3.24.1.dist-info → not1mm-23.3.27.dist-info}/METADATA +12 -1
- {not1mm-23.3.24.1.dist-info → not1mm-23.3.27.dist-info}/RECORD +12 -11
- {not1mm-23.3.24.1.dist-info → not1mm-23.3.27.dist-info}/LICENSE +0 -0
- {not1mm-23.3.24.1.dist-info → not1mm-23.3.27.dist-info}/WHEEL +0 -0
- {not1mm-23.3.24.1.dist-info → not1mm-23.3.27.dist-info}/entry_points.txt +0 -0
- {not1mm-23.3.24.1.dist-info → not1mm-23.3.27.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -206,6 +206,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
206
206
|
self.actionPreferences.triggered.connect(self.preference_selected)
|
207
207
|
self.actionQRZ_Settings.triggered.connect(self.qrz_preference_selected)
|
208
208
|
self.actionGenerate_Cabrillo.triggered.connect(self.generate_cabrillo)
|
209
|
+
self.actionGenerate_ADIF.triggered.connect(self.generate_adif)
|
209
210
|
self.actionLog_Window.triggered.connect(self.launch_log_window)
|
210
211
|
self.radioButton_run.clicked.connect(self.run_sp_buttons_clicked)
|
211
212
|
self.radioButton_sp.clicked.connect(self.run_sp_buttons_clicked)
|
@@ -511,7 +512,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
511
512
|
def save_contact(self):
|
512
513
|
"""Save to db"""
|
513
514
|
logger.debug("saving")
|
514
|
-
if len(self.callsign.text()) <
|
515
|
+
if len(self.callsign.text()) < 3:
|
515
516
|
return
|
516
517
|
if not any(char.isdigit() for char in self.callsign.text()):
|
517
518
|
return
|
@@ -662,7 +663,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
662
663
|
|
663
664
|
def select_contest(self):
|
664
665
|
"""Load contest"""
|
665
|
-
self.contest = doimp("
|
666
|
+
self.contest = doimp("cq_wpx_cw")
|
666
667
|
logger.debug("Loaded Contest Name = %s", self.contest.name)
|
667
668
|
self.contest.init_contest(self)
|
668
669
|
|
@@ -983,10 +984,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
983
984
|
"""Called when text in the callsign field has changed"""
|
984
985
|
text = self.callsign.text()
|
985
986
|
text = text.upper()
|
986
|
-
|
987
|
+
position = self.callsign.cursorPosition()
|
988
|
+
stripped_text = text.strip().replace(" ", "")
|
987
989
|
self.callsign.setText(stripped_text)
|
990
|
+
self.callsign.setCursorPosition(position)
|
988
991
|
|
989
|
-
if
|
992
|
+
if " " in text:
|
990
993
|
if stripped_text == "CW":
|
991
994
|
self.setmode("CW")
|
992
995
|
self.radio_state["mode"] = "CW"
|
@@ -1112,9 +1115,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1112
1115
|
"""Checks if a callsign is a dupe on current band/mode."""
|
1113
1116
|
band = float(get_logged_band(str(self.radio_state.get("vfoa", 0.0))))
|
1114
1117
|
mode = self.radio_state.get("mode", "")
|
1115
|
-
debugline =
|
1118
|
+
debugline = (
|
1119
|
+
f"Call: {call} Band: {band} Mode: {mode} Dupetype: {self.contest.dupe_type}"
|
1120
|
+
)
|
1116
1121
|
logger.debug("%s", debugline)
|
1117
|
-
|
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}
|
1118
1130
|
debugline = f"{result}"
|
1119
1131
|
logger.debug("%s", debugline)
|
1120
1132
|
return result.get("isdupe", False)
|
@@ -1232,135 +1244,16 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1232
1244
|
self.F12.setText(f"F12: {self.fkeys['F12'][0]}")
|
1233
1245
|
self.F12.setToolTip(self.fkeys["F12"][1])
|
1234
1246
|
|
1247
|
+
def generate_adif(self):
|
1248
|
+
"""Generate ADIF"""
|
1249
|
+
logger.debug("******ADIF*****")
|
1250
|
+
self.contest.adif(self)
|
1251
|
+
|
1235
1252
|
def generate_cabrillo(self):
|
1236
1253
|
"""Generates Cabrillo file. Maybe."""
|
1237
1254
|
# https://www.cqwpx.com/cabrillo.htm
|
1238
1255
|
logger.debug("******Cabrillo*****")
|
1239
|
-
|
1240
|
-
str(Path.home())
|
1241
|
-
+ "/"
|
1242
|
-
+ f"{self.pref.get('callsign').upper()}_{self.contest.cabrillo_name}.log"
|
1243
|
-
)
|
1244
|
-
logger.debug("%s", filename)
|
1245
|
-
# self.infobox.setTextColor(QtGui.QColor(211, 215, 207))
|
1246
|
-
# self.infobox.insertPlainText(f"Saving cabrillo to: {filename}")
|
1247
|
-
# app.processEvents()
|
1248
|
-
# bonuses = 0
|
1249
|
-
log = self.database.fetch_all_contacts_asc()
|
1250
|
-
# catpower = ""
|
1251
|
-
try:
|
1252
|
-
with open(filename, "w", encoding="ascii") as file_descriptor:
|
1253
|
-
print("START-OF-LOG: 3.0", end="\r\n", file=file_descriptor)
|
1254
|
-
print(
|
1255
|
-
f"CREATED-BY: Not1MM v{__version__}",
|
1256
|
-
end="\r\n",
|
1257
|
-
file=file_descriptor,
|
1258
|
-
)
|
1259
|
-
print(
|
1260
|
-
f"CONTEST: {self.contest.cabrillo_name}",
|
1261
|
-
end="\r\n",
|
1262
|
-
file=file_descriptor,
|
1263
|
-
)
|
1264
|
-
print(
|
1265
|
-
f"CALLSIGN: {self.pref.get('callsign','')}",
|
1266
|
-
end="\r\n",
|
1267
|
-
file=file_descriptor,
|
1268
|
-
)
|
1269
|
-
print(
|
1270
|
-
f"LOCATION: {self.pref.get('section', '')}",
|
1271
|
-
end="\r\n",
|
1272
|
-
file=file_descriptor,
|
1273
|
-
)
|
1274
|
-
# print(
|
1275
|
-
# f"ARRL-SECTION: {self.pref.get('section', '')}",
|
1276
|
-
# end="\r\n",
|
1277
|
-
# file=file_descriptor,
|
1278
|
-
# )
|
1279
|
-
print(
|
1280
|
-
f"CATEGORY: {None}",
|
1281
|
-
end="\r\n",
|
1282
|
-
file=file_descriptor,
|
1283
|
-
)
|
1284
|
-
print("CATEGORY-POWER: ", end="\r\n", file=file_descriptor)
|
1285
|
-
|
1286
|
-
print(
|
1287
|
-
f"CLAIMED-SCORE: {self.contest.calc_score(self)}",
|
1288
|
-
end="\r\n",
|
1289
|
-
file=file_descriptor,
|
1290
|
-
)
|
1291
|
-
print(
|
1292
|
-
"OPERATORS: ",
|
1293
|
-
end="\r\n",
|
1294
|
-
file=file_descriptor,
|
1295
|
-
)
|
1296
|
-
print(
|
1297
|
-
f"NAME: {self.pref.get('name', '')}",
|
1298
|
-
end="\r\n",
|
1299
|
-
file=file_descriptor,
|
1300
|
-
)
|
1301
|
-
print(
|
1302
|
-
f"ADDRESS: {self.pref.get('address1', '')}",
|
1303
|
-
end="\r\n",
|
1304
|
-
file=file_descriptor,
|
1305
|
-
)
|
1306
|
-
print(
|
1307
|
-
f"ADDRESS-CITY: {self.pref.get('city', '')}",
|
1308
|
-
end="\r\n",
|
1309
|
-
file=file_descriptor,
|
1310
|
-
)
|
1311
|
-
print(
|
1312
|
-
f"ADDRESS-STATE: {self.pref.get('state', '')}",
|
1313
|
-
end="\r\n",
|
1314
|
-
file=file_descriptor,
|
1315
|
-
)
|
1316
|
-
print(
|
1317
|
-
f"ADDRESS-POSTALCODE: {self.pref.get('zip', '')}",
|
1318
|
-
end="\r\n",
|
1319
|
-
file=file_descriptor,
|
1320
|
-
)
|
1321
|
-
print(
|
1322
|
-
f"ADDRESS-COUNTRY: {self.pref.get('country', '')}",
|
1323
|
-
end="\r\n",
|
1324
|
-
file=file_descriptor,
|
1325
|
-
)
|
1326
|
-
print(
|
1327
|
-
f"EMAIL: {self.pref.get('email', '')}",
|
1328
|
-
end="\r\n",
|
1329
|
-
file=file_descriptor,
|
1330
|
-
)
|
1331
|
-
for contact in log:
|
1332
|
-
# hiscall = contact.get("Call", "")
|
1333
|
-
# hisclass = contact.get("class")
|
1334
|
-
# hissection = contact.get("section")
|
1335
|
-
the_date_and_time = contact.get("TS", "")
|
1336
|
-
# band = contact.get("Band", "")
|
1337
|
-
mode = contact.get("Mode", "")
|
1338
|
-
if mode == "LSB" or mode == "USB":
|
1339
|
-
mode = "PH"
|
1340
|
-
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
1341
|
-
|
1342
|
-
loggeddate = the_date_and_time[:10]
|
1343
|
-
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
1344
|
-
print(
|
1345
|
-
f"QSO: {frequency} {mode} {loggeddate} {loggedtime} "
|
1346
|
-
f"{contact.get('StationPrefix', '').ljust(13)} "
|
1347
|
-
f"{str(contact.get('SNT', '')).ljust(3)} "
|
1348
|
-
f"{str(contact.get('SentNr', '')).ljust(6)} "
|
1349
|
-
f"{contact.get('Call', '').ljust(13)} "
|
1350
|
-
f"{str(contact.get('RCV', '')).ljust(3)} "
|
1351
|
-
f"{str(contact.get('NR', '')).ljust(6)}",
|
1352
|
-
end="\r\n",
|
1353
|
-
file=file_descriptor,
|
1354
|
-
)
|
1355
|
-
print("END-OF-LOG:", end="\r\n", file=file_descriptor)
|
1356
|
-
except IOError as exception:
|
1357
|
-
logger.critical(
|
1358
|
-
"cabrillo: IO error: %s, writing to %s", exception, filename
|
1359
|
-
)
|
1360
|
-
# self.infobox.insertPlainText(" Failed\n\n")
|
1361
|
-
# app.processEvents()
|
1362
|
-
return
|
1363
|
-
# self.infobox.insertPlainText(" Done\n\n")
|
1256
|
+
self.contest.cabrillo(self)
|
1364
1257
|
|
1365
1258
|
|
1366
1259
|
def load_fonts_from_dir(directory: str) -> set:
|
not1mm/data/main.ui
CHANGED
@@ -789,6 +789,7 @@
|
|
789
789
|
<addaction name="actionQRZ_Settings"/>
|
790
790
|
<addaction name="actionConnection_Settings"/>
|
791
791
|
<addaction name="actionGenerate_Cabrillo"/>
|
792
|
+
<addaction name="actionGenerate_ADIF"/>
|
792
793
|
</widget>
|
793
794
|
<widget class="QMenu" name="menuHelp">
|
794
795
|
<property name="title">
|
@@ -930,6 +931,11 @@
|
|
930
931
|
<string>Log Window</string>
|
931
932
|
</property>
|
932
933
|
</action>
|
934
|
+
<action name="actionGenerate_ADIF">
|
935
|
+
<property name="text">
|
936
|
+
<string>Generate ADIF</string>
|
937
|
+
</property>
|
938
|
+
</action>
|
933
939
|
</widget>
|
934
940
|
<resources/>
|
935
941
|
<connections/>
|
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.
|
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
|
not1mm/plugins/cq_wpx_ssb.py
CHANGED
@@ -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 =
|
18
|
+
dupe_type = 2
|
13
19
|
|
14
20
|
|
15
21
|
def init_contest(self):
|
@@ -156,3 +162,228 @@ def calc_score(self):
|
|
156
162
|
mults = int(result.get("wpx_count", 0))
|
157
163
|
return contest_points * mults
|
158
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,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version: 23.3.
|
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,8 @@ Feature complete.
|
|
74
75
|
|
75
76
|
## Changes of note
|
76
77
|
|
78
|
+
- [23-3-27] Fix cursor behaviour when editing text in callsign field.
|
79
|
+
- [23-3-25] Fix minimum call length. Fix cabrillo tag. Add adif output.
|
77
80
|
- [23-3-24] Added dupe checking. Added CAT check for flrig or rigctld. Added online flag for flrig.
|
78
81
|
- [23-3-23] Added most of Cabrillo generation. Plan to test it this weekends CQ WPX SSB.
|
79
82
|
- [23-3-22] Add prefill of serial nr. set OP call on startup. Set IsMultiplier1 new unique wpx. Add OP and contest name to window title. and stuff.
|
@@ -196,6 +199,14 @@ So for me it would be:
|
|
196
199
|
|
197
200
|
K6GTE_CQ-WPX-SSB.log
|
198
201
|
|
202
|
+
## ADIF
|
203
|
+
|
204
|
+
`File` > `Generate ADIF`
|
205
|
+
|
206
|
+
Boom... ADIF
|
207
|
+
|
208
|
+
`StationCall`_`ContestName`.adi
|
209
|
+
|
199
210
|
## Dupe checking
|
200
211
|
|
201
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=
|
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
|
@@ -17,7 +17,7 @@ not1mm/data/k6gte.not1mm-128.png,sha256=vWqt3Cgsaguj-BBiIoSJApzzhisPxldM8HZQbZ05
|
|
17
17
|
not1mm/data/k6gte.not1mm-32.png,sha256=yucSwzlmqv3NegdWUvPvZzSgP7G22Ky3se8TWRXvzfI,1108
|
18
18
|
not1mm/data/k6gte.not1mm-64.png,sha256=1KQvk0WBckUds79BvIFUt-KdTwQKKvTz6hiJu8MiT68,2152
|
19
19
|
not1mm/data/logwindow.ui,sha256=_-wobHhIjALzCswyXIrqNadnLdc88eay1GNF23a-Qh0,970
|
20
|
-
not1mm/data/main.ui,sha256=
|
20
|
+
not1mm/data/main.ui,sha256=ro6ws39JgvJFHQvvpA6bO5hTevP8bQr2slFFyqAGpq8,29483
|
21
21
|
not1mm/data/opon.ui,sha256=6r9_6ORGfNqwOnpzQjaJ1tWP_81amuXqLYlx1hHgdME,2018
|
22
22
|
not1mm/data/reddot.png,sha256=M33jEMoU8W4rQ4_MVyzzKxDPDte1ypKBch5VnUMNLKE,565
|
23
23
|
not1mm/data/settings.ui,sha256=-uEW4fQWolcv6QrNVpQ_TYhpJLCnhnCiggVSMR27cpA,35558
|
@@ -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=
|
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=
|
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/
|
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.
|
52
|
-
not1mm-23.3.
|
53
|
-
not1mm-23.3.
|
54
|
-
not1mm-23.3.
|
55
|
-
not1mm-23.3.
|
56
|
-
not1mm-23.3.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|