not1mm 25.4.12__py3-none-any.whl → 25.4.14__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 +7 -1
- not1mm/data/donors.html +1 -0
- not1mm/data/new_contest.ui +5 -0
- not1mm/lib/database.py +60 -0
- not1mm/lib/version.py +1 -1
- not1mm/plugins/es_ll_kv.py +568 -0
- not1mm/plugins/jidx_cw.py +14 -3
- not1mm/plugins/jidx_ph.py +14 -3
- {not1mm-25.4.12.dist-info → not1mm-25.4.14.dist-info}/METADATA +40 -15
- {not1mm-25.4.12.dist-info → not1mm-25.4.14.dist-info}/RECORD +14 -13
- {not1mm-25.4.12.dist-info → not1mm-25.4.14.dist-info}/WHEEL +0 -0
- {not1mm-25.4.12.dist-info → not1mm-25.4.14.dist-info}/entry_points.txt +0 -0
- {not1mm-25.4.12.dist-info → not1mm-25.4.14.dist-info}/licenses/LICENSE +0 -0
- {not1mm-25.4.12.dist-info → not1mm-25.4.14.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -3705,6 +3705,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
3705
3705
|
result = self.database.check_dupe_on_band_mode(call, band, mode)
|
3706
3706
|
if self.contest.dupe_type == 4:
|
3707
3707
|
result = {"isdupe": False}
|
3708
|
+
if self.contest.dupe_type == 5:
|
3709
|
+
result = {"isdupe": False} # in case contest has no function.
|
3710
|
+
if hasattr(self.contest, "check_dupe"):
|
3711
|
+
result = self.contest.specific_contest_check_dupe(self, call)
|
3712
|
+
|
3708
3713
|
debugline = f"{result}"
|
3709
3714
|
logger.debug("%s", debugline)
|
3710
3715
|
self.contact_is_dupe = result.get("isdupe", False)
|
@@ -4095,7 +4100,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
4095
4100
|
"""
|
4096
4101
|
|
4097
4102
|
logger.debug("******EDI*****")
|
4098
|
-
self.contest
|
4103
|
+
if hasattr(self.contest, "edi"):
|
4104
|
+
self.contest.edi(self)
|
4099
4105
|
|
4100
4106
|
def generate_cabrillo(self, file_encoding: str) -> None:
|
4101
4107
|
"""
|
not1mm/data/donors.html
CHANGED
not1mm/data/new_contest.ui
CHANGED
not1mm/lib/database.py
CHANGED
@@ -1217,3 +1217,63 @@ class DataBase:
|
|
1217
1217
|
except sqlite3.OperationalError as exception:
|
1218
1218
|
logger.debug("%s", exception)
|
1219
1219
|
return ()
|
1220
|
+
|
1221
|
+
def check_dupe_on_period_1_mode(
|
1222
|
+
self, call, band, mode, contest_start_time, contest_time_period_1
|
1223
|
+
) -> dict:
|
1224
|
+
"""Checks if a call is dupe on band/mode"""
|
1225
|
+
try:
|
1226
|
+
with sqlite3.connect(self.database) as conn:
|
1227
|
+
conn.row_factory = self.row_factory
|
1228
|
+
cursor = conn.cursor()
|
1229
|
+
cursor.execute(
|
1230
|
+
f"select count(*) as isdupe from dxlog where Call = '{call}' and Mode = '{mode}' and Band = '{band}' and ContestNR = {self.current_contest} AND TS >= '{contest_start_time}' AND TS <= '{contest_time_period_1}';"
|
1231
|
+
)
|
1232
|
+
return cursor.fetchone()
|
1233
|
+
except sqlite3.OperationalError as exception:
|
1234
|
+
logger.debug("%s", exception)
|
1235
|
+
return {}
|
1236
|
+
|
1237
|
+
def check_dupe_on_period_2_mode(
|
1238
|
+
self,
|
1239
|
+
call,
|
1240
|
+
band,
|
1241
|
+
mode,
|
1242
|
+
contest_start_time,
|
1243
|
+
contest_time_period_1,
|
1244
|
+
contest_time_period_2,
|
1245
|
+
) -> dict:
|
1246
|
+
"""Checks if a call is dupe on band/mode"""
|
1247
|
+
try:
|
1248
|
+
with sqlite3.connect(self.database) as conn:
|
1249
|
+
conn.row_factory = self.row_factory
|
1250
|
+
cursor = conn.cursor()
|
1251
|
+
cursor.execute(
|
1252
|
+
f"select count(*) as isdupe from dxlog where Call = '{call}' and Mode = '{mode}' and Band = '{band}' and ContestNR = {self.current_contest} AND TS >= '{contest_time_period_1}' AND TS <= '{contest_time_period_2}';"
|
1253
|
+
)
|
1254
|
+
return cursor.fetchone()
|
1255
|
+
except sqlite3.OperationalError as exception:
|
1256
|
+
logger.debug("%s", exception)
|
1257
|
+
return {}
|
1258
|
+
|
1259
|
+
def check_dupe_on_period_3_mode(
|
1260
|
+
self,
|
1261
|
+
call,
|
1262
|
+
band,
|
1263
|
+
mode,
|
1264
|
+
contest_start_time,
|
1265
|
+
contest_time_period_2,
|
1266
|
+
contest_time_period_3,
|
1267
|
+
) -> dict:
|
1268
|
+
"""Checks if a call is dupe on band/mode"""
|
1269
|
+
try:
|
1270
|
+
with sqlite3.connect(self.database) as conn:
|
1271
|
+
conn.row_factory = self.row_factory
|
1272
|
+
cursor = conn.cursor()
|
1273
|
+
cursor.execute(
|
1274
|
+
f"select count(*) as isdupe from dxlog where Call = '{call}' and Mode = '{mode}' and Band = '{band}' and ContestNR = {self.current_contest} AND TS >= '{contest_time_period_2}' AND TS <= '{contest_time_period_3}';"
|
1275
|
+
)
|
1276
|
+
return cursor.fetchone()
|
1277
|
+
except sqlite3.OperationalError as exception:
|
1278
|
+
logger.debug("%s", exception)
|
1279
|
+
return {}
|
not1mm/lib/version.py
CHANGED
@@ -0,0 +1,568 @@
|
|
1
|
+
""" """
|
2
|
+
|
3
|
+
import datetime
|
4
|
+
import logging
|
5
|
+
import platform
|
6
|
+
|
7
|
+
from pathlib import Path
|
8
|
+
|
9
|
+
from PyQt6 import QtWidgets
|
10
|
+
|
11
|
+
from not1mm.lib.plugin_common import gen_adif, get_points
|
12
|
+
|
13
|
+
from not1mm.lib.ham_utility import calculate_wpx_prefix
|
14
|
+
from not1mm.lib.version import __version__
|
15
|
+
|
16
|
+
logger = logging.getLogger(__name__)
|
17
|
+
|
18
|
+
EXCHANGE_HINT = "#"
|
19
|
+
|
20
|
+
name = "ES OPEN"
|
21
|
+
cabrillo_name = "ES-OPEN"
|
22
|
+
mode = "BOTH" # CW SSB BOTH RTTY
|
23
|
+
|
24
|
+
columns = [
|
25
|
+
"YYYY-MM-DD HH:MM:SS",
|
26
|
+
"Call",
|
27
|
+
"Freq",
|
28
|
+
"Mode",
|
29
|
+
"Snt",
|
30
|
+
"Rcv",
|
31
|
+
"SentNr",
|
32
|
+
"RcvNr",
|
33
|
+
"PTS",
|
34
|
+
]
|
35
|
+
|
36
|
+
advance_on_space = [True, True, True, True, True]
|
37
|
+
|
38
|
+
# 5 Contest specific dupe check.
|
39
|
+
dupe_type = 5
|
40
|
+
|
41
|
+
|
42
|
+
def specific_contest_check_dupe(self, call):
|
43
|
+
""""""
|
44
|
+
|
45
|
+
# constant to split the contest
|
46
|
+
contest_length_in_minutes = 60
|
47
|
+
split_contest_by_minutes = 20
|
48
|
+
|
49
|
+
period_count = int(contest_length_in_minutes / split_contest_by_minutes)
|
50
|
+
|
51
|
+
# think about generic solution by splitting the contest to n different periods
|
52
|
+
start_date_init = self.contest_settings.get("StartDate", "")
|
53
|
+
self.contest_start_date = start_date_init.split(" ")[0]
|
54
|
+
self.contest_start_time = start_date_init.split(" ")[1]
|
55
|
+
|
56
|
+
start_date_init_date = datetime.strptime(start_date_init, "%Y-%m-%d %H:%M:%S")
|
57
|
+
|
58
|
+
# Create time periods dynamically based on period count
|
59
|
+
time_periods = []
|
60
|
+
for i in range(period_count):
|
61
|
+
minutes_to_add = split_contest_by_minutes * (i + 1)
|
62
|
+
time_period = start_date_init_date + datetime.timedelta(minutes=minutes_to_add)
|
63
|
+
time_periods.append(time_period)
|
64
|
+
|
65
|
+
# Assign to variables for backwards compatibility
|
66
|
+
time_period_1 = time_periods[0] if len(time_periods) > 0 else None
|
67
|
+
time_period_2 = time_periods[1] if len(time_periods) > 1 else None
|
68
|
+
time_period_3 = time_periods[2] if len(time_periods) > 2 else None
|
69
|
+
|
70
|
+
# get current time in UTC
|
71
|
+
iso_current_time = datetime.now(datetime.timezone.utc)
|
72
|
+
current_time = iso_current_time.replace(tzinfo=None)
|
73
|
+
|
74
|
+
if current_time < time_period_1:
|
75
|
+
start_date_init = self.contest_start_date + " " + self.contest_start_time
|
76
|
+
|
77
|
+
result = self.database.check_dupe_on_period_1_mode(
|
78
|
+
call,
|
79
|
+
self.contact.get("Band", ""),
|
80
|
+
mode,
|
81
|
+
start_date_init,
|
82
|
+
time_period_1.strftime("%Y-%m-%d %H:%M:%S"),
|
83
|
+
)
|
84
|
+
|
85
|
+
if current_time < time_period_2 and current_time >= time_period_1:
|
86
|
+
start_date_init = self.contest_start_date + " " + self.contest_start_time
|
87
|
+
|
88
|
+
result = self.database.check_dupe_on_period_2_mode(
|
89
|
+
call,
|
90
|
+
self.contact.get("Band", ""),
|
91
|
+
mode,
|
92
|
+
start_date_init,
|
93
|
+
time_period_1.strftime("%Y-%m-%d %H:%M:%S"),
|
94
|
+
time_period_2.strftime("%Y-%m-%d %H:%M:%S"),
|
95
|
+
)
|
96
|
+
|
97
|
+
if current_time < time_period_3 and current_time >= time_period_2:
|
98
|
+
start_date_init = self.contest_start_date + " " + self.contest_start_time
|
99
|
+
|
100
|
+
result = self.database.check_dupe_on_period_3_mode(
|
101
|
+
call,
|
102
|
+
self.contact.get("Band", ""),
|
103
|
+
mode,
|
104
|
+
start_date_init,
|
105
|
+
time_period_2.strftime("%Y-%m-%d %H:%M:%S"),
|
106
|
+
time_period_3.strftime("%Y-%m-%d %H:%M:%S"),
|
107
|
+
)
|
108
|
+
else:
|
109
|
+
result = self.database.check_dupe_on_period_mode(
|
110
|
+
call, self.contact.get("Band", ""), mode, start_date_init
|
111
|
+
)
|
112
|
+
return result
|
113
|
+
|
114
|
+
|
115
|
+
def init_contest(self):
|
116
|
+
"""setup plugin"""
|
117
|
+
set_tab_next(self)
|
118
|
+
set_tab_prev(self)
|
119
|
+
interface(self)
|
120
|
+
self.next_field = self.other_2
|
121
|
+
|
122
|
+
|
123
|
+
def interface(self):
|
124
|
+
"""Setup user interface"""
|
125
|
+
self.field1.show()
|
126
|
+
self.field2.show()
|
127
|
+
self.field3.show()
|
128
|
+
self.field4.show()
|
129
|
+
self.other_label.setText("Sent")
|
130
|
+
self.field3.setAccessibleName("Sent")
|
131
|
+
self.exch_label.setText("SN")
|
132
|
+
self.field4.setAccessibleName("SN")
|
133
|
+
|
134
|
+
|
135
|
+
def reset_label(self):
|
136
|
+
"""reset label after field cleared"""
|
137
|
+
|
138
|
+
|
139
|
+
def set_tab_next(self):
|
140
|
+
"""Set TAB Advances"""
|
141
|
+
self.tab_next = {
|
142
|
+
self.callsign: self.other_1,
|
143
|
+
self.sent: self.other_1,
|
144
|
+
self.receive: self.other_1,
|
145
|
+
self.other_1: self.other_2,
|
146
|
+
self.other_2: self.callsign,
|
147
|
+
}
|
148
|
+
|
149
|
+
|
150
|
+
def set_tab_prev(self):
|
151
|
+
"""Set TAB Advances"""
|
152
|
+
self.tab_prev = {
|
153
|
+
self.callsign: self.other_2,
|
154
|
+
self.sent: self.callsign,
|
155
|
+
self.receive: self.callsign,
|
156
|
+
self.other_1: self.callsign,
|
157
|
+
self.other_2: self.other_1,
|
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
|
+
|
172
|
+
def predupe(self):
|
173
|
+
"""called after callsign entered"""
|
174
|
+
|
175
|
+
|
176
|
+
def prefill(self):
|
177
|
+
"""Fill SentNR"""
|
178
|
+
sent_sxchange_setting = self.contest_settings.get("SentExchange", "")
|
179
|
+
if sent_sxchange_setting.strip() == "#":
|
180
|
+
result = self.database.get_serial()
|
181
|
+
serial_nr = str(result.get("serial_nr", "1")).zfill(3)
|
182
|
+
if serial_nr == "None":
|
183
|
+
serial_nr = "001"
|
184
|
+
if len(self.other_1.text()) == 0:
|
185
|
+
self.other_1.setText(serial_nr)
|
186
|
+
else:
|
187
|
+
self.other_1.setText(sent_sxchange_setting)
|
188
|
+
|
189
|
+
|
190
|
+
def points(self):
|
191
|
+
""" """
|
192
|
+
if self.contact_is_dupe > 0:
|
193
|
+
return 0
|
194
|
+
|
195
|
+
_mode = self.contact.get("Mode", "")
|
196
|
+
if _mode in "SSB, USB, LSB, FM, AM":
|
197
|
+
return 1
|
198
|
+
if _mode in "CW":
|
199
|
+
return 2
|
200
|
+
|
201
|
+
return 0
|
202
|
+
|
203
|
+
|
204
|
+
def show_mults(self, rtc=None):
|
205
|
+
"""Return display string for mults"""
|
206
|
+
our_prefix = calculate_wpx_prefix(self.station.get("Call", ""))
|
207
|
+
query = f"SELECT count(DISTINCT(substr(WPXPrefix,3,1) || ':' || Band || ':' || Mode)) as mults from DXLOG where ContestNR = {self.pref.get('contest', '1')} AND CountryPrefix = 'ES' AND WPXPrefix != '{our_prefix}';"
|
208
|
+
result = self.database.exec_sql(query)
|
209
|
+
if result:
|
210
|
+
mult_count = result.get("mults", 0)
|
211
|
+
return mult_count
|
212
|
+
return 0
|
213
|
+
|
214
|
+
|
215
|
+
def show_qso(self):
|
216
|
+
"""Return qso count"""
|
217
|
+
result = self.database.fetch_qso_count()
|
218
|
+
if result:
|
219
|
+
return int(result.get("qsos", 0))
|
220
|
+
return 0
|
221
|
+
|
222
|
+
|
223
|
+
def calc_score(self):
|
224
|
+
"""Return calculated score"""
|
225
|
+
result = self.database.fetch_points()
|
226
|
+
if result is not None:
|
227
|
+
score = result.get("Points", "0")
|
228
|
+
if score is None:
|
229
|
+
score = "0"
|
230
|
+
contest_points = int(score)
|
231
|
+
mults = show_mults(self)
|
232
|
+
return contest_points * (mults + 1)
|
233
|
+
return 0
|
234
|
+
|
235
|
+
|
236
|
+
def recalculate_mults(self):
|
237
|
+
"""Recalculates multipliers after change in logged qso."""
|
238
|
+
|
239
|
+
|
240
|
+
def adif(self):
|
241
|
+
"""Call the generate ADIF function"""
|
242
|
+
gen_adif(self, cabrillo_name, "ES OPEN")
|
243
|
+
|
244
|
+
|
245
|
+
def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
|
246
|
+
""""""
|
247
|
+
print(
|
248
|
+
line_to_output.encode(file_encoding, errors="ignore").decode(),
|
249
|
+
end=ending,
|
250
|
+
file=file_descriptor,
|
251
|
+
)
|
252
|
+
|
253
|
+
|
254
|
+
def cabrillo(self, file_encoding):
|
255
|
+
"""Generates Cabrillo file. Maybe."""
|
256
|
+
# https://www.cqwpx.com/cabrillo.htm
|
257
|
+
logger.debug("******Cabrillo*****")
|
258
|
+
logger.debug("Station: %s", f"{self.station}")
|
259
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
260
|
+
now = datetime.datetime.now()
|
261
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
262
|
+
filename = (
|
263
|
+
str(Path.home())
|
264
|
+
+ "/"
|
265
|
+
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
|
266
|
+
)
|
267
|
+
logger.debug("%s", filename)
|
268
|
+
log = self.database.fetch_all_contacts_asc()
|
269
|
+
try:
|
270
|
+
with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
|
271
|
+
output_cabrillo_line(
|
272
|
+
"START-OF-LOG: 3.0",
|
273
|
+
"\r\n",
|
274
|
+
file_descriptor,
|
275
|
+
file_encoding,
|
276
|
+
)
|
277
|
+
output_cabrillo_line(
|
278
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
279
|
+
"\r\n",
|
280
|
+
file_descriptor,
|
281
|
+
file_encoding,
|
282
|
+
)
|
283
|
+
output_cabrillo_line(
|
284
|
+
f"CONTEST: {cabrillo_name}",
|
285
|
+
"\r\n",
|
286
|
+
file_descriptor,
|
287
|
+
file_encoding,
|
288
|
+
)
|
289
|
+
if self.station.get("Club", ""):
|
290
|
+
output_cabrillo_line(
|
291
|
+
f"CLUB: {self.station.get('Club', '').upper()}",
|
292
|
+
"\r\n",
|
293
|
+
file_descriptor,
|
294
|
+
file_encoding,
|
295
|
+
)
|
296
|
+
output_cabrillo_line(
|
297
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
298
|
+
"\r\n",
|
299
|
+
file_descriptor,
|
300
|
+
file_encoding,
|
301
|
+
)
|
302
|
+
output_cabrillo_line(
|
303
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
304
|
+
"\r\n",
|
305
|
+
file_descriptor,
|
306
|
+
file_encoding,
|
307
|
+
)
|
308
|
+
output_cabrillo_line(
|
309
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
310
|
+
"\r\n",
|
311
|
+
file_descriptor,
|
312
|
+
file_encoding,
|
313
|
+
)
|
314
|
+
output_cabrillo_line(
|
315
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
316
|
+
"\r\n",
|
317
|
+
file_descriptor,
|
318
|
+
file_encoding,
|
319
|
+
)
|
320
|
+
output_cabrillo_line(
|
321
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
322
|
+
"\r\n",
|
323
|
+
file_descriptor,
|
324
|
+
file_encoding,
|
325
|
+
)
|
326
|
+
mode = self.contest_settings.get("ModeCategory", "")
|
327
|
+
if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
|
328
|
+
mode = "MIXED"
|
329
|
+
output_cabrillo_line(
|
330
|
+
f"CATEGORY-MODE: {mode}",
|
331
|
+
"\r\n",
|
332
|
+
file_descriptor,
|
333
|
+
file_encoding,
|
334
|
+
)
|
335
|
+
output_cabrillo_line(
|
336
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
337
|
+
"\r\n",
|
338
|
+
file_descriptor,
|
339
|
+
file_encoding,
|
340
|
+
)
|
341
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
342
|
+
output_cabrillo_line(
|
343
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
344
|
+
"\r\n",
|
345
|
+
file_descriptor,
|
346
|
+
file_encoding,
|
347
|
+
)
|
348
|
+
output_cabrillo_line(
|
349
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
350
|
+
"\r\n",
|
351
|
+
file_descriptor,
|
352
|
+
file_encoding,
|
353
|
+
)
|
354
|
+
output_cabrillo_line(
|
355
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
356
|
+
"\r\n",
|
357
|
+
file_descriptor,
|
358
|
+
file_encoding,
|
359
|
+
)
|
360
|
+
|
361
|
+
output_cabrillo_line(
|
362
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
363
|
+
"\r\n",
|
364
|
+
file_descriptor,
|
365
|
+
file_encoding,
|
366
|
+
)
|
367
|
+
ops = f"@{self.station.get('Call','')}"
|
368
|
+
list_of_ops = self.database.get_ops()
|
369
|
+
for op in list_of_ops:
|
370
|
+
ops += f", {op.get('Operator', '')}"
|
371
|
+
output_cabrillo_line(
|
372
|
+
f"OPERATORS: {ops}",
|
373
|
+
"\r\n",
|
374
|
+
file_descriptor,
|
375
|
+
file_encoding,
|
376
|
+
)
|
377
|
+
output_cabrillo_line(
|
378
|
+
f"NAME: {self.station.get('Name', '')}",
|
379
|
+
"\r\n",
|
380
|
+
file_descriptor,
|
381
|
+
file_encoding,
|
382
|
+
)
|
383
|
+
output_cabrillo_line(
|
384
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
385
|
+
"\r\n",
|
386
|
+
file_descriptor,
|
387
|
+
file_encoding,
|
388
|
+
)
|
389
|
+
output_cabrillo_line(
|
390
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
391
|
+
"\r\n",
|
392
|
+
file_descriptor,
|
393
|
+
file_encoding,
|
394
|
+
)
|
395
|
+
output_cabrillo_line(
|
396
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
397
|
+
"\r\n",
|
398
|
+
file_descriptor,
|
399
|
+
file_encoding,
|
400
|
+
)
|
401
|
+
output_cabrillo_line(
|
402
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
403
|
+
"\r\n",
|
404
|
+
file_descriptor,
|
405
|
+
file_encoding,
|
406
|
+
)
|
407
|
+
output_cabrillo_line(
|
408
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
409
|
+
"\r\n",
|
410
|
+
file_descriptor,
|
411
|
+
file_encoding,
|
412
|
+
)
|
413
|
+
output_cabrillo_line(
|
414
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
415
|
+
"\r\n",
|
416
|
+
file_descriptor,
|
417
|
+
file_encoding,
|
418
|
+
)
|
419
|
+
for contact in log:
|
420
|
+
the_date_and_time = contact.get("TS", "")
|
421
|
+
themode = contact.get("Mode", "")
|
422
|
+
if themode == "LSB" or themode == "USB":
|
423
|
+
themode = "PH"
|
424
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
425
|
+
|
426
|
+
loggeddate = the_date_and_time[:10]
|
427
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
428
|
+
output_cabrillo_line(
|
429
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
430
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
431
|
+
f"{str(contact.get('SNT', '')).ljust(3)} "
|
432
|
+
f"{str(contact.get('SentNr', '')).ljust(6)} "
|
433
|
+
f"{contact.get('Call', '').ljust(13)} "
|
434
|
+
f"{str(contact.get('RCV', '')).ljust(3)} "
|
435
|
+
f"{str(contact.get('NR', '')).ljust(6)}",
|
436
|
+
"\r\n",
|
437
|
+
file_descriptor,
|
438
|
+
file_encoding,
|
439
|
+
)
|
440
|
+
output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
|
441
|
+
self.show_message_box(f"Cabrillo saved to: {filename}")
|
442
|
+
except IOError as exception:
|
443
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
444
|
+
self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
|
445
|
+
return
|
446
|
+
|
447
|
+
|
448
|
+
# def populate_history_info_line(self):
|
449
|
+
# result = self.database.fetch_call_history(self.callsign.text())
|
450
|
+
# if result:
|
451
|
+
# self.history_info.setText(
|
452
|
+
# f"{result.get('Call', '')}, {result.get('Exch1', '')}, {result.get('UserText','...')}"
|
453
|
+
# )
|
454
|
+
# else:
|
455
|
+
# self.history_info.setText("")
|
456
|
+
|
457
|
+
|
458
|
+
# def check_call_history(self):
|
459
|
+
# """"""
|
460
|
+
# result = self.database.fetch_call_history(self.callsign.text())
|
461
|
+
# print(f"{result=}")
|
462
|
+
# if result:
|
463
|
+
# self.history_info.setText(f"{result.get('UserText','')}")
|
464
|
+
# if self.other_2.text() == "":
|
465
|
+
# self.other_2.setText(f"{result.get('Exch1', '')}")
|
466
|
+
|
467
|
+
|
468
|
+
def process_esm(self, new_focused_widget=None, with_enter=False):
|
469
|
+
"""ESM State Machine"""
|
470
|
+
|
471
|
+
# self.pref["run_state"]
|
472
|
+
|
473
|
+
# -----===== Assigned F-Keys =====-----
|
474
|
+
# self.esm_dict["CQ"]
|
475
|
+
# self.esm_dict["EXCH"]
|
476
|
+
# self.esm_dict["QRZ"]
|
477
|
+
# self.esm_dict["AGN"]
|
478
|
+
# self.esm_dict["HISCALL"]
|
479
|
+
# self.esm_dict["MYCALL"]
|
480
|
+
# self.esm_dict["QSOB4"]
|
481
|
+
|
482
|
+
# ----==== text fields ====----
|
483
|
+
# self.callsign
|
484
|
+
# self.sent
|
485
|
+
# self.receive
|
486
|
+
# self.other_1
|
487
|
+
# self.other_2
|
488
|
+
|
489
|
+
if new_focused_widget is not None:
|
490
|
+
self.current_widget = self.inputs_dict.get(new_focused_widget)
|
491
|
+
|
492
|
+
# print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
|
493
|
+
|
494
|
+
for a_button in [
|
495
|
+
self.esm_dict["CQ"],
|
496
|
+
self.esm_dict["EXCH"],
|
497
|
+
self.esm_dict["QRZ"],
|
498
|
+
self.esm_dict["AGN"],
|
499
|
+
self.esm_dict["HISCALL"],
|
500
|
+
self.esm_dict["MYCALL"],
|
501
|
+
self.esm_dict["QSOB4"],
|
502
|
+
]:
|
503
|
+
if a_button is not None:
|
504
|
+
self.restore_button_color(a_button)
|
505
|
+
|
506
|
+
buttons_to_send = []
|
507
|
+
|
508
|
+
if self.pref.get("run_state"):
|
509
|
+
if self.current_widget == "callsign":
|
510
|
+
if len(self.callsign.text()) < 3:
|
511
|
+
self.make_button_green(self.esm_dict["CQ"])
|
512
|
+
buttons_to_send.append(self.esm_dict["CQ"])
|
513
|
+
elif len(self.callsign.text()) > 2:
|
514
|
+
self.make_button_green(self.esm_dict["HISCALL"])
|
515
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
516
|
+
buttons_to_send.append(self.esm_dict["HISCALL"])
|
517
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
518
|
+
|
519
|
+
elif self.current_widget == "other_2":
|
520
|
+
if self.other_2.text() == "":
|
521
|
+
self.make_button_green(self.esm_dict["AGN"])
|
522
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
523
|
+
else:
|
524
|
+
self.make_button_green(self.esm_dict["QRZ"])
|
525
|
+
buttons_to_send.append(self.esm_dict["QRZ"])
|
526
|
+
buttons_to_send.append("LOGIT")
|
527
|
+
|
528
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
529
|
+
for button in buttons_to_send:
|
530
|
+
if button:
|
531
|
+
if button == "LOGIT":
|
532
|
+
self.save_contact()
|
533
|
+
continue
|
534
|
+
self.process_function_key(button)
|
535
|
+
else:
|
536
|
+
if self.current_widget == "callsign":
|
537
|
+
if len(self.callsign.text()) > 2:
|
538
|
+
self.make_button_green(self.esm_dict["MYCALL"])
|
539
|
+
buttons_to_send.append(self.esm_dict["MYCALL"])
|
540
|
+
|
541
|
+
elif self.current_widget == "other_2":
|
542
|
+
if self.other_2.text() == "":
|
543
|
+
self.make_button_green(self.esm_dict["AGN"])
|
544
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
545
|
+
else:
|
546
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
547
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
548
|
+
buttons_to_send.append("LOGIT")
|
549
|
+
|
550
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
551
|
+
for button in buttons_to_send:
|
552
|
+
if button:
|
553
|
+
if button == "LOGIT":
|
554
|
+
self.save_contact()
|
555
|
+
continue
|
556
|
+
self.process_function_key(button)
|
557
|
+
|
558
|
+
|
559
|
+
def get_mults(self):
|
560
|
+
"""Get mults for RTC XML"""
|
561
|
+
mults = {}
|
562
|
+
mults["country"], mults["state"] = show_mults(self, rtc=True)
|
563
|
+
return mults
|
564
|
+
|
565
|
+
|
566
|
+
def just_points(self):
|
567
|
+
"""Get points for RTC XML"""
|
568
|
+
return get_points(self)
|
not1mm/plugins/jidx_cw.py
CHANGED
@@ -335,14 +335,25 @@ def cabrillo(self, file_encoding):
|
|
335
335
|
file_encoding,
|
336
336
|
)
|
337
337
|
output_cabrillo_line(
|
338
|
-
f"ADDRESS: {self.station.get('City', '')}
|
339
|
-
f"{self.station.get('Zip', '')}",
|
338
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
340
339
|
"\r\n",
|
341
340
|
file_descriptor,
|
342
341
|
file_encoding,
|
343
342
|
)
|
344
343
|
output_cabrillo_line(
|
345
|
-
f"ADDRESS: {self.station.get('
|
344
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
345
|
+
"\r\n",
|
346
|
+
file_descriptor,
|
347
|
+
file_encoding,
|
348
|
+
)
|
349
|
+
output_cabrillo_line(
|
350
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
351
|
+
"\r\n",
|
352
|
+
file_descriptor,
|
353
|
+
file_encoding,
|
354
|
+
)
|
355
|
+
output_cabrillo_line(
|
356
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
346
357
|
"\r\n",
|
347
358
|
file_descriptor,
|
348
359
|
file_encoding,
|
not1mm/plugins/jidx_ph.py
CHANGED
@@ -304,14 +304,25 @@ def cabrillo(self, file_encoding):
|
|
304
304
|
file_encoding,
|
305
305
|
)
|
306
306
|
output_cabrillo_line(
|
307
|
-
f"ADDRESS: {self.station.get('City', '')}
|
308
|
-
f"{self.station.get('Zip', '')}",
|
307
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
309
308
|
"\r\n",
|
310
309
|
file_descriptor,
|
311
310
|
file_encoding,
|
312
311
|
)
|
313
312
|
output_cabrillo_line(
|
314
|
-
f"ADDRESS: {self.station.get('
|
313
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
314
|
+
"\r\n",
|
315
|
+
file_descriptor,
|
316
|
+
file_encoding,
|
317
|
+
)
|
318
|
+
output_cabrillo_line(
|
319
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
320
|
+
"\r\n",
|
321
|
+
file_descriptor,
|
322
|
+
file_encoding,
|
323
|
+
)
|
324
|
+
output_cabrillo_line(
|
325
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
315
326
|
"\r\n",
|
316
327
|
file_descriptor,
|
317
328
|
file_encoding,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.4.
|
3
|
+
Version: 25.4.14
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
License: GPL-3.0-or-later
|
@@ -105,6 +105,8 @@ Dynamic: license-file
|
|
105
105
|
- [Sending CW](#sending-cw)
|
106
106
|
- [Sending CW Macros](#sending-cw-macros)
|
107
107
|
- [Auto CQ](#auto-cq)
|
108
|
+
- [Setting the delay](#setting-the-delay)
|
109
|
+
- [Cancelling the Auto CQ](#cancelling-the-auto-cq)
|
108
110
|
- [Sending CW Free Form](#sending-cw-free-form)
|
109
111
|
- [Editing macro keys](#editing-macro-keys)
|
110
112
|
- [Macro substitutions](#macro-substitutions)
|
@@ -117,7 +119,7 @@ Dynamic: license-file
|
|
117
119
|
- [The Log Window](#the-log-window)
|
118
120
|
- [Editing a contact](#editing-a-contact)
|
119
121
|
- [The Bandmap Window](#the-bandmap-window)
|
120
|
-
- [The Check Window](#the-check-window)
|
122
|
+
- [The Check Partial Window](#the-check-partial-window)
|
121
123
|
- [The Rate Window](#the-rate-window)
|
122
124
|
- [The Remote VFO Window](#the-remote-vfo-window)
|
123
125
|
- [Cabrillo](#cabrillo)
|
@@ -228,6 +230,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
228
230
|
- EA Majistad CW
|
229
231
|
- EA Majistad SSB
|
230
232
|
- EA RTTY
|
233
|
+
- ES OPEN HF
|
231
234
|
- Helvetia
|
232
235
|
- IARU Fieldday R1 CW, SSB
|
233
236
|
- IARU HF
|
@@ -251,14 +254,16 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
251
254
|
|
252
255
|
## Recent Changes
|
253
256
|
|
257
|
+
- [25-4-14] Add ES Open HF Chanmpionship.
|
258
|
+
- [25-4-13] Fix crash in JIDX Cabrillo output.
|
254
259
|
- [25-4-12] Added an Auto CQ time to fire progress bar.
|
255
260
|
- [25-4-11-3] Fixed issue with winkeyer not sending multiple macros in ESM mode.
|
256
261
|
- [25-4-11-2] Fixed a crash.
|
257
262
|
- [25-4-11-1] Add clear buffer to winkeyer interface to stop sending.
|
258
263
|
- [25-4-11] Add Scandinavian Activity Contest
|
259
|
-
- [25-4-10-1] Add ARI 40/80 contest. Add
|
264
|
+
- [25-4-10-1] Add ARI 40/80 contest. Add CTRL-R to toggle Run state.
|
260
265
|
- [25-4-10] Add Auto CQ visual indicator.
|
261
|
-
- [25-4-9] Added UKEI DX
|
266
|
+
- [25-4-9] Added UKEI DX Contest.
|
262
267
|
- [25-4-8] Remove focus from statistics table widget.
|
263
268
|
- [25-4-7] Merge in changes from dj1yfk correcting SPDX Cabrillo name.
|
264
269
|
- [25-4-5] Add SPDX.
|
@@ -671,14 +676,22 @@ pressing F1 - F12. See next section on Editing macro keys.
|
|
671
676
|
|
672
677
|
### Auto CQ
|
673
678
|
|
674
|
-
If you press `SHIFT-F1` The Auto CQ mode will be activated
|
675
|
-
after each Auto CQ Delay interval has passed.
|
676
|
-
the F1 macro key as a visual reminder that your
|
679
|
+
If you press `SHIFT-F1` The Auto CQ mode will be activated, you will be placed in a Run state
|
680
|
+
and the F1 macro will be resent after each Auto CQ Delay interval has passed.
|
681
|
+
An indicator will appear to the upper left of the F1 macro key as a visual reminder that your
|
682
|
+
Auto CQ is active. With it to the right, you will see a small progress bar giving you a visual
|
683
|
+
indication as to when F1 will fire next.
|
677
684
|
|
678
685
|

|
679
686
|
|
687
|
+
#### Setting the delay
|
688
|
+
|
680
689
|
The delay can be changed by going to the `Options` TAB in the Configuration dialog. If you are in
|
681
|
-
S&P mode when you enable Auto CQ, you will be automatically switched into RUN mode.
|
690
|
+
S&P mode when you enable Auto CQ, you will be automatically switched into RUN mode. To properly set
|
691
|
+
the delay you should time how long your F1 macro takes to key, then add how many seconds of pause
|
692
|
+
you would like. This is your delay value.
|
693
|
+
|
694
|
+
#### Cancelling the Auto CQ
|
682
695
|
|
683
696
|
The auto CQ can be cancelled by either typing in the call sign field, or by pressing ESC.
|
684
697
|
|
@@ -759,6 +772,8 @@ is this has happened, since the gridsquare will replace the word "Regional".
|
|
759
772
|
|
760
773
|
## Other uses for the call field
|
761
774
|
|
775
|
+
**You must press the SPACE bar after entering any of the below.**
|
776
|
+
|
762
777
|
- [A Frequency] You can enter a frequency in kilohertz. This will change the band you're logging on. If you have CAT control, this will change the frequency of the radio as well.
|
763
778
|
- [CW, SSB, RTTY] You can set the mode logged. If you have CAT control this will also change the mode on the radio.
|
764
779
|
- [OPON] Change the operator currently logging.
|
@@ -775,9 +790,9 @@ is this has happened, since the gridsquare will replace the word "Regional".
|
|
775
790
|
|
776
791
|
| Key | Result |
|
777
792
|
| -------------- | --- |
|
778
|
-
| [Esc] | Stops
|
779
|
-
| [PgUp] | Increases the
|
780
|
-
| [PgDown] | Decreases the
|
793
|
+
| [Esc] | Stops sending CW. |
|
794
|
+
| [PgUp] | Increases the CW sending speed. |
|
795
|
+
| [PgDown] | Decreases the CW sending speed. |
|
781
796
|
| [Arrow-Up] | Jump to the next spot above the current VFO cursor in the bandmap window (CAT Required). |
|
782
797
|
| [Arrow-Down] | Jump to the next spot below the current VFO cursor in the bandmap window (CAT Required). |
|
783
798
|
| [TAB] | Move cursor to the right one field. |
|
@@ -792,6 +807,12 @@ is this has happened, since the gridsquare will replace the word "Regional".
|
|
792
807
|
| [CTRL-SHIFT-K] | Open CW text input field. |
|
793
808
|
| [CTRL-=] | Log the contact without sending the ESM macros.|
|
794
809
|
| [CTRL-W] | Clears the input fields of any text. |
|
810
|
+
| [ALT-B] | Toggles the BandMap window. |
|
811
|
+
| [ALT-C] | Toggles the Check Partial window. |
|
812
|
+
| [ALT-L] | Toggles the QSO Log window. |
|
813
|
+
| [ALT-R] | Toggles the Rate window. |
|
814
|
+
| [ALT-S] | Toggles the Statistics window. |
|
815
|
+
| [ALT-V] | Toggles the VFO window. |
|
795
816
|
|
796
817
|
### The Log Window
|
797
818
|
|
@@ -839,9 +860,9 @@ blue rectangle shows the receivers bandwidth if one is reported.
|
|
839
860
|
Clicked on spots now tune the radio and set the callsign field. Previously
|
840
861
|
worked calls are displayed in red.
|
841
862
|
|
842
|
-
### The Check Window
|
863
|
+
### The Check Partial Window
|
843
864
|
|
844
|
-
`Window`>`Check Window`
|
865
|
+
`Window`>`Check Partial Window`
|
845
866
|
|
846
867
|
As you enter a callsign, the Check Window will show probable matches to calls
|
847
868
|
either in the MASTER.SCP file, your local log or the recent telnet spots. The
|
@@ -905,8 +926,12 @@ change.
|
|
905
926
|
|
906
927
|
## ESM
|
907
928
|
|
908
|
-
|
909
|
-
|
929
|
+
ESM or Enter Sends Message. ESM is a feature in which the logging program will automatically
|
930
|
+
send the right function key macros based on the information present in the input fields and
|
931
|
+
which input field is active when you press the Enter key. You can see a common flow in the
|
932
|
+
examples below.
|
933
|
+
|
934
|
+
To test it out you can go to `FILE -> Configuration Settings`
|
910
935
|
|
911
936
|

|
912
937
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=T03w3kUEWO4gy1oiDYG7GnqxhN4P5MH4ZB1u6SWB7pQ,153922
|
3
3
|
not1mm/bandmap.py,sha256=-zu5slsuAm2GmeW8g3yvURzsuQxemwIQfw1HEq8xKHM,29920
|
4
4
|
not1mm/checkwindow.py,sha256=zEHlw40j6Wr3rvKbCQf2lcezCoiZqaBqEvBjQU5aKW0,7630
|
5
5
|
not1mm/fsutils.py,sha256=ukHKxKTeNKxKwqRaJjtzRShL4X5Xl0jRBbADyy3Ifp8,1701
|
@@ -23,7 +23,7 @@ not1mm/data/configuration.ui,sha256=mqhEvxD9lQGeoEkUrvbO9uNrOG62z6EIUUMa_b_SG-o,
|
|
23
23
|
not1mm/data/contests.sql,sha256=4hmJCDvrbxnA_Y5S4T5o52TZieeFk6QUwFerwlFePNA,89307
|
24
24
|
not1mm/data/cty.json,sha256=bwPhOrOAgvV9JiXUDT9kzCqfNWAhGuJQt489h0SKsCk,4925375
|
25
25
|
not1mm/data/cwmacros.txt,sha256=NztufsX6R52gAO7VyJ2AHr7wOh41pJTwHKh5Lcs32ds,468
|
26
|
-
not1mm/data/donors.html,sha256=
|
26
|
+
not1mm/data/donors.html,sha256=qLg2n3NoJ5ZMNZye-nD_lgNjtSqL7952k_Z_bbJM5hA,297
|
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
29
|
not1mm/data/greendot.png,sha256=El9TomJcGtViRcHOR7kMxGzjzvYs0TSAqOb3tZv0JDA,368
|
@@ -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=-JDQXOaxj8_7Wda9KT2rEM4YUjBs31CiT1Rjc_DBobM,64907
|
37
|
-
not1mm/data/new_contest.ui,sha256=
|
37
|
+
not1mm/data/new_contest.ui,sha256=glqsmFGF5gh-JB-zuEVxAWrOR7-Hok5ibvZYCMcDCWE,25223
|
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
|
@@ -102,7 +102,7 @@ not1mm/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
102
102
|
not1mm/lib/about.py,sha256=sWycfGcruN3SaEe4JmaJ61K6D8Itq0WxpUYT-lEcmYM,416
|
103
103
|
not1mm/lib/cat_interface.py,sha256=BJvy-34ZyiN73kKNQcCzE4w6ll2O6Ue0uz01T_3sf1E,25204
|
104
104
|
not1mm/lib/cwinterface.py,sha256=rKUnqljHQC_Iljq4TCmAgSPe49lWbKcfxg58cE8YX5Y,5177
|
105
|
-
not1mm/lib/database.py,sha256
|
105
|
+
not1mm/lib/database.py,sha256=fykyaQaTa_Pwde51f09Odbexy1mlUqObv0fjZ7hf3E0,51693
|
106
106
|
not1mm/lib/edit_contact.py,sha256=Ki9bGPpqyQQBB1cU8VIBDCal3lbXeQ6qxhzklmhE2_w,353
|
107
107
|
not1mm/lib/edit_macro.py,sha256=raKWBwsHInj5EUKmvyLQ6gqc3ZFDlstsD3xqoM4PC8E,517
|
108
108
|
not1mm/lib/edit_opon.py,sha256=j3qJ1aBsQoIOnQ9yiBl3lyeISvKTP0I_rtBYBPAfgeI,359
|
@@ -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=VF2ECEwHJr0MWw2BVQtIHH1HDZfZCrSeIks7YLhW7iU,48
|
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
|
@@ -152,14 +152,15 @@ not1mm/plugins/darc_xmas.py,sha256=p5UNYLdtylsC_sSlxT8NvXXL1oSW0KyUhIN-rJonHgI,1
|
|
152
152
|
not1mm/plugins/ea_majistad_cw.py,sha256=tl9y92Oz4NTch4H-SrBnZND2tHGqWQvtgl3emXfU8og,23352
|
153
153
|
not1mm/plugins/ea_majistad_ssb.py,sha256=TwZLHwgybpIgA4ECXzV3bIeP89MLr3vXa4_O99-mgxQ,22946
|
154
154
|
not1mm/plugins/ea_rtty.py,sha256=JvszWdtUqC_Sn2sJAlMhMp2AdlLyAIj-6nWT-yFkihw,23229
|
155
|
+
not1mm/plugins/es_ll_kv.py,sha256=A0zW59A6DYzPTM6Q_zBGKM3zeDr9DXlS9oaAPdxKt5k,18384
|
155
156
|
not1mm/plugins/general_logging.py,sha256=eQuna-LnrWpf93LmHTTo6956GWoGocVfeYnzY5cyTmw,9600
|
156
157
|
not1mm/plugins/helvetia.py,sha256=fDKhvjDh5PxxLxmxvqTHzt-u0cMjHOjlF6JWBu3qB20,20079
|
157
158
|
not1mm/plugins/iaru_fieldday_r1_cw.py,sha256=1AVyZFi3ri2zqaNJY181Wtyz74fai8QLoi7PoyXpfaY,17218
|
158
159
|
not1mm/plugins/iaru_fieldday_r1_ssb.py,sha256=w0j4MY1LeGxOaQfRjxRS-Q4waTOOt-hbxA1spil7z_I,17222
|
159
160
|
not1mm/plugins/iaru_hf.py,sha256=VtNCijj_p03EIRfUJE-5FSarGb8P-Ek7gxIdPF_zHQQ,16721
|
160
161
|
not1mm/plugins/icwc_mst.py,sha256=IUpAETCjXxeTmOFu2ItivXiZGRaQgcuaPSu6Q1kOJAk,16539
|
161
|
-
not1mm/plugins/jidx_cw.py,sha256=
|
162
|
-
not1mm/plugins/jidx_ph.py,sha256=
|
162
|
+
not1mm/plugins/jidx_cw.py,sha256=fbdo-KDzNAHq-lH1V0X99wsZJkBVUkJN4yyegTRZFrs,16292
|
163
|
+
not1mm/plugins/jidx_ph.py,sha256=oFHZOPIa0pzVge0F73WPZ3z4cLiZCSBlO3499_Pe9NI,15241
|
163
164
|
not1mm/plugins/k1usn_sst.py,sha256=yeaejs9rgXot1ISayTHFCWtYcNxOT2NG4E9oeXfQrq8,17198
|
164
165
|
not1mm/plugins/labre_rs_digi.py,sha256=93awbxHK2Wi_XZWvUvtaZlQaxpoyX-ev_uj5lm0IZ60,20125
|
165
166
|
not1mm/plugins/lz-dx.py,sha256=hP6APYus4AFpz1rMxU82mq7ZB15_hwgsfuR4qInEG6k,19886
|
@@ -178,9 +179,9 @@ not1mm/plugins/stew_perry_topband.py,sha256=3U-Dr28haBTqTaZWLiC1qHQBmLsLENDL-ihy
|
|
178
179
|
not1mm/plugins/ukeidx.py,sha256=0ABGW7_9Ui0Rgr8mkPBxOJokAIerM1a4-HWnl6VsnV8,19105
|
179
180
|
not1mm/plugins/weekly_rtty.py,sha256=C8Xs3Q5UgSYx-mFFar8BVARWtmqlyrbeC98Ubzb4UN8,20128
|
180
181
|
not1mm/plugins/winter_field_day.py,sha256=hmAMgkdqIXtnCNyUp8J9Bb8liN8wj10wps6ROuG-Bok,15284
|
181
|
-
not1mm-25.4.
|
182
|
-
not1mm-25.4.
|
183
|
-
not1mm-25.4.
|
184
|
-
not1mm-25.4.
|
185
|
-
not1mm-25.4.
|
186
|
-
not1mm-25.4.
|
182
|
+
not1mm-25.4.14.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
183
|
+
not1mm-25.4.14.dist-info/METADATA,sha256=zEUjyqIWcZk19fufgQqtY-OwoWxDYPuoZ9y0gdbxYEc,39394
|
184
|
+
not1mm-25.4.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
185
|
+
not1mm-25.4.14.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
186
|
+
not1mm-25.4.14.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
187
|
+
not1mm-25.4.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|