not1mm 25.6.18__py3-none-any.whl → 25.6.18.1__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/data/new_contest.ui +5 -0
- not1mm/lib/plugin_common.py +19 -18
- not1mm/lib/version.py +1 -1
- not1mm/plugins/es_field_day.py +40 -19
- not1mm/plugins/es_manual_key.py +651 -0
- not1mm/plugins/es_open.py +33 -13
- {not1mm-25.6.18.dist-info → not1mm-25.6.18.1.dist-info}/METADATA +2 -1
- {not1mm-25.6.18.dist-info → not1mm-25.6.18.1.dist-info}/RECORD +12 -11
- {not1mm-25.6.18.dist-info → not1mm-25.6.18.1.dist-info}/WHEEL +0 -0
- {not1mm-25.6.18.dist-info → not1mm-25.6.18.1.dist-info}/entry_points.txt +0 -0
- {not1mm-25.6.18.dist-info → not1mm-25.6.18.1.dist-info}/licenses/LICENSE +0 -0
- {not1mm-25.6.18.dist-info → not1mm-25.6.18.1.dist-info}/top_level.txt +0 -0
not1mm/data/new_contest.ui
CHANGED
not1mm/lib/plugin_common.py
CHANGED
@@ -338,22 +338,23 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
338
338
|
self.show_message_box(f"Error saving ADIF file: {error}")
|
339
339
|
|
340
340
|
|
341
|
-
def get_station_arrlsection_code(self):
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
341
|
+
# def get_station_arrlsection_code(self):
|
342
|
+
# # get the station ARRL Section in station settings
|
343
|
+
# query = f"SELECT ARRLSection as arrlsection from Station;"
|
344
|
+
# # run query
|
345
|
+
# result = self.database.exec_sql(query)
|
346
|
+
# if result:
|
347
|
+
# arrlsection = result.get("arrlsection", "")
|
348
|
+
# return arrlsection
|
349
|
+
# return ""
|
350
350
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
351
|
+
|
352
|
+
# def get_station_state_code(self):
|
353
|
+
# # get the station state code in station settings
|
354
|
+
# query = f"SELECT state as state from Station;"
|
355
|
+
# # run query
|
356
|
+
# result = self.database.exec_sql(query)
|
357
|
+
# if result:
|
358
|
+
# state = result.get("state", "")
|
359
|
+
# return state
|
360
|
+
# return ""
|
not1mm/lib/version.py
CHANGED
not1mm/plugins/es_field_day.py
CHANGED
@@ -10,9 +10,11 @@ from pathlib import Path
|
|
10
10
|
|
11
11
|
from PyQt6 import QtWidgets
|
12
12
|
|
13
|
-
from not1mm.lib.plugin_common import
|
13
|
+
from not1mm.lib.plugin_common import (
|
14
|
+
gen_adif,
|
15
|
+
get_points,
|
16
|
+
)
|
14
17
|
|
15
|
-
from not1mm.lib.ham_utility import calculate_wpx_prefix
|
16
18
|
from not1mm.lib.version import __version__
|
17
19
|
|
18
20
|
logger = logging.getLogger(__name__)
|
@@ -56,9 +58,10 @@ estonian_regions = [
|
|
56
58
|
"TL",
|
57
59
|
"VC",
|
58
60
|
"VO",
|
59
|
-
"VP"
|
61
|
+
"VP",
|
60
62
|
]
|
61
63
|
|
64
|
+
|
62
65
|
def specific_contest_check_dupe(self, call):
|
63
66
|
""""""
|
64
67
|
# get mode from radio state
|
@@ -85,7 +88,7 @@ def specific_contest_check_dupe(self, call):
|
|
85
88
|
time_period_1 = time_periods[0] if len(time_periods) > 0 else None
|
86
89
|
time_period_2 = time_periods[1] if len(time_periods) > 1 else None
|
87
90
|
time_period_3 = time_periods[2] if len(time_periods) > 2 else None
|
88
|
-
|
91
|
+
|
89
92
|
# get current time in UTC
|
90
93
|
iso_current_time = datetime.now(timezone.utc)
|
91
94
|
current_time = iso_current_time.replace(tzinfo=None)
|
@@ -93,7 +96,11 @@ def specific_contest_check_dupe(self, call):
|
|
93
96
|
result = {}
|
94
97
|
result["isdupe"] = False
|
95
98
|
|
96
|
-
if
|
99
|
+
if (
|
100
|
+
time_period_1 is not None
|
101
|
+
and current_time < time_period_1
|
102
|
+
and current_time >= start_date_init_date
|
103
|
+
):
|
97
104
|
|
98
105
|
result = self.database.check_dupe_on_period_mode(
|
99
106
|
call,
|
@@ -103,7 +110,12 @@ def specific_contest_check_dupe(self, call):
|
|
103
110
|
time_period_1.strftime("%Y-%m-%d %H:%M:%S"),
|
104
111
|
)
|
105
112
|
|
106
|
-
if
|
113
|
+
if (
|
114
|
+
time_period_1 is not None
|
115
|
+
and time_period_2 is not None
|
116
|
+
and current_time < time_period_2
|
117
|
+
and current_time >= time_period_1
|
118
|
+
):
|
107
119
|
|
108
120
|
result = self.database.check_dupe_on_period_mode(
|
109
121
|
call,
|
@@ -113,7 +125,12 @@ def specific_contest_check_dupe(self, call):
|
|
113
125
|
time_period_2.strftime("%Y-%m-%d %H:%M:%S"),
|
114
126
|
)
|
115
127
|
|
116
|
-
if
|
128
|
+
if (
|
129
|
+
time_period_2 is not None
|
130
|
+
and time_period_3 is not None
|
131
|
+
and current_time < time_period_3
|
132
|
+
and current_time >= time_period_2
|
133
|
+
):
|
117
134
|
|
118
135
|
result = self.database.check_dupe_on_period_mode(
|
119
136
|
call,
|
@@ -131,6 +148,7 @@ def specific_contest_check_dupe(self, call):
|
|
131
148
|
|
132
149
|
return result
|
133
150
|
|
151
|
+
|
134
152
|
def init_contest(self):
|
135
153
|
"""setup plugin"""
|
136
154
|
set_tab_next(self)
|
@@ -195,13 +213,13 @@ def predupe(self):
|
|
195
213
|
|
196
214
|
def prefill(self):
|
197
215
|
"""Fill SentNR"""
|
198
|
-
|
216
|
+
|
199
217
|
sent_sxchange_setting = self.contest_settings.get("SentExchange", "")
|
200
218
|
if sent_sxchange_setting.strip() == "#":
|
201
219
|
result = self.database.get_serial()
|
202
220
|
serial_nr = str(result.get("serial_nr", "1")).zfill(3)
|
203
221
|
# get station region code from setup ARRLSection field
|
204
|
-
serial_nr = serial_nr + " " +
|
222
|
+
serial_nr = serial_nr + " " + self.station.get("State", "")
|
205
223
|
|
206
224
|
if serial_nr == "None":
|
207
225
|
serial_nr = "001"
|
@@ -228,15 +246,17 @@ def points(self):
|
|
228
246
|
else:
|
229
247
|
return 1
|
230
248
|
|
249
|
+
|
231
250
|
def show_mults(self, rtc=None):
|
232
251
|
"""Return display string for mults"""
|
233
252
|
|
234
253
|
# implement here multipliers checks
|
235
254
|
# get received number and region code
|
236
255
|
|
237
|
-
call_result
|
256
|
+
# call_result never used, so commenting it out.
|
257
|
+
# call_result = str(self.contact.get("NR", ""))
|
238
258
|
# create placeholders
|
239
|
-
placeholders =
|
259
|
+
placeholders = ",".join(["?"] * len(estonian_regions))
|
240
260
|
# main query to filter by regions
|
241
261
|
query = f"SELECT count(distinct(SUBSTR(NR, -2)) || ':' || Band || ':' || Mode) as mults from DXLOG where ContestNR = {self.pref.get('contest', '1')} AND CountryPrefix = 'ES' AND NR GLOB '*[A-Z]*' AND substr(NR,-2) IN ({placeholders});"
|
242
262
|
# apply params
|
@@ -248,6 +268,7 @@ def show_mults(self, rtc=None):
|
|
248
268
|
return mult_count
|
249
269
|
return 0
|
250
270
|
|
271
|
+
|
251
272
|
def show_qso(self):
|
252
273
|
"""Return qso count"""
|
253
274
|
result = self.database.fetch_qso_count()
|
@@ -592,13 +613,13 @@ def process_esm(self, new_focused_widget=None, with_enter=False):
|
|
592
613
|
self.process_function_key(button)
|
593
614
|
|
594
615
|
|
595
|
-
def get_mults(self):
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
616
|
+
# def get_mults(self):
|
617
|
+
# """Get mults for RTC XML"""
|
618
|
+
# mults = {}
|
619
|
+
# mults["country"], mults["state"] = show_mults(self, rtc=True)
|
620
|
+
# return mults
|
600
621
|
|
601
622
|
|
602
|
-
def just_points(self):
|
603
|
-
|
604
|
-
|
623
|
+
# def just_points(self):
|
624
|
+
# """Get points for RTC XML"""
|
625
|
+
# return get_points(self)
|
@@ -0,0 +1,651 @@
|
|
1
|
+
""" """
|
2
|
+
|
3
|
+
import logging
|
4
|
+
import platform
|
5
|
+
import datetime
|
6
|
+
|
7
|
+
|
8
|
+
from pathlib import Path
|
9
|
+
|
10
|
+
from PyQt6 import QtWidgets
|
11
|
+
|
12
|
+
from not1mm.lib.plugin_common import gen_adif, get_points
|
13
|
+
|
14
|
+
from not1mm.lib.ham_utility import calculate_wpx_prefix
|
15
|
+
from not1mm.lib.version import __version__
|
16
|
+
|
17
|
+
logger = logging.getLogger(__name__)
|
18
|
+
|
19
|
+
EXCHANGE_HINT = "#"
|
20
|
+
|
21
|
+
|
22
|
+
name = "ES MANUAL KEY"
|
23
|
+
cabrillo_name = "ES-MANUAL-KEY"
|
24
|
+
mode = "CW" # CW SSB BOTH RTTY
|
25
|
+
|
26
|
+
columns = [
|
27
|
+
"YYYY-MM-DD HH:MM:SS",
|
28
|
+
"Call",
|
29
|
+
"Freq",
|
30
|
+
"Mode",
|
31
|
+
"Snt",
|
32
|
+
"Rcv",
|
33
|
+
"SentNr",
|
34
|
+
"RcvNr",
|
35
|
+
"PTS",
|
36
|
+
]
|
37
|
+
|
38
|
+
advance_on_space = [True, True, True, True, True]
|
39
|
+
|
40
|
+
# 5 Contest specific dupe check.
|
41
|
+
dupe_type = 5
|
42
|
+
|
43
|
+
|
44
|
+
def specific_contest_check_dupe(self, call):
|
45
|
+
""""""
|
46
|
+
# get mode from radio state
|
47
|
+
mode = self.radio_state.get("mode", "")
|
48
|
+
"""Dupe checking specific to just this contest."""
|
49
|
+
# constant to split the contest - correct ES Open Contest length is 4 hours
|
50
|
+
contest_length_in_minutes = 45
|
51
|
+
split_contest_by_minutes = 15
|
52
|
+
|
53
|
+
period_count = int(contest_length_in_minutes / split_contest_by_minutes)
|
54
|
+
|
55
|
+
# think about generic solution by splitting the contest to n different periods
|
56
|
+
start_date_init = self.contest_settings.get("StartDate", "")
|
57
|
+
start_date_init_date = datetime.datetime.strptime(
|
58
|
+
start_date_init, "%Y-%m-%d %H:%M:%S"
|
59
|
+
)
|
60
|
+
|
61
|
+
# Create time periods dynamically based on period count
|
62
|
+
time_periods = []
|
63
|
+
for i in range(period_count):
|
64
|
+
minutes_to_add = split_contest_by_minutes * (i + 1)
|
65
|
+
time_period = start_date_init_date + datetime.timedelta(minutes=minutes_to_add)
|
66
|
+
time_periods.append(time_period)
|
67
|
+
|
68
|
+
# Assign to variables for backwards compatibility
|
69
|
+
time_period_1 = time_periods[0] if len(time_periods) > 0 else None
|
70
|
+
time_period_2 = time_periods[1] if len(time_periods) > 1 else None
|
71
|
+
time_period_3 = time_periods[2] if len(time_periods) > 2 else None
|
72
|
+
|
73
|
+
# get current time in UTC
|
74
|
+
iso_current_time = datetime.datetime.now(datetime.timezone.utc)
|
75
|
+
current_time = iso_current_time.replace(tzinfo=None)
|
76
|
+
|
77
|
+
result = {}
|
78
|
+
result["isdupe"] = False
|
79
|
+
|
80
|
+
if (
|
81
|
+
time_period_1 is not None
|
82
|
+
and current_time < time_period_1
|
83
|
+
and current_time >= start_date_init_date
|
84
|
+
):
|
85
|
+
|
86
|
+
result = self.database.check_dupe_on_period_mode(
|
87
|
+
call,
|
88
|
+
self.contact.get("Band", ""),
|
89
|
+
mode,
|
90
|
+
start_date_init_date,
|
91
|
+
time_period_1.strftime("%Y-%m-%d %H:%M:%S"),
|
92
|
+
)
|
93
|
+
|
94
|
+
if (
|
95
|
+
time_period_2 is not None
|
96
|
+
and time_period_1 is not None
|
97
|
+
and current_time < time_period_2
|
98
|
+
and current_time >= time_period_1
|
99
|
+
):
|
100
|
+
|
101
|
+
result = self.database.check_dupe_on_period_mode(
|
102
|
+
call,
|
103
|
+
self.contact.get("Band", ""),
|
104
|
+
mode,
|
105
|
+
time_period_1.strftime("%Y-%m-%d %H:%M:%S"),
|
106
|
+
time_period_2.strftime("%Y-%m-%d %H:%M:%S"),
|
107
|
+
)
|
108
|
+
|
109
|
+
if (
|
110
|
+
time_period_3 is not None
|
111
|
+
and time_period_2 is not None
|
112
|
+
and current_time < time_period_3
|
113
|
+
and current_time >= time_period_2
|
114
|
+
):
|
115
|
+
|
116
|
+
result = self.database.check_dupe_on_period_mode(
|
117
|
+
call,
|
118
|
+
self.contact.get("Band", ""),
|
119
|
+
mode,
|
120
|
+
time_period_2.strftime("%Y-%m-%d %H:%M:%S"),
|
121
|
+
time_period_3.strftime("%Y-%m-%d %H:%M:%S"),
|
122
|
+
)
|
123
|
+
|
124
|
+
# just for band and mode if outside of time period
|
125
|
+
else:
|
126
|
+
result = self.database.check_dupe_on_band_mode(
|
127
|
+
call, self.contact.get("Band", ""), mode
|
128
|
+
)
|
129
|
+
|
130
|
+
return result
|
131
|
+
|
132
|
+
|
133
|
+
def init_contest(self):
|
134
|
+
"""setup plugin"""
|
135
|
+
set_tab_next(self)
|
136
|
+
set_tab_prev(self)
|
137
|
+
interface(self)
|
138
|
+
self.next_field = self.other_2
|
139
|
+
|
140
|
+
|
141
|
+
def interface(self):
|
142
|
+
"""Setup user interface"""
|
143
|
+
self.field1.show()
|
144
|
+
self.field2.show()
|
145
|
+
self.field3.show()
|
146
|
+
self.field4.show()
|
147
|
+
self.other_label.setText("Sent")
|
148
|
+
self.field3.setAccessibleName("Sent")
|
149
|
+
self.exch_label.setText("SN")
|
150
|
+
self.field4.setAccessibleName("SN")
|
151
|
+
|
152
|
+
|
153
|
+
def reset_label(self):
|
154
|
+
"""reset label after field cleared"""
|
155
|
+
|
156
|
+
|
157
|
+
def set_tab_next(self):
|
158
|
+
"""Set TAB Advances"""
|
159
|
+
self.tab_next = {
|
160
|
+
self.callsign: self.other_1,
|
161
|
+
self.sent: self.other_1,
|
162
|
+
self.receive: self.other_1,
|
163
|
+
self.other_1: self.other_2,
|
164
|
+
self.other_2: self.callsign,
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
def set_tab_prev(self):
|
169
|
+
"""Set TAB Advances"""
|
170
|
+
self.tab_prev = {
|
171
|
+
self.callsign: self.other_2,
|
172
|
+
self.sent: self.callsign,
|
173
|
+
self.receive: self.callsign,
|
174
|
+
self.other_1: self.callsign,
|
175
|
+
self.other_2: self.other_1,
|
176
|
+
}
|
177
|
+
|
178
|
+
|
179
|
+
def set_contact_vars(self):
|
180
|
+
"""Contest Specific"""
|
181
|
+
self.contact["SNT"] = self.sent.text()
|
182
|
+
self.contact["RCV"] = self.receive.text()
|
183
|
+
self.contact["SentNr"] = self.other_1.text().upper()
|
184
|
+
self.contact["NR"] = self.other_2.text().upper()
|
185
|
+
|
186
|
+
self.contact["IsMultiplier1"] = 0
|
187
|
+
self.contact["IsMultiplier2"] = 0
|
188
|
+
|
189
|
+
|
190
|
+
def predupe(self):
|
191
|
+
"""called after callsign entered"""
|
192
|
+
|
193
|
+
|
194
|
+
def prefill(self):
|
195
|
+
"""Fill SentNR"""
|
196
|
+
sent_sxchange_setting = self.contest_settings.get("SentExchange", "")
|
197
|
+
if sent_sxchange_setting.strip() == "#":
|
198
|
+
result = self.database.get_serial()
|
199
|
+
serial_nr = str(result.get("serial_nr", "1"))
|
200
|
+
serial_nr_last3 = serial_nr[-3:].zfill(3)
|
201
|
+
if serial_nr_last3 == "None":
|
202
|
+
serial_nr_last3 = "001"
|
203
|
+
# get station license class from setup LicenseClass field - use it for seniority
|
204
|
+
# how many years from the first QSO using club station or individual station
|
205
|
+
|
206
|
+
# The LicenseClass should already be available in the self.station object
|
207
|
+
# serial_nr = get_station_license_class(self) + serial_nr_last3
|
208
|
+
serial_nr = self.station.get("LicenseClass", "") + serial_nr_last3
|
209
|
+
|
210
|
+
if len(self.other_1.text()) == 0:
|
211
|
+
self.other_1.setText(serial_nr)
|
212
|
+
else:
|
213
|
+
self.other_1.setText(sent_sxchange_setting)
|
214
|
+
|
215
|
+
|
216
|
+
# Points are awarded for each communication/qso according to the correspondent's broadcasting
|
217
|
+
# experience/seniority
|
218
|
+
# (i.e. the first two numbers of the received report).
|
219
|
+
# To obtain the total number of points, the experience/seniority points for all communications/qsos
|
220
|
+
# (including repeated communications) are added together,
|
221
|
+
# to which the competitor's own experience/seniority points
|
222
|
+
# for each period worked are added, i.e. 3 times.
|
223
|
+
# To motivate competitors with less experience, operators with up to 10 years of experience
|
224
|
+
# (inclusive) are awarded an additional 20 points for each communication/qso,
|
225
|
+
# and for operators with an experience range of 11-20 years, an additional 10 points.
|
226
|
+
# The competitor must also add the same points 3 times to his/her total to obtain the final result.
|
227
|
+
|
228
|
+
|
229
|
+
def points(self):
|
230
|
+
""" """
|
231
|
+
if self.contact_is_dupe > 0:
|
232
|
+
return 0
|
233
|
+
|
234
|
+
_mode = self.contact.get("Mode", "")
|
235
|
+
|
236
|
+
if _mode in "CW":
|
237
|
+
|
238
|
+
call_result = str(self.contact.get("NR", "")).strip()
|
239
|
+
|
240
|
+
# get call seniority
|
241
|
+
try:
|
242
|
+
seniority = int(call_result[:2])
|
243
|
+
except ValueError:
|
244
|
+
seniority = 0
|
245
|
+
|
246
|
+
# get call age (this is not used, so commenting out)
|
247
|
+
# age = call_result[2:4]
|
248
|
+
|
249
|
+
# get call serial number (this is not used, so commenting out)
|
250
|
+
# call_serial_nr = call_result[4:6]
|
251
|
+
|
252
|
+
if seniority < 10:
|
253
|
+
points = seniority + 20
|
254
|
+
elif seniority > 10 and seniority <= 20:
|
255
|
+
points = seniority + 10
|
256
|
+
else:
|
257
|
+
points = seniority
|
258
|
+
return points
|
259
|
+
|
260
|
+
return 0
|
261
|
+
|
262
|
+
|
263
|
+
def show_mults(self, rtc=None):
|
264
|
+
"""Return display string for mults"""
|
265
|
+
our_prefix = calculate_wpx_prefix(self.station.get("Call", ""))
|
266
|
+
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}';"
|
267
|
+
result = self.database.exec_sql(query)
|
268
|
+
if result:
|
269
|
+
mult_count = result.get("mults", 0)
|
270
|
+
return mult_count
|
271
|
+
return 0
|
272
|
+
|
273
|
+
|
274
|
+
def show_qso(self):
|
275
|
+
"""Return qso count"""
|
276
|
+
result = self.database.fetch_qso_count()
|
277
|
+
if result:
|
278
|
+
return int(result.get("qsos", 0))
|
279
|
+
return 0
|
280
|
+
|
281
|
+
|
282
|
+
# Points are awarded for each communication/qso according to the correspondent's broadcasting experience/seniority
|
283
|
+
# (i.e. the first two numbers of the received report).
|
284
|
+
# To obtain the total number of points, the experience/seniority points for all communications/qsos
|
285
|
+
# (including repeated communications) are added together,
|
286
|
+
# to which the competitor's own experience/seniority points
|
287
|
+
# for each period worked are added, i.e. 3 times.
|
288
|
+
# To motivate competitors with less experience, operators with up to 10 years of experience
|
289
|
+
# (inclusive) are awarded an additional 20 points for each communication/qso,
|
290
|
+
# and for operators with an experience range of 11-20 years, an additional 10 points.
|
291
|
+
# The competitor must also add the same points 3 times to his/her total to obtain the final result.
|
292
|
+
|
293
|
+
|
294
|
+
def calc_score(self):
|
295
|
+
"""Return calculated score"""
|
296
|
+
result = self.database.fetch_points()
|
297
|
+
if result is not None:
|
298
|
+
score = result.get("Points", "0")
|
299
|
+
if score is None:
|
300
|
+
score = "0"
|
301
|
+
contest_points = int(score)
|
302
|
+
|
303
|
+
# egt station seniority number
|
304
|
+
station_seniority = self.station.get("LicenseClass", "")
|
305
|
+
# calc station seniority
|
306
|
+
try:
|
307
|
+
station_seniority_multiplier = 3 * int(station_seniority.strip()[:2])
|
308
|
+
except ValueError:
|
309
|
+
station_seniority_multiplier = 3
|
310
|
+
|
311
|
+
# always add 3 times your own seniority to the overall score
|
312
|
+
contest_points = contest_points + station_seniority_multiplier
|
313
|
+
|
314
|
+
mults = show_mults(self)
|
315
|
+
return contest_points * (mults + 1)
|
316
|
+
return 0
|
317
|
+
|
318
|
+
|
319
|
+
def recalculate_mults(self):
|
320
|
+
"""Recalculates multipliers after change in logged qso."""
|
321
|
+
|
322
|
+
|
323
|
+
def adif(self):
|
324
|
+
"""Call the generate ADIF function"""
|
325
|
+
gen_adif(self, cabrillo_name, "ES OPEN")
|
326
|
+
|
327
|
+
|
328
|
+
def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
|
329
|
+
""""""
|
330
|
+
print(
|
331
|
+
line_to_output.encode(file_encoding, errors="ignore").decode(),
|
332
|
+
end=ending,
|
333
|
+
file=file_descriptor,
|
334
|
+
)
|
335
|
+
|
336
|
+
|
337
|
+
def cabrillo(self, file_encoding):
|
338
|
+
"""Generates Cabrillo file. Maybe."""
|
339
|
+
# https://www.cqwpx.com/cabrillo.htm
|
340
|
+
logger.debug("******Cabrillo*****")
|
341
|
+
logger.debug("Station: %s", f"{self.station}")
|
342
|
+
logger.debug("Contest: %s", f"{self.contest_settings}")
|
343
|
+
now = datetime.datetime.now()
|
344
|
+
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
345
|
+
filename = (
|
346
|
+
str(Path.home())
|
347
|
+
+ "/"
|
348
|
+
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
|
349
|
+
)
|
350
|
+
logger.debug("%s", filename)
|
351
|
+
log = self.database.fetch_all_contacts_asc()
|
352
|
+
try:
|
353
|
+
with open(filename, "w", encoding=file_encoding, newline="") as file_descriptor:
|
354
|
+
output_cabrillo_line(
|
355
|
+
"START-OF-LOG: 3.0",
|
356
|
+
"\r\n",
|
357
|
+
file_descriptor,
|
358
|
+
file_encoding,
|
359
|
+
)
|
360
|
+
output_cabrillo_line(
|
361
|
+
f"CREATED-BY: Not1MM v{__version__}",
|
362
|
+
"\r\n",
|
363
|
+
file_descriptor,
|
364
|
+
file_encoding,
|
365
|
+
)
|
366
|
+
output_cabrillo_line(
|
367
|
+
f"CONTEST: {cabrillo_name}",
|
368
|
+
"\r\n",
|
369
|
+
file_descriptor,
|
370
|
+
file_encoding,
|
371
|
+
)
|
372
|
+
if self.station.get("Club", ""):
|
373
|
+
output_cabrillo_line(
|
374
|
+
f"CLUB: {self.station.get('Club', '').upper()}",
|
375
|
+
"\r\n",
|
376
|
+
file_descriptor,
|
377
|
+
file_encoding,
|
378
|
+
)
|
379
|
+
output_cabrillo_line(
|
380
|
+
f"CALLSIGN: {self.station.get('Call','')}",
|
381
|
+
"\r\n",
|
382
|
+
file_descriptor,
|
383
|
+
file_encoding,
|
384
|
+
)
|
385
|
+
output_cabrillo_line(
|
386
|
+
f"LOCATION: {self.station.get('ARRLSection', '')}",
|
387
|
+
"\r\n",
|
388
|
+
file_descriptor,
|
389
|
+
file_encoding,
|
390
|
+
)
|
391
|
+
output_cabrillo_line(
|
392
|
+
f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
|
393
|
+
"\r\n",
|
394
|
+
file_descriptor,
|
395
|
+
file_encoding,
|
396
|
+
)
|
397
|
+
output_cabrillo_line(
|
398
|
+
f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
|
399
|
+
"\r\n",
|
400
|
+
file_descriptor,
|
401
|
+
file_encoding,
|
402
|
+
)
|
403
|
+
output_cabrillo_line(
|
404
|
+
f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
|
405
|
+
"\r\n",
|
406
|
+
file_descriptor,
|
407
|
+
file_encoding,
|
408
|
+
)
|
409
|
+
mode = self.contest_settings.get("ModeCategory", "")
|
410
|
+
if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
|
411
|
+
mode = "MIXED"
|
412
|
+
output_cabrillo_line(
|
413
|
+
f"CATEGORY-MODE: {mode}",
|
414
|
+
"\r\n",
|
415
|
+
file_descriptor,
|
416
|
+
file_encoding,
|
417
|
+
)
|
418
|
+
output_cabrillo_line(
|
419
|
+
f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
|
420
|
+
"\r\n",
|
421
|
+
file_descriptor,
|
422
|
+
file_encoding,
|
423
|
+
)
|
424
|
+
if self.contest_settings.get("OverlayCategory", "") != "N/A":
|
425
|
+
output_cabrillo_line(
|
426
|
+
f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
|
427
|
+
"\r\n",
|
428
|
+
file_descriptor,
|
429
|
+
file_encoding,
|
430
|
+
)
|
431
|
+
output_cabrillo_line(
|
432
|
+
f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
|
433
|
+
"\r\n",
|
434
|
+
file_descriptor,
|
435
|
+
file_encoding,
|
436
|
+
)
|
437
|
+
output_cabrillo_line(
|
438
|
+
f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
|
439
|
+
"\r\n",
|
440
|
+
file_descriptor,
|
441
|
+
file_encoding,
|
442
|
+
)
|
443
|
+
|
444
|
+
output_cabrillo_line(
|
445
|
+
f"CLAIMED-SCORE: {calc_score(self)}",
|
446
|
+
"\r\n",
|
447
|
+
file_descriptor,
|
448
|
+
file_encoding,
|
449
|
+
)
|
450
|
+
ops = f"@{self.station.get('Call','')}"
|
451
|
+
list_of_ops = self.database.get_ops()
|
452
|
+
for op in list_of_ops:
|
453
|
+
ops += f", {op.get('Operator', '')}"
|
454
|
+
output_cabrillo_line(
|
455
|
+
f"OPERATORS: {ops}",
|
456
|
+
"\r\n",
|
457
|
+
file_descriptor,
|
458
|
+
file_encoding,
|
459
|
+
)
|
460
|
+
output_cabrillo_line(
|
461
|
+
f"NAME: {self.station.get('Name', '')}",
|
462
|
+
"\r\n",
|
463
|
+
file_descriptor,
|
464
|
+
file_encoding,
|
465
|
+
)
|
466
|
+
output_cabrillo_line(
|
467
|
+
f"ADDRESS: {self.station.get('Street1', '')}",
|
468
|
+
"\r\n",
|
469
|
+
file_descriptor,
|
470
|
+
file_encoding,
|
471
|
+
)
|
472
|
+
output_cabrillo_line(
|
473
|
+
f"ADDRESS-CITY: {self.station.get('City', '')}",
|
474
|
+
"\r\n",
|
475
|
+
file_descriptor,
|
476
|
+
file_encoding,
|
477
|
+
)
|
478
|
+
output_cabrillo_line(
|
479
|
+
f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
|
480
|
+
"\r\n",
|
481
|
+
file_descriptor,
|
482
|
+
file_encoding,
|
483
|
+
)
|
484
|
+
output_cabrillo_line(
|
485
|
+
f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
|
486
|
+
"\r\n",
|
487
|
+
file_descriptor,
|
488
|
+
file_encoding,
|
489
|
+
)
|
490
|
+
output_cabrillo_line(
|
491
|
+
f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
|
492
|
+
"\r\n",
|
493
|
+
file_descriptor,
|
494
|
+
file_encoding,
|
495
|
+
)
|
496
|
+
output_cabrillo_line(
|
497
|
+
f"EMAIL: {self.station.get('Email', '')}",
|
498
|
+
"\r\n",
|
499
|
+
file_descriptor,
|
500
|
+
file_encoding,
|
501
|
+
)
|
502
|
+
for contact in log:
|
503
|
+
the_date_and_time = contact.get("TS", "")
|
504
|
+
themode = contact.get("Mode", "")
|
505
|
+
if themode == "LSB" or themode == "USB":
|
506
|
+
themode = "PH"
|
507
|
+
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
508
|
+
|
509
|
+
loggeddate = the_date_and_time[:10]
|
510
|
+
loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
|
511
|
+
output_cabrillo_line(
|
512
|
+
f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
|
513
|
+
f"{contact.get('StationPrefix', '').ljust(13)} "
|
514
|
+
f"{str(contact.get('SNT', '')).ljust(3)} "
|
515
|
+
f"{str(contact.get('SentNr', '')).ljust(6)} "
|
516
|
+
f"{contact.get('Call', '').ljust(13)} "
|
517
|
+
f"{str(contact.get('RCV', '')).ljust(3)} "
|
518
|
+
f"{str(contact.get('NR', '')).ljust(6)}",
|
519
|
+
"\r\n",
|
520
|
+
file_descriptor,
|
521
|
+
file_encoding,
|
522
|
+
)
|
523
|
+
output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
|
524
|
+
self.show_message_box(f"Cabrillo saved to: {filename}")
|
525
|
+
except IOError as exception:
|
526
|
+
logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
|
527
|
+
self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
|
528
|
+
return
|
529
|
+
|
530
|
+
|
531
|
+
# def populate_history_info_line(self):
|
532
|
+
# result = self.database.fetch_call_history(self.callsign.text())
|
533
|
+
# if result:
|
534
|
+
# self.history_info.setText(
|
535
|
+
# f"{result.get('Call', '')}, {result.get('Exch1', '')}, {result.get('UserText','...')}"
|
536
|
+
# )
|
537
|
+
# else:
|
538
|
+
# self.history_info.setText("")
|
539
|
+
|
540
|
+
|
541
|
+
# def check_call_history(self):
|
542
|
+
# """"""
|
543
|
+
# result = self.database.fetch_call_history(self.callsign.text())
|
544
|
+
# print(f"{result=}")
|
545
|
+
# if result:
|
546
|
+
# self.history_info.setText(f"{result.get('UserText','')}")
|
547
|
+
# if self.other_2.text() == "":
|
548
|
+
# self.other_2.setText(f"{result.get('Exch1', '')}")
|
549
|
+
|
550
|
+
|
551
|
+
def process_esm(self, new_focused_widget=None, with_enter=False):
|
552
|
+
"""ESM State Machine"""
|
553
|
+
|
554
|
+
# self.pref["run_state"]
|
555
|
+
|
556
|
+
# -----===== Assigned F-Keys =====-----
|
557
|
+
# self.esm_dict["CQ"]
|
558
|
+
# self.esm_dict["EXCH"]
|
559
|
+
# self.esm_dict["QRZ"]
|
560
|
+
# self.esm_dict["AGN"]
|
561
|
+
# self.esm_dict["HISCALL"]
|
562
|
+
# self.esm_dict["MYCALL"]
|
563
|
+
# self.esm_dict["QSOB4"]
|
564
|
+
|
565
|
+
# ----==== text fields ====----
|
566
|
+
# self.callsign
|
567
|
+
# self.sent
|
568
|
+
# self.receive
|
569
|
+
# self.other_1
|
570
|
+
# self.other_2
|
571
|
+
|
572
|
+
if new_focused_widget is not None:
|
573
|
+
self.current_widget = self.inputs_dict.get(new_focused_widget)
|
574
|
+
|
575
|
+
# print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
|
576
|
+
|
577
|
+
for a_button in [
|
578
|
+
self.esm_dict["CQ"],
|
579
|
+
self.esm_dict["EXCH"],
|
580
|
+
self.esm_dict["QRZ"],
|
581
|
+
self.esm_dict["AGN"],
|
582
|
+
self.esm_dict["HISCALL"],
|
583
|
+
self.esm_dict["MYCALL"],
|
584
|
+
self.esm_dict["QSOB4"],
|
585
|
+
]:
|
586
|
+
if a_button is not None:
|
587
|
+
self.restore_button_color(a_button)
|
588
|
+
|
589
|
+
buttons_to_send = []
|
590
|
+
|
591
|
+
if self.pref.get("run_state"):
|
592
|
+
if self.current_widget == "callsign":
|
593
|
+
if len(self.callsign.text()) < 3:
|
594
|
+
self.make_button_green(self.esm_dict["CQ"])
|
595
|
+
buttons_to_send.append(self.esm_dict["CQ"])
|
596
|
+
elif len(self.callsign.text()) > 2:
|
597
|
+
self.make_button_green(self.esm_dict["HISCALL"])
|
598
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
599
|
+
buttons_to_send.append(self.esm_dict["HISCALL"])
|
600
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
601
|
+
|
602
|
+
elif self.current_widget == "other_2":
|
603
|
+
if self.other_2.text() == "":
|
604
|
+
self.make_button_green(self.esm_dict["AGN"])
|
605
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
606
|
+
else:
|
607
|
+
self.make_button_green(self.esm_dict["QRZ"])
|
608
|
+
buttons_to_send.append(self.esm_dict["QRZ"])
|
609
|
+
buttons_to_send.append("LOGIT")
|
610
|
+
|
611
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
612
|
+
for button in buttons_to_send:
|
613
|
+
if button:
|
614
|
+
if button == "LOGIT":
|
615
|
+
self.save_contact()
|
616
|
+
continue
|
617
|
+
self.process_function_key(button)
|
618
|
+
else:
|
619
|
+
if self.current_widget == "callsign":
|
620
|
+
if len(self.callsign.text()) > 2:
|
621
|
+
self.make_button_green(self.esm_dict["MYCALL"])
|
622
|
+
buttons_to_send.append(self.esm_dict["MYCALL"])
|
623
|
+
|
624
|
+
elif self.current_widget == "other_2":
|
625
|
+
if self.other_2.text() == "":
|
626
|
+
self.make_button_green(self.esm_dict["AGN"])
|
627
|
+
buttons_to_send.append(self.esm_dict["AGN"])
|
628
|
+
else:
|
629
|
+
self.make_button_green(self.esm_dict["EXCH"])
|
630
|
+
buttons_to_send.append(self.esm_dict["EXCH"])
|
631
|
+
buttons_to_send.append("LOGIT")
|
632
|
+
|
633
|
+
if with_enter is True and bool(len(buttons_to_send)):
|
634
|
+
for button in buttons_to_send:
|
635
|
+
if button:
|
636
|
+
if button == "LOGIT":
|
637
|
+
self.save_contact()
|
638
|
+
continue
|
639
|
+
self.process_function_key(button)
|
640
|
+
|
641
|
+
|
642
|
+
# def get_mults(self):
|
643
|
+
# """Get mults for RTC XML"""
|
644
|
+
# mults = {}
|
645
|
+
# mults["country"], mults["state"] = show_mults(self, rtc=True)
|
646
|
+
# return mults
|
647
|
+
|
648
|
+
|
649
|
+
# def just_points(self):
|
650
|
+
# """Get points for RTC XML"""
|
651
|
+
# return get_points(self)
|
not1mm/plugins/es_open.py
CHANGED
@@ -78,7 +78,11 @@ def specific_contest_check_dupe(self, call):
|
|
78
78
|
result = {}
|
79
79
|
result["isdupe"] = False
|
80
80
|
|
81
|
-
if
|
81
|
+
if (
|
82
|
+
time_period_1 is not None
|
83
|
+
and current_time < time_period_1
|
84
|
+
and current_time >= start_date_init_date
|
85
|
+
):
|
82
86
|
|
83
87
|
result = self.database.check_dupe_on_period_mode(
|
84
88
|
call,
|
@@ -88,7 +92,12 @@ def specific_contest_check_dupe(self, call):
|
|
88
92
|
time_period_1.strftime("%Y-%m-%d %H:%M:%S"),
|
89
93
|
)
|
90
94
|
|
91
|
-
if
|
95
|
+
if (
|
96
|
+
time_period_1 is not None
|
97
|
+
and time_period_2 is not None
|
98
|
+
and current_time < time_period_2
|
99
|
+
and current_time >= time_period_1
|
100
|
+
):
|
92
101
|
|
93
102
|
result = self.database.check_dupe_on_period_mode(
|
94
103
|
call,
|
@@ -98,7 +107,12 @@ def specific_contest_check_dupe(self, call):
|
|
98
107
|
time_period_2.strftime("%Y-%m-%d %H:%M:%S"),
|
99
108
|
)
|
100
109
|
|
101
|
-
if
|
110
|
+
if (
|
111
|
+
time_period_2 is not None
|
112
|
+
and time_period_3 is not None
|
113
|
+
and current_time < time_period_3
|
114
|
+
and current_time >= time_period_2
|
115
|
+
):
|
102
116
|
|
103
117
|
result = self.database.check_dupe_on_period_mode(
|
104
118
|
call,
|
@@ -108,7 +122,12 @@ def specific_contest_check_dupe(self, call):
|
|
108
122
|
time_period_3.strftime("%Y-%m-%d %H:%M:%S"),
|
109
123
|
)
|
110
124
|
|
111
|
-
if
|
125
|
+
if (
|
126
|
+
time_period_3 is not None
|
127
|
+
and time_period_4 is not None
|
128
|
+
and current_time < time_period_4
|
129
|
+
and current_time >= time_period_3
|
130
|
+
):
|
112
131
|
|
113
132
|
result = self.database.check_dupe_on_period_mode(
|
114
133
|
call,
|
@@ -125,6 +144,7 @@ def specific_contest_check_dupe(self, call):
|
|
125
144
|
|
126
145
|
return result
|
127
146
|
|
147
|
+
|
128
148
|
def init_contest(self):
|
129
149
|
"""setup plugin"""
|
130
150
|
set_tab_next(self)
|
@@ -270,7 +290,7 @@ def cabrillo(self, file_encoding):
|
|
270
290
|
logger.debug("******Cabrillo*****")
|
271
291
|
logger.debug("Station: %s", f"{self.station}")
|
272
292
|
logger.debug("Contest: %s", f"{self.contest_settings}")
|
273
|
-
now = datetime.
|
293
|
+
now = datetime.now()
|
274
294
|
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
275
295
|
filename = (
|
276
296
|
str(Path.home())
|
@@ -569,13 +589,13 @@ def process_esm(self, new_focused_widget=None, with_enter=False):
|
|
569
589
|
self.process_function_key(button)
|
570
590
|
|
571
591
|
|
572
|
-
def get_mults(self):
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
592
|
+
# def get_mults(self):
|
593
|
+
# """Get mults for RTC XML"""
|
594
|
+
# mults = {}
|
595
|
+
# mults["country"], mults["state"] = show_mults(self, rtc=True)
|
596
|
+
# return mults
|
577
597
|
|
578
598
|
|
579
|
-
def just_points(self):
|
580
|
-
|
581
|
-
|
599
|
+
# def just_points(self):
|
600
|
+
# """Get points for RTC XML"""
|
601
|
+
# return get_points(self)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.6.18
|
3
|
+
Version: 25.6.18.1
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
License: GPL-3.0-or-later
|
@@ -246,6 +246,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
246
246
|
|
247
247
|
## Recent Changes
|
248
248
|
|
249
|
+
- [25-6-18] Merged changes from @term73, Adding ES Manual Key contest.
|
249
250
|
- [25-6-16] Merged PR from @awandahl SM0HPL, adding ESM buttons to General DX Logging plugin.
|
250
251
|
- [25-6-15] Corrected tab focus of rotator windows buttons.
|
251
252
|
- [25-6-13] Polished up the Rotator window. Adding Stop and Park. Made the NSWE buttons smaller.
|
@@ -40,7 +40,7 @@ not1mm/data/logwindow.ui,sha256=vfkNdzJgFs3tTOBKLDavF2zVMvNHWOZ82fAErRi6pQY,1436
|
|
40
40
|
not1mm/data/logwindowx.ui,sha256=9FzDJtLRpagvAWcDjFdB9NnvNZ4bVxdTNHy1Jit2ido,1610
|
41
41
|
not1mm/data/main.ui,sha256=2cGrhepmcTylTWJ2LwisW6q9nZsReOH38yThvUn_31g,65717
|
42
42
|
not1mm/data/map3.png,sha256=EJqHeFp0ys6Vb1oKkjL4m0v8i3uWXtIgRrxzi0ETUHM,40704
|
43
|
-
not1mm/data/new_contest.ui,sha256=
|
43
|
+
not1mm/data/new_contest.ui,sha256=dobgydE_RBaQ2YGJ_8FGR8NHYteztOsLmdwq4Wfm1HQ,25631
|
44
44
|
not1mm/data/not1mm.html,sha256=c9-mfjMwDt4f5pySUruz2gREW33CQ2_rCddM2z5CZQo,23273
|
45
45
|
not1mm/data/opon.ui,sha256=mC4OhoVIfR1H9IqHAKXliPMm8VOVmxSEadpsFQ7XnS4,2247
|
46
46
|
not1mm/data/pickcontest.ui,sha256=Pbb_YEOzQfacyhIRkx-M3ZGugIIPL1KPztdwVv5c_q0,1696
|
@@ -121,12 +121,12 @@ not1mm/lib/lookup.py,sha256=k-BctngA0QEvMo5cPDB9UkUnQvIk69LnJ8bJek2So4U,11326
|
|
121
121
|
not1mm/lib/multicast.py,sha256=KJcruI-bOuHfHXPjl3SGQhL6I9sKrygy-sdFSvxffUM,3255
|
122
122
|
not1mm/lib/n1mm.py,sha256=H54mpgJF0GAmKavM-nb5OAq2SJFWYkux4eMWWiSRxJc,6288
|
123
123
|
not1mm/lib/new_contest.py,sha256=IznTDMq7yXHB6zBoGUEC_WDYPCPpsSZW4wwMJi16zK0,816
|
124
|
-
not1mm/lib/plugin_common.py,sha256=
|
124
|
+
not1mm/lib/plugin_common.py,sha256=4M5CqBXPVvqiakmCEV_SvcRHAZrlwYgGRZwfxAw2e9U,13951
|
125
125
|
not1mm/lib/rot_interface.py,sha256=bOyxpV9pQHORUY5qfNZE2QAV1V71QEG2jooiI2p9AwE,3744
|
126
126
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
127
127
|
not1mm/lib/settings.py,sha256=5xnsagH48qGeCDhfxPWW9yaXtv8wT13yoIVvYt8h_Qs,16023
|
128
128
|
not1mm/lib/super_check_partial.py,sha256=jX7DjHesEV4KNVQbddJui0wAsYHerikH7W0iPv7PXQw,3110
|
129
|
-
not1mm/lib/version.py,sha256=
|
129
|
+
not1mm/lib/version.py,sha256=6vtRvmqFiXcSqD6LJaNhFmapnntAFFNtZCCGJh245_I,50
|
130
130
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
131
131
|
not1mm/plugins/10_10_fall_cw.py,sha256=oJh3JKqjOpnWElSlZpiQ631UnaOd8qra5s9bl_QoInk,14783
|
132
132
|
not1mm/plugins/10_10_spring_cw.py,sha256=p7dSDtbFK0e6Xouw2V6swYn3VFVgHKyx4IfRWyBjMZY,14786
|
@@ -161,8 +161,9 @@ not1mm/plugins/darc_xmas.py,sha256=p5UNYLdtylsC_sSlxT8NvXXL1oSW0KyUhIN-rJonHgI,1
|
|
161
161
|
not1mm/plugins/ea_majistad_cw.py,sha256=O-GLcW0tMAesw7Ow01M3i6MirbGFXwTcwrY7xJdCYDA,23382
|
162
162
|
not1mm/plugins/ea_majistad_ssb.py,sha256=kZoFknVkslHAEjvleV8shsJEwk12Q3aU6qcmBXzVojo,22976
|
163
163
|
not1mm/plugins/ea_rtty.py,sha256=r6c85eyGHbx_ZLBIqKI96vIMqCGH0KCZq2pd-GQt_Dg,23259
|
164
|
-
not1mm/plugins/es_field_day.py,sha256=
|
165
|
-
not1mm/plugins/
|
164
|
+
not1mm/plugins/es_field_day.py,sha256=SMzkLHRbFqUM3VZ5-8KxqOcakSqlusGnLUhtZ4FXrww,19403
|
165
|
+
not1mm/plugins/es_manual_key.py,sha256=pnc5Wm5xb10ue5rFfBQ4-YDRd-dSnYJ_-aecLxYVobI,21639
|
166
|
+
not1mm/plugins/es_open.py,sha256=SkvweNe0nNoeUFODkC2bwyQMRSm-bK7pidk-6H5C6iY,19089
|
166
167
|
not1mm/plugins/general_logging.py,sha256=qon9snE369TC0DUQYH7dezENQ-vl7BH0j3w_Cb0LyU0,8796
|
167
168
|
not1mm/plugins/helvetia.py,sha256=nvgFjCq-_5XF0cLiCVFFwAS8NtIIFPDptr8eLsoprGE,20082
|
168
169
|
not1mm/plugins/iaru_fieldday_r1_cw.py,sha256=1AVyZFi3ri2zqaNJY181Wtyz74fai8QLoi7PoyXpfaY,17218
|
@@ -190,9 +191,9 @@ not1mm/plugins/ukeidx.py,sha256=ZsIFXgOSwjuKNmN4W_C0TAgGqgnabJGNLMHwGkl3_bk,1910
|
|
190
191
|
not1mm/plugins/vhf_sprint.py,sha256=a9QFTpv8XUbZ_GLjdVCh7svykFa-gXOWwKFZ6MD3uQM,19289
|
191
192
|
not1mm/plugins/weekly_rtty.py,sha256=C8Xs3Q5UgSYx-mFFar8BVARWtmqlyrbeC98Ubzb4UN8,20128
|
192
193
|
not1mm/plugins/winter_field_day.py,sha256=hmAMgkdqIXtnCNyUp8J9Bb8liN8wj10wps6ROuG-Bok,15284
|
193
|
-
not1mm-25.6.18.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
194
|
-
not1mm-25.6.18.dist-info/METADATA,sha256=
|
195
|
-
not1mm-25.6.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
196
|
-
not1mm-25.6.18.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
197
|
-
not1mm-25.6.18.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
198
|
-
not1mm-25.6.18.dist-info/RECORD,,
|
194
|
+
not1mm-25.6.18.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
195
|
+
not1mm-25.6.18.1.dist-info/METADATA,sha256=Siv6s5xx3WIWa4SDjncdlmZmDEsKfOt1QuxpBPM-rT4,36945
|
196
|
+
not1mm-25.6.18.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
197
|
+
not1mm-25.6.18.1.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
198
|
+
not1mm-25.6.18.1.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
199
|
+
not1mm-25.6.18.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|