not1mm 25.4.8__py3-none-any.whl → 25.4.10__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 +27 -8
- not1mm/data/greendot.png +0 -0
- not1mm/data/new_contest.ui +5 -0
- not1mm/lib/version.py +2 -1
- not1mm/plugins/ukeidx.py +597 -0
- {not1mm-25.4.8.dist-info → not1mm-25.4.10.dist-info}/METADATA +17 -4
- {not1mm-25.4.8.dist-info → not1mm-25.4.10.dist-info}/RECORD +11 -10
- {not1mm-25.4.8.dist-info → not1mm-25.4.10.dist-info}/WHEEL +0 -0
- {not1mm-25.4.8.dist-info → not1mm-25.4.10.dist-info}/entry_points.txt +0 -0
- {not1mm-25.4.8.dist-info → not1mm-25.4.10.dist-info}/licenses/LICENSE +0 -0
- {not1mm-25.4.8.dist-info → not1mm-25.4.10.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -795,12 +795,20 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
795
795
|
try:
|
796
796
|
with open(filename, "rt", encoding="utf-8") as file_descriptor:
|
797
797
|
lines = file_descriptor.readlines()
|
798
|
-
|
799
|
-
|
798
|
+
substring_to_find = "!!Order!!"
|
799
|
+
found_index = -1 # Initialize to -1 to indicate not found
|
800
|
+
|
801
|
+
for index, item in enumerate(lines):
|
802
|
+
if substring_to_find in item:
|
803
|
+
found_index = index
|
804
|
+
break # Exit the loop once found
|
805
|
+
|
806
|
+
if found_index != -1:
|
807
|
+
item_names = lines[found_index].strip().split(",")
|
800
808
|
# ['!!Order!!', 'Call', 'Sect', 'State', 'CK', 'UserText', '']
|
801
809
|
item_names = item_names[1:]
|
802
810
|
# ['Call', 'Sect', 'State', 'CK', 'UserText', '']
|
803
|
-
lines = lines[1:]
|
811
|
+
lines = lines[found_index + 1 :]
|
804
812
|
group_list = []
|
805
813
|
for line in lines:
|
806
814
|
if line.startswith("#"):
|
@@ -832,6 +840,15 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
832
840
|
if hasattr(self.contest, "process_esm"):
|
833
841
|
self.contest.process_esm(self, new_focused_widget=new)
|
834
842
|
|
843
|
+
def make_button_blue(self, the_button: QtWidgets.QPushButton) -> None:
|
844
|
+
"""Takes supplied QPushButton object and turns it blue."""
|
845
|
+
if the_button is not None:
|
846
|
+
pal = QPalette()
|
847
|
+
pal.isCopyOf(self.current_palette)
|
848
|
+
blueColor = QColor(0, 0, 128)
|
849
|
+
pal.setBrush(QPalette.ColorRole.Button, blueColor)
|
850
|
+
the_button.setPalette(pal)
|
851
|
+
|
835
852
|
def make_button_green(self, the_button: QtWidgets.QPushButton) -> None:
|
836
853
|
"""Takes supplied QPushButton object and turns it green."""
|
837
854
|
if the_button is not None:
|
@@ -1026,7 +1043,6 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1026
1043
|
if self.bandmap_window:
|
1027
1044
|
self.bandmap_window.msg_from_main(cmd)
|
1028
1045
|
|
1029
|
-
|
1030
1046
|
if setdarkmode:
|
1031
1047
|
darkPalette = QPalette()
|
1032
1048
|
darkColor = QColor(56, 56, 56)
|
@@ -2089,6 +2105,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2089
2105
|
def stop_cw(self):
|
2090
2106
|
""""""
|
2091
2107
|
self.auto_cq = False
|
2108
|
+
self.leftdot.hide()
|
2092
2109
|
if self.cw is not None:
|
2093
2110
|
if self.cw.servertype == 1:
|
2094
2111
|
self.cw.sendcw("\x1b4")
|
@@ -2334,6 +2351,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2334
2351
|
if event.modifiers() == Qt.KeyboardModifier.ShiftModifier:
|
2335
2352
|
self.radioButton_run.setChecked(True)
|
2336
2353
|
self.run_sp_buttons_clicked()
|
2354
|
+
# self.make_button_blue(self.F1)
|
2355
|
+
self.leftdot.show()
|
2337
2356
|
self.auto_cq = True
|
2338
2357
|
self.auto_cq_time = datetime.datetime.now() + datetime.timedelta(
|
2339
2358
|
milliseconds=self.auto_cq_delay
|
@@ -2889,8 +2908,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2889
2908
|
|
2890
2909
|
logger.debug("PTT On")
|
2891
2910
|
if self.rig_control:
|
2892
|
-
self.leftdot.setPixmap(self.greendot)
|
2893
|
-
app.processEvents()
|
2911
|
+
# self.leftdot.setPixmap(self.greendot)
|
2912
|
+
# app.processEvents()
|
2894
2913
|
self.rig_control.ptt_on()
|
2895
2914
|
|
2896
2915
|
def ptt_off(self) -> None:
|
@@ -2908,8 +2927,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2908
2927
|
|
2909
2928
|
logger.debug("PTT Off")
|
2910
2929
|
if self.rig_control:
|
2911
|
-
self.leftdot.setPixmap(self.reddot)
|
2912
|
-
app.processEvents()
|
2930
|
+
# self.leftdot.setPixmap(self.reddot)
|
2931
|
+
# app.processEvents()
|
2913
2932
|
self.rig_control.ptt_off()
|
2914
2933
|
|
2915
2934
|
def process_function_key(self, function_key, rttysendrx=True) -> None:
|
not1mm/data/greendot.png
CHANGED
Binary file
|
not1mm/data/new_contest.ui
CHANGED
not1mm/lib/version.py
CHANGED
not1mm/plugins/ukeidx.py
ADDED
@@ -0,0 +1,597 @@
|
|
1
|
+
"""10 10 fall cw plugin"""
|
2
|
+
|
3
|
+
# pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member, unused-import
|
4
|
+
|
5
|
+
import datetime
|
6
|
+
import logging
|
7
|
+
from pathlib import Path
|
8
|
+
|
9
|
+
from PyQt6 import QtWidgets
|
10
|
+
|
11
|
+
from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
|
12
|
+
from not1mm.lib.version import __version__
|
13
|
+
|
14
|
+
logger = logging.getLogger(__name__)
|
15
|
+
|
16
|
+
EXCHANGE_HINT = "# or # And Dist"
|
17
|
+
|
18
|
+
ukei_pfx = [
|
19
|
+
"G",
|
20
|
+
"GD",
|
21
|
+
"GJ",
|
22
|
+
"GM",
|
23
|
+
"GI",
|
24
|
+
"GW",
|
25
|
+
"GU",
|
26
|
+
"EI",
|
27
|
+
]
|
28
|
+
|
29
|
+
name = "UKEI-DX"
|
30
|
+
cabrillo_name = "UKEI-DX"
|
31
|
+
mode = "BOTH" # CW SSB BOTH RTTY
|
32
|
+
# columns = [0, 1, 2, 3, 4, 5, 6, 15]
|
33
|
+
columns = [
|
34
|
+
"YYYY-MM-DD HH:MM:SS",
|
35
|
+
"Call",
|
36
|
+
"Freq",
|
37
|
+
"Snt",
|
38
|
+
"Rcv",
|
39
|
+
"SentNr",
|
40
|
+
"RcvNr",
|
41
|
+
"PTS",
|
42
|
+
]
|
43
|
+
|
44
|
+
# 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
|
45
|
+
dupe_type = 2
|
46
|
+
|
47
|
+
|
48
|
+
def init_contest(self):
|
49
|
+
"""setup plugin"""
|
50
|
+
set_tab_next(self)
|
51
|
+
set_tab_prev(self)
|
52
|
+
interface(self)
|
53
|
+
self.next_field = self.other_2
|
54
|
+
|
55
|
+
|
56
|
+
def interface(self):
|
57
|
+
"""Setup user interface"""
|
58
|
+
self.field1.show()
|
59
|
+
self.field2.show()
|
60
|
+
self.field3.show()
|
61
|
+
self.field4.show()
|
62
|
+
self.snt_label.setText("SNT")
|
63
|
+
self.field1.setAccessibleName("RST Sent")
|
64
|
+
self.other_label.setText("Sent Nr")
|
65
|
+
self.field2.setAccessibleName("Sent Number")
|
66
|
+
self.exch_label.setText("# and Dist")
|
67
|
+
self.field4.setAccessibleName("Number and District")
|
68
|
+
|
69
|
+
|
70
|
+
def reset_label(self):
|
71
|
+
"""reset label after field cleared"""
|
72
|
+
|
73
|
+
|
74
|
+
def set_tab_next(self):
|
75
|
+
"""Set TAB Advances"""
|
76
|
+
self.tab_next = {
|
77
|
+
self.callsign: self.sent,
|
78
|
+
self.sent: self.receive,
|
79
|
+
self.receive: self.other_1,
|
80
|
+
self.other_1: self.other_2,
|
81
|
+
self.other_2: self.callsign,
|
82
|
+
}
|
83
|
+
|
84
|
+
|
85
|
+
def set_tab_prev(self):
|
86
|
+
"""Set TAB Advances"""
|
87
|
+
self.tab_prev = {
|
88
|
+
self.callsign: self.other_2,
|
89
|
+
self.sent: self.callsign,
|
90
|
+
self.receive: self.sent,
|
91
|
+
self.other_1: self.receive,
|
92
|
+
self.other_2: self.other_1,
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
def validate(self):
|
97
|
+
"""doc"""
|
98
|
+
return True
|
99
|
+
|
100
|
+
|
101
|
+
def set_contact_vars(self):
|
102
|
+
"""Contest Specific"""
|
103
|
+
self.contact["SNT"] = self.sent.text()
|
104
|
+
self.contact["RCV"] = self.receive.text()
|
105
|
+
self.contact["NR"] = self.other_2.text().upper()
|
106
|
+
self.contact["SentNr"] = self.other_1.text()
|
107
|
+
|
108
|
+
|
109
|
+
def predupe(self):
|
110
|
+
"""called after callsign entered"""
|
111
|
+
|
112
|
+
|
113
|
+
def prefill(self):
|
114
|
+
"""Fill sentnr"""
|
115
|
+
exch = str(self.contest_settings.get("SentExchange", 0))
|
116
|
+
result = self.database.get_serial()
|
117
|
+
serial_nr = str(result.get("serial_nr", "1")).zfill(3)
|
118
|
+
if serial_nr == "None":
|
119
|
+
serial_nr = "001"
|
120
|
+
if len(self.other_1.text()) == 0:
|
121
|
+
self.other_1.setText(exch.replace("#", serial_nr))
|
122
|
+
|
123
|
+
|
124
|
+
def points(self):
|
125
|
+
"""Calc point"""
|
126
|
+
|
127
|
+
# UK/EI stations contacting :
|
128
|
+
# UK/EI/Europe 80m, 40m - 4 points 20m, 15m, 10m - 2 points
|
129
|
+
# DX (Outside Europe) 80m, 40m - 8 points 20m, 15m, 10m - 4 points
|
130
|
+
|
131
|
+
# Note : For UK/EI stations only, all QSOs will score double points between the hours of 0100z and 0459z.
|
132
|
+
|
133
|
+
# European stations contacting :
|
134
|
+
# UK/EI 80m, 40m - 4 points 20m, 15m, 10m - 2 points
|
135
|
+
# Europe 80m, 40m - 2 points 20m, 15m, 10m - 1 points
|
136
|
+
# DX (Outside Europe) 80m, 40m - 4 points 20m, 15m, 10m - 2 points
|
137
|
+
|
138
|
+
# DX (Outside Europe) contacting :
|
139
|
+
# UK/EI 80m, 40m - 8 points 20m, 15m, 10m - 4 points
|
140
|
+
# Europe 80m, 40m - 4 points 20m, 15m, 10m - 2 points
|
141
|
+
# DX (Outside Europe) 80m, 40m - 2 points 20m, 15m, 10m - 1 points
|
142
|
+
|
143
|
+
# f"{primary_pfx}: {continent}/{entity} cq:{cq} itu:{itu}"
|
144
|
+
|
145
|
+
if self.contact_is_dupe > 0:
|
146
|
+
return 0
|
147
|
+
|
148
|
+
myprimary_pfx = ""
|
149
|
+
# mycountry = ""
|
150
|
+
mycontinent = ""
|
151
|
+
hisprimary_pfx = ""
|
152
|
+
# hiscountry = ""
|
153
|
+
hiscontinent = ""
|
154
|
+
|
155
|
+
result = self.cty_lookup(self.station.get("Call", ""))
|
156
|
+
if result:
|
157
|
+
for item in result.items():
|
158
|
+
myprimary_pfx = item[1].get("primary_pfx", "")
|
159
|
+
# mycountry = item[1].get("entity", "")
|
160
|
+
mycontinent = item[1].get("continent", "")
|
161
|
+
|
162
|
+
result = self.cty_lookup(self.contact.get("Call", ""))
|
163
|
+
if result:
|
164
|
+
for item in result.items():
|
165
|
+
hisprimary_pfx = item[1].get("primary_pfx", "")
|
166
|
+
# hiscountry = item[1].get("entity", "")
|
167
|
+
hiscontinent = item[1].get("continent", "")
|
168
|
+
|
169
|
+
st = 100
|
170
|
+
et = 459
|
171
|
+
zt = datetime.datetime.now(datetime.timezone.utc).isoformat(" ")[11:16]
|
172
|
+
ct = int(zt[0:2]) * 100 + int(zt[3:5])
|
173
|
+
double_window = st <= ct <= et
|
174
|
+
|
175
|
+
# UK/EI stations:
|
176
|
+
if myprimary_pfx in ukei_pfx:
|
177
|
+
if hiscontinent == "EU":
|
178
|
+
if self.contact.get("Band", 0) in ["3.5", "7"]:
|
179
|
+
return 4 + (4 * double_window)
|
180
|
+
return 2 + (2 * double_window)
|
181
|
+
if self.contact.get("Band", 0) in ["3.5", "7"]:
|
182
|
+
return 8 + (8 * double_window)
|
183
|
+
return 4 + (4 * double_window)
|
184
|
+
|
185
|
+
# European stations:
|
186
|
+
if mycontinent == "EU":
|
187
|
+
if hisprimary_pfx in ukei_pfx:
|
188
|
+
if self.contact.get("Band", 0) in ["3.5", "7"]:
|
189
|
+
return 4
|
190
|
+
return 2
|
191
|
+
elif hiscontinent == "EU":
|
192
|
+
if self.contact.get("Band", 0) in ["3.5", "7"]:
|
193
|
+
return 2
|
194
|
+
return 1
|
195
|
+
if self.contact.get("Band", 0) in ["3.5", "7"]:
|
196
|
+
return 4
|
197
|
+
return 2
|
198
|
+
|
199
|
+
# DX (Outside Europe)
|
200
|
+
if mycontinent != "EU":
|
201
|
+
if hisprimary_pfx in ukei_pfx:
|
202
|
+
if self.contact.get("Band", "") in ["3.5", "7"]:
|
203
|
+
return 8
|
204
|
+
return 4
|
205
|
+
elif hiscontinent == "EU":
|
206
|
+
if self.contact.get("Band", "") in ["3.5", "7"]:
|
207
|
+
return 4
|
208
|
+
return 2
|
209
|
+
if self.contact.get("Band", "") in ["3.5", "7"]:
|
210
|
+
return 2
|
211
|
+
return 1
|
212
|
+
|
213
|
+
return 0
|
214
|
+
|
215
|
+
|
216
|
+
def show_mults(self):
|
217
|
+
"""Return display string for mults"""
|
218
|
+
|
219
|
+
query = f"SELECT COUNT(DISTINCT CountryPrefix) as dxcc_count FROM DXLOG WHERE CountryPrefix NOT IN ('EI', 'G', 'GD', 'GI', 'GJ', 'GM', 'GU', 'GW') and ContestNR = {self.pref.get('contest', '1')};"
|
220
|
+
result = self.database.exec_sql(query)
|
221
|
+
dxcc_count = result.get("dxcc_count", 0)
|
222
|
+
|
223
|
+
query = f"SELECT COUNT(DISTINCT SUBSTR(NR, LENGTH(NR) - 1)) as code_count FROM DXLOG WHERE ContestNR = {self.pref.get('contest', '1')} and typeof(NR) = 'text';"
|
224
|
+
result = self.database.exec_sql(query)
|
225
|
+
code_count = result.get("code_count", 0)
|
226
|
+
|
227
|
+
return dxcc_count + code_count
|
228
|
+
|
229
|
+
|
230
|
+
def show_qso(self):
|
231
|
+
"""Return qso count"""
|
232
|
+
result = self.database.fetch_qso_count()
|
233
|
+
if result:
|
234
|
+
return int(result.get("qsos", 0))
|
235
|
+
return 0
|
236
|
+
|
237
|
+
|
238
|
+
def calc_score(self):
|
239
|
+
"""Return calculated score"""
|
240
|
+
result = self.database.fetch_points()
|
241
|
+
if result is not None:
|
242
|
+
score = result.get("Points", "0")
|
243
|
+
if score is None:
|
244
|
+
score = "0"
|
245
|
+
contest_points = int(score)
|
246
|
+
mults = show_mults(self)
|
247
|
+
return contest_points * mults
|
248
|
+
return 0
|
249
|
+
|
250
|
+
|
251
|
+
def adif(self):
|
252
|
+
"""Call the generate ADIF function"""
|
253
|
+
gen_adif(self, cabrillo_name)
|
254
|
+
|
255
|
+
|
256
|
+
def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
|
257
|
+
""""""
|
258
|
+
print(
|
259
|
+
line_to_output.encode(file_encoding, errors="ignore").decode(),
|
260
|
+
end=ending,
|
261
|
+
file=file_descriptor,
|
262
|
+
)
|
263
|
+
|
264
|
+
|
265
|
+
def cabrillo(self, file_encoding):
|
266
|
+
"""Generates Cabrillo file. Maybe."""
|
267
|
+
# https://www.cqwpx.com/cabrillo.htm
|
268
|
+
logger.debug("******Cabrillo*****")
|
269
|
+
logger.debug("Station: %s", f"{self.station}")
|
270
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
271
|
+
now = datetime.datetime.now()
|
272
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
273
|
+
filename = (
|
274
|
+
str(Path.home())
|
275
|
+
+ "/"
|
276
|
+
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
|
277
|
+
)
|
278
|
+
logger.debug("%s", filename)
|
279
|
+
log = self.database.fetch_all_contacts_asc()
|
280
|
+
try:
|
281
|
+
with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
|
282
|
+
output_cabrillo_line(
|
283
|
+
"START-OF-LOG: 3.0",
|
284
|
+
"\r\n",
|
285
|
+
file_descriptor,
|
286
|
+
file_encoding,
|
287
|
+
)
|
288
|
+
output_cabrillo_line(
|
289
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
290
|
+
"\r\n",
|
291
|
+
file_descriptor,
|
292
|
+
file_encoding,
|
293
|
+
)
|
294
|
+
output_cabrillo_line(
|
295
|
+
f"CONTEST: {cabrillo_name}",
|
296
|
+
"\r\n",
|
297
|
+
file_descriptor,
|
298
|
+
file_encoding,
|
299
|
+
)
|
300
|
+
if self.station.get("Club", ""):
|
301
|
+
output_cabrillo_line(
|
302
|
+
f"CLUB: {self.station.get('Club', '').upper()}",
|
303
|
+
"\r\n",
|
304
|
+
file_descriptor,
|
305
|
+
file_encoding,
|
306
|
+
)
|
307
|
+
output_cabrillo_line(
|
308
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
309
|
+
"\r\n",
|
310
|
+
file_descriptor,
|
311
|
+
file_encoding,
|
312
|
+
)
|
313
|
+
output_cabrillo_line(
|
314
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
315
|
+
"\r\n",
|
316
|
+
file_descriptor,
|
317
|
+
file_encoding,
|
318
|
+
)
|
319
|
+
output_cabrillo_line(
|
320
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
321
|
+
"\r\n",
|
322
|
+
file_descriptor,
|
323
|
+
file_encoding,
|
324
|
+
)
|
325
|
+
output_cabrillo_line(
|
326
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
327
|
+
"\r\n",
|
328
|
+
file_descriptor,
|
329
|
+
file_encoding,
|
330
|
+
)
|
331
|
+
output_cabrillo_line(
|
332
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
333
|
+
"\r\n",
|
334
|
+
file_descriptor,
|
335
|
+
file_encoding,
|
336
|
+
)
|
337
|
+
mode = self.contest_settings.get("ModeCategory", "")
|
338
|
+
if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
|
339
|
+
mode = "MIXED"
|
340
|
+
output_cabrillo_line(
|
341
|
+
f"CATEGORY-MODE: {mode}",
|
342
|
+
"\r\n",
|
343
|
+
file_descriptor,
|
344
|
+
file_encoding,
|
345
|
+
)
|
346
|
+
output_cabrillo_line(
|
347
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
348
|
+
"\r\n",
|
349
|
+
file_descriptor,
|
350
|
+
file_encoding,
|
351
|
+
)
|
352
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
353
|
+
output_cabrillo_line(
|
354
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
355
|
+
"\r\n",
|
356
|
+
file_descriptor,
|
357
|
+
file_encoding,
|
358
|
+
)
|
359
|
+
output_cabrillo_line(
|
360
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
361
|
+
"\r\n",
|
362
|
+
file_descriptor,
|
363
|
+
file_encoding,
|
364
|
+
)
|
365
|
+
output_cabrillo_line(
|
366
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
367
|
+
"\r\n",
|
368
|
+
file_descriptor,
|
369
|
+
file_encoding,
|
370
|
+
)
|
371
|
+
|
372
|
+
output_cabrillo_line(
|
373
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
374
|
+
"\r\n",
|
375
|
+
file_descriptor,
|
376
|
+
file_encoding,
|
377
|
+
)
|
378
|
+
ops = f"@{self.station.get('Call','')}"
|
379
|
+
list_of_ops = self.database.get_ops()
|
380
|
+
for op in list_of_ops:
|
381
|
+
ops += f", {op.get('Operator', '')}"
|
382
|
+
output_cabrillo_line(
|
383
|
+
f"OPERATORS: {ops}",
|
384
|
+
"\r\n",
|
385
|
+
file_descriptor,
|
386
|
+
file_encoding,
|
387
|
+
)
|
388
|
+
output_cabrillo_line(
|
389
|
+
f"NAME: {self.station.get('Name', '')}",
|
390
|
+
"\r\n",
|
391
|
+
file_descriptor,
|
392
|
+
file_encoding,
|
393
|
+
)
|
394
|
+
output_cabrillo_line(
|
395
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
396
|
+
"\r\n",
|
397
|
+
file_descriptor,
|
398
|
+
file_encoding,
|
399
|
+
)
|
400
|
+
output_cabrillo_line(
|
401
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
402
|
+
"\r\n",
|
403
|
+
file_descriptor,
|
404
|
+
file_encoding,
|
405
|
+
)
|
406
|
+
output_cabrillo_line(
|
407
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
408
|
+
"\r\n",
|
409
|
+
file_descriptor,
|
410
|
+
file_encoding,
|
411
|
+
)
|
412
|
+
output_cabrillo_line(
|
413
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
414
|
+
"\r\n",
|
415
|
+
file_descriptor,
|
416
|
+
file_encoding,
|
417
|
+
)
|
418
|
+
output_cabrillo_line(
|
419
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
420
|
+
"\r\n",
|
421
|
+
file_descriptor,
|
422
|
+
file_encoding,
|
423
|
+
)
|
424
|
+
output_cabrillo_line(
|
425
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
426
|
+
"\r\n",
|
427
|
+
file_descriptor,
|
428
|
+
file_encoding,
|
429
|
+
)
|
430
|
+
for contact in log:
|
431
|
+
the_date_and_time = contact.get("TS", "")
|
432
|
+
themode = contact.get("Mode", "")
|
433
|
+
if themode == "LSB" or themode == "USB":
|
434
|
+
themode = "PH"
|
435
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
436
|
+
|
437
|
+
loggeddate = the_date_and_time[:10]
|
438
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
439
|
+
sentnr = str(contact.get("SentNr", "")).upper().split()
|
440
|
+
if len(sentnr) == 2:
|
441
|
+
sentnr = sentnr[0].zfill(3) + " " + sentnr[1]
|
442
|
+
else:
|
443
|
+
sentnr = sentnr[0].zfill(3) + " --"
|
444
|
+
|
445
|
+
nr = str(contact.get("NR", "")).upper().split()
|
446
|
+
if len(nr) == 2:
|
447
|
+
nr = nr[0].zfill(3) + " " + nr[1]
|
448
|
+
else:
|
449
|
+
if nr[0][-2:].isalpha():
|
450
|
+
nr = nr[0][:-2].zfill(3) + " " + nr[0][-2:]
|
451
|
+
else:
|
452
|
+
nr = nr[0].zfill(3) + " --"
|
453
|
+
|
454
|
+
output_cabrillo_line(
|
455
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
456
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
457
|
+
f"{str(contact.get('SNT', '')).ljust(3)} "
|
458
|
+
f"{sentnr} "
|
459
|
+
f"{contact.get('Call', '').ljust(13)} "
|
460
|
+
f"{str(contact.get('RCV', '')).ljust(3)} "
|
461
|
+
f"{nr}",
|
462
|
+
"\r\n",
|
463
|
+
file_descriptor,
|
464
|
+
file_encoding,
|
465
|
+
)
|
466
|
+
output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
|
467
|
+
self.show_message_box(f"Cabrillo saved to: {filename}")
|
468
|
+
except IOError as exception:
|
469
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
470
|
+
self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
|
471
|
+
return
|
472
|
+
|
473
|
+
|
474
|
+
def recalculate_mults(self):
|
475
|
+
"""Recalculates multipliers after change in logged qso."""
|
476
|
+
|
477
|
+
|
478
|
+
def process_esm(self, new_focused_widget=None, with_enter=False):
|
479
|
+
"""ESM State Machine"""
|
480
|
+
|
481
|
+
# self.pref["run_state"]
|
482
|
+
|
483
|
+
# -----===== Assigned F-Keys =====-----
|
484
|
+
# self.esm_dict["CQ"]
|
485
|
+
# self.esm_dict["EXCH"]
|
486
|
+
# self.esm_dict["QRZ"]
|
487
|
+
# self.esm_dict["AGN"]
|
488
|
+
# self.esm_dict["HISCALL"]
|
489
|
+
# self.esm_dict["MYCALL"]
|
490
|
+
# self.esm_dict["QSOB4"]
|
491
|
+
|
492
|
+
# ----==== text fields ====----
|
493
|
+
# self.callsign
|
494
|
+
# self.sent
|
495
|
+
# self.receive
|
496
|
+
# self.other_1
|
497
|
+
# self.other_2
|
498
|
+
|
499
|
+
if new_focused_widget is not None:
|
500
|
+
self.current_widget = self.inputs_dict.get(new_focused_widget)
|
501
|
+
|
502
|
+
# print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
|
503
|
+
|
504
|
+
for a_button in [
|
505
|
+
self.esm_dict["CQ"],
|
506
|
+
self.esm_dict["EXCH"],
|
507
|
+
self.esm_dict["QRZ"],
|
508
|
+
self.esm_dict["AGN"],
|
509
|
+
self.esm_dict["HISCALL"],
|
510
|
+
self.esm_dict["MYCALL"],
|
511
|
+
self.esm_dict["QSOB4"],
|
512
|
+
]:
|
513
|
+
if a_button is not None:
|
514
|
+
self.restore_button_color(a_button)
|
515
|
+
|
516
|
+
buttons_to_send = []
|
517
|
+
|
518
|
+
if self.pref.get("run_state"):
|
519
|
+
if self.current_widget == "callsign":
|
520
|
+
if len(self.callsign.text()) < 3:
|
521
|
+
self.make_button_green(self.esm_dict["CQ"])
|
522
|
+
buttons_to_send.append(self.esm_dict["CQ"])
|
523
|
+
elif len(self.callsign.text()) > 2:
|
524
|
+
self.make_button_green(self.esm_dict["HISCALL"])
|
525
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
526
|
+
buttons_to_send.append(self.esm_dict["HISCALL"])
|
527
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
528
|
+
|
529
|
+
elif self.current_widget in ["other_2"]:
|
530
|
+
if self.other_2.text() == "":
|
531
|
+
self.make_button_green(self.esm_dict["AGN"])
|
532
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
533
|
+
else:
|
534
|
+
self.make_button_green(self.esm_dict["QRZ"])
|
535
|
+
buttons_to_send.append(self.esm_dict["QRZ"])
|
536
|
+
buttons_to_send.append("LOGIT")
|
537
|
+
|
538
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
539
|
+
for button in buttons_to_send:
|
540
|
+
if button:
|
541
|
+
if button == "LOGIT":
|
542
|
+
self.save_contact()
|
543
|
+
continue
|
544
|
+
self.process_function_key(button)
|
545
|
+
else:
|
546
|
+
if self.current_widget == "callsign":
|
547
|
+
if len(self.callsign.text()) > 2:
|
548
|
+
self.make_button_green(self.esm_dict["MYCALL"])
|
549
|
+
buttons_to_send.append(self.esm_dict["MYCALL"])
|
550
|
+
|
551
|
+
elif self.current_widget in ["other_2"]:
|
552
|
+
if self.other_2.text() == "":
|
553
|
+
self.make_button_green(self.esm_dict["AGN"])
|
554
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
555
|
+
else:
|
556
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
557
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
558
|
+
buttons_to_send.append("LOGIT")
|
559
|
+
|
560
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
561
|
+
for button in buttons_to_send:
|
562
|
+
if button:
|
563
|
+
if button == "LOGIT":
|
564
|
+
self.save_contact()
|
565
|
+
continue
|
566
|
+
self.process_function_key(button)
|
567
|
+
|
568
|
+
|
569
|
+
def get_mults(self):
|
570
|
+
""""""
|
571
|
+
|
572
|
+
mults = {}
|
573
|
+
return mults
|
574
|
+
|
575
|
+
|
576
|
+
def just_points(self):
|
577
|
+
""""""
|
578
|
+
return get_points(self)
|
579
|
+
|
580
|
+
|
581
|
+
def populate_history_info_line(self):
|
582
|
+
result = self.database.fetch_call_history(self.callsign.text())
|
583
|
+
if result:
|
584
|
+
self.history_info.setText(
|
585
|
+
f"{result.get('Call', '')}, {result.get('Exch1', '')}, {result.get('UserText','...')}"
|
586
|
+
)
|
587
|
+
else:
|
588
|
+
self.history_info.setText("")
|
589
|
+
|
590
|
+
|
591
|
+
def check_call_history(self):
|
592
|
+
""""""
|
593
|
+
result = self.database.fetch_call_history(self.callsign.text())
|
594
|
+
if result:
|
595
|
+
self.history_info.setText(f"{result.get('UserText','')}")
|
596
|
+
if self.other_2.text() == "":
|
597
|
+
self.other_2.setText(f"{result.get('Exch1', '')}")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.4.
|
3
|
+
Version: 25.4.10
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
License: GPL-3.0-or-later
|
@@ -141,6 +141,7 @@ Dynamic: license-file
|
|
141
141
|
- [The exchange](#the-exchange)
|
142
142
|
- [RAEM](#raem)
|
143
143
|
- [RandomGram](#randomgram)
|
144
|
+
- [UKEI DX](#ukei-dx)
|
144
145
|
|
145
146
|
## What and Why is Not1MM
|
146
147
|
|
@@ -243,11 +244,14 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
243
244
|
- REF CW, SSB
|
244
245
|
- SPDX
|
245
246
|
- Stew Perry Topband
|
247
|
+
- UK/EI DX
|
246
248
|
- Weekly RTTY
|
247
249
|
- Winter Field Day
|
248
250
|
|
249
251
|
## Recent Changes
|
250
252
|
|
253
|
+
- [25-4-10] Add Auto CQ visual indicator.
|
254
|
+
- [25-4-9] Added UKEI DX
|
251
255
|
- [25-4-8] Remove focus from statistics table widget.
|
252
256
|
- [25-4-7] Merge in changes from dj1yfk correcting SPDX Cabrillo name.
|
253
257
|
- [25-4-5] Add SPDX.
|
@@ -661,9 +665,13 @@ pressing F1 - F12. See next section on Editing macro keys.
|
|
661
665
|
### Auto CQ
|
662
666
|
|
663
667
|
If you press `SHIFT-F1` The Auto CQ mode will be activated and the F1 macro will be resent
|
664
|
-
after each Auto CQ Delay interval has passed.
|
665
|
-
|
666
|
-
|
668
|
+
after each Auto CQ Delay interval has passed. An indicator will appear to the upper left of
|
669
|
+
the F1 macro key as a visual reminder that your Auto CQ is active.
|
670
|
+
|
671
|
+

|
672
|
+
|
673
|
+
The delay can be changed by going to the `Options` TAB in the Configuration dialog. If you are in
|
674
|
+
S&P mode when you enable Auto CQ, you will be automatically switched into RUN mode.
|
667
675
|
|
668
676
|
The auto CQ can be cancelled by either typing in the call sign field, or by pressing ESC.
|
669
677
|
|
@@ -1034,3 +1042,8 @@ for me 33N117W. And in the exchange macro put `# {EXCH}`.
|
|
1034
1042
|
### RandomGram
|
1035
1043
|
|
1036
1044
|
This plugin was submitted by @alduhoo. It reads a rg.txt file if it exists in the user's home directory to populate the next group in the sent exchange field.
|
1045
|
+
|
1046
|
+
### UKEI DX
|
1047
|
+
|
1048
|
+
For the Run exchange macro I'd put '{SNT} # {EXCH}'
|
1049
|
+
|
@@ -1,5 +1,5 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=xtWIC2PsCIHlaeUYS7kFwUhCBAP4rZ2ib0k0ILA8pPs,152411
|
3
3
|
not1mm/bandmap.py,sha256=-zu5slsuAm2GmeW8g3yvURzsuQxemwIQfw1HEq8xKHM,29920
|
4
4
|
not1mm/checkwindow.py,sha256=zEHlw40j6Wr3rvKbCQf2lcezCoiZqaBqEvBjQU5aKW0,7630
|
5
5
|
not1mm/fsutils.py,sha256=ukHKxKTeNKxKwqRaJjtzRShL4X5Xl0jRBbADyy3Ifp8,1701
|
@@ -26,7 +26,7 @@ not1mm/data/cwmacros.txt,sha256=NztufsX6R52gAO7VyJ2AHr7wOh41pJTwHKh5Lcs32ds,468
|
|
26
26
|
not1mm/data/donors.html,sha256=0NEh7eu9Dsfv1Gy0_f6UMp4ZjVjm7OgoQJEQd-4whoU,267
|
27
27
|
not1mm/data/editcontact.ui,sha256=TNOsXETYfDaON4wj6AkzCJ-n2SmbNRO2-g2SLl5m8s0,27437
|
28
28
|
not1mm/data/editmacro.ui,sha256=Vg-S62ogKYcWlDDlza_JYyZkCQfa8mCfF-cFqpBej-w,2700
|
29
|
-
not1mm/data/greendot.png,sha256=
|
29
|
+
not1mm/data/greendot.png,sha256=El9TomJcGtViRcHOR7kMxGzjzvYs0TSAqOb3tZv0JDA,368
|
30
30
|
not1mm/data/k6gte-not1mm.desktop,sha256=dUi-YbHbavOsL3A29eglDQ0p1_cSKzJeEGQ52Qv_eKo,243
|
31
31
|
not1mm/data/k6gte.not1mm-128.png,sha256=ZP93MfRqr4WwsFCwg1m5MZjLs8bG895vDW9DDDn1B_Q,6076
|
32
32
|
not1mm/data/k6gte.not1mm-32.png,sha256=XdTsCa3xqwTfn26Ga7RwO_Vlbg_77RKkSc8bMxVcCac,1526
|
@@ -34,7 +34,7 @@ not1mm/data/k6gte.not1mm-64.png,sha256=6ku45Gq1g5ezh04F07osoKRtanb3e4kbx5XdIEh3N
|
|
34
34
|
not1mm/data/logwindow.ui,sha256=f7vULj96tHIQuR1nJMyvPHHcmVgzkhv9D1isyojsnFU,1458
|
35
35
|
not1mm/data/logwindowx.ui,sha256=CwpI-h7cI1yqyldH9quKftsdHL5lTyL9ABOcf80nfqc,1632
|
36
36
|
not1mm/data/main.ui,sha256=DNJ7jK_1Dd9SDiiGbdwvXDA0WEKjApdRKqBPYFt7S3c,63737
|
37
|
-
not1mm/data/new_contest.ui,sha256
|
37
|
+
not1mm/data/new_contest.ui,sha256=-EMhmysI9hq3HbMv-SH8bJGzsiW0wOhmRE2iOjqxFQ0,24806
|
38
38
|
not1mm/data/not1mm.html,sha256=c9-mfjMwDt4f5pySUruz2gREW33CQ2_rCddM2z5CZQo,23273
|
39
39
|
not1mm/data/opon.ui,sha256=QDicqAk2lORG2UWsHa6jHlsGn6uzrrI2R4HSAocpPes,2258
|
40
40
|
not1mm/data/pickcontest.ui,sha256=4hPBszCglObThx_eIWtmK9CEcbr7WBjbB1rKZdI-o3I,1707
|
@@ -118,7 +118,7 @@ not1mm/lib/plugin_common.py,sha256=D1OBjyLmX7zuSPqgTCmHwXzAKA12J_zTQItvyIem-4Y,1
|
|
118
118
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
119
119
|
not1mm/lib/settings.py,sha256=mXffn8Xaj5KATPQinNBR0V5DbHWQPsRfh24_axWGYuk,15254
|
120
120
|
not1mm/lib/super_check_partial.py,sha256=hwT2NRwobu0PLDyw6ltmbmcAtGBD02CKGFbgGWjXMqA,2334
|
121
|
-
not1mm/lib/version.py,sha256=
|
121
|
+
not1mm/lib/version.py,sha256=esZgsPgAQkPjdl-aToDOFAAErps2s6CWufrJYpsuWtU,49
|
122
122
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
123
123
|
not1mm/plugins/10_10_fall_cw.py,sha256=oJh3JKqjOpnWElSlZpiQ631UnaOd8qra5s9bl_QoInk,14783
|
124
124
|
not1mm/plugins/10_10_spring_cw.py,sha256=p7dSDtbFK0e6Xouw2V6swYn3VFVgHKyx4IfRWyBjMZY,14786
|
@@ -172,11 +172,12 @@ not1mm/plugins/ref_cw.py,sha256=SY-U-DSyhkTFrsQ6ZLYAt0jTWKa8z05rIZiQ8sTQC-U,2138
|
|
172
172
|
not1mm/plugins/ref_ssb.py,sha256=cUFUtbe7-5rwZZHEzpPnaIAnwrwayqBvtgctxQDF5Gw,21592
|
173
173
|
not1mm/plugins/spdx.py,sha256=O_PhTaWdjaV29hj2G8tUK3m6GNx8f40hO1JAF-olLMg,15909
|
174
174
|
not1mm/plugins/stew_perry_topband.py,sha256=3U-Dr28haBTqTaZWLiC1qHQBmLsLENDL-ihyddPpJbg,15403
|
175
|
+
not1mm/plugins/ukeidx.py,sha256=0ABGW7_9Ui0Rgr8mkPBxOJokAIerM1a4-HWnl6VsnV8,19105
|
175
176
|
not1mm/plugins/weekly_rtty.py,sha256=C8Xs3Q5UgSYx-mFFar8BVARWtmqlyrbeC98Ubzb4UN8,20128
|
176
177
|
not1mm/plugins/winter_field_day.py,sha256=hmAMgkdqIXtnCNyUp8J9Bb8liN8wj10wps6ROuG-Bok,15284
|
177
|
-
not1mm-25.4.
|
178
|
-
not1mm-25.4.
|
179
|
-
not1mm-25.4.
|
180
|
-
not1mm-25.4.
|
181
|
-
not1mm-25.4.
|
182
|
-
not1mm-25.4.
|
178
|
+
not1mm-25.4.10.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
179
|
+
not1mm-25.4.10.dist-info/METADATA,sha256=gCw9oRSa0QBMwrcqprwbz_63W6BPjHHQSO6ovRsj_uI,37832
|
180
|
+
not1mm-25.4.10.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
181
|
+
not1mm-25.4.10.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
182
|
+
not1mm-25.4.10.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
183
|
+
not1mm-25.4.10.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|