not1mm 24.12.3.1__py3-none-any.whl → 24.12.5.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/__main__.py +53 -7
- not1mm/data/configuration.ui +70 -0
- not1mm/lib/plugin_common.py +63 -3
- not1mm/lib/settings.py +22 -0
- not1mm/lib/version.py +1 -1
- not1mm/lookupservice.py +2 -2
- not1mm/plugins/arrl_160m.py +98 -14
- not1mm/plugins/cq_ww_cw.py +14 -1
- not1mm/plugins/cwt.py +21 -1
- not1mm/plugins/icwc_mst.py +21 -1
- not1mm/rtc_service.py +80 -0
- {not1mm-24.12.3.1.dist-info → not1mm-24.12.5.1.dist-info}/METADATA +21 -24
- {not1mm-24.12.3.1.dist-info → not1mm-24.12.5.1.dist-info}/RECORD +17 -16
- {not1mm-24.12.3.1.dist-info → not1mm-24.12.5.1.dist-info}/LICENSE +0 -0
- {not1mm-24.12.3.1.dist-info → not1mm-24.12.5.1.dist-info}/WHEEL +0 -0
- {not1mm-24.12.3.1.dist-info → not1mm-24.12.5.1.dist-info}/entry_points.txt +0 -0
- {not1mm-24.12.3.1.dist-info → not1mm-24.12.5.1.dist-info}/top_level.txt +0 -0
not1mm/__main__.py
CHANGED
@@ -77,6 +77,7 @@ from not1mm.vfo import VfoWindow
|
|
77
77
|
from not1mm.radio import Radio
|
78
78
|
from not1mm.voice_keying import Voice
|
79
79
|
from not1mm.lookupservice import LookupService
|
80
|
+
from not1mm.rtc_service import RTCService
|
80
81
|
|
81
82
|
poll_time = datetime.datetime.now()
|
82
83
|
|
@@ -102,6 +103,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
102
103
|
"multicast_group": "239.1.1.1",
|
103
104
|
"multicast_port": 2239,
|
104
105
|
"interface_ip": "0.0.0.0",
|
106
|
+
"send_rtc_scores": False,
|
107
|
+
"rtc_url": "",
|
108
|
+
"rtc_user": "",
|
109
|
+
"rtc_pass": "",
|
110
|
+
"rtc_interval": 2,
|
105
111
|
"send_n1mm_packets": False,
|
106
112
|
"n1mm_station_name": "20M CW Tent",
|
107
113
|
"n1mm_operator": "Bernie",
|
@@ -156,7 +162,6 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
156
162
|
opon_dialog = None
|
157
163
|
dbname = fsutils.USER_DATA_PATH, "/ham.db"
|
158
164
|
radio_state = {}
|
159
|
-
rig_control = None
|
160
165
|
worked_list = {}
|
161
166
|
cw_entry_visible = False
|
162
167
|
last_focus = None
|
@@ -170,6 +175,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
170
175
|
radio_thread = QThread()
|
171
176
|
voice_thread = QThread()
|
172
177
|
fldigi_thread = QThread()
|
178
|
+
rtc_thread = QThread()
|
173
179
|
|
174
180
|
fldigi_watcher = None
|
175
181
|
rig_control = None
|
@@ -179,6 +185,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
179
185
|
vfo_window = None
|
180
186
|
lookup_service = None
|
181
187
|
fldigi_util = None
|
188
|
+
rtc_service = None
|
182
189
|
|
183
190
|
current_widget = None
|
184
191
|
|
@@ -604,7 +611,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
604
611
|
logger.debug(f"{QT_VERSION_STR=} {PYQT_VERSION_STR=}")
|
605
612
|
x = PYQT_VERSION_STR.split(".")
|
606
613
|
old_Qt = True
|
607
|
-
# test if pyqt version is at least 6.
|
614
|
+
# test if pyqt version is at least 6.8
|
608
615
|
if len(x) == 1:
|
609
616
|
if int(x[0]) > 6:
|
610
617
|
old_Qt = False
|
@@ -612,7 +619,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
612
619
|
if int(x[0]) >= 6 and int(x[1]) >= 8:
|
613
620
|
old_Qt = False
|
614
621
|
|
615
|
-
# Featureset for wayland if pyqt is older that 6.
|
622
|
+
# Featureset for wayland if pyqt is older that 6.8
|
616
623
|
dockfeatures = (
|
617
624
|
QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetClosable
|
618
625
|
| QtWidgets.QDockWidget.DockWidgetFeature.DockWidgetMovable
|
@@ -712,7 +719,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
712
719
|
)
|
713
720
|
|
714
721
|
def load_call_history(self) -> None:
|
715
|
-
""""""
|
722
|
+
"""Display filepicker and load chosen call history file."""
|
716
723
|
filename = self.filepicker("other")
|
717
724
|
if filename:
|
718
725
|
self.database.create_callhistory_table()
|
@@ -755,13 +762,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
755
762
|
self.show_message_box(f"{err}")
|
756
763
|
|
757
764
|
def on_focus_changed(self, new):
|
758
|
-
""""""
|
765
|
+
"""Called when text entry focus has changed."""
|
759
766
|
if self.use_esm:
|
760
767
|
if hasattr(self.contest, "process_esm"):
|
761
768
|
self.contest.process_esm(self, new_focused_widget=new)
|
762
769
|
|
763
770
|
def make_button_green(self, the_button: QtWidgets.QPushButton) -> None:
|
764
|
-
"""
|
771
|
+
"""Takes supplied QPushButton object and turns it green."""
|
765
772
|
if the_button is not None:
|
766
773
|
pal = QPalette()
|
767
774
|
pal.isCopyOf(self.current_palette)
|
@@ -1599,6 +1606,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1599
1606
|
self.set_window_title()
|
1600
1607
|
if self.rig_control:
|
1601
1608
|
self.rig_control.set_mode(self.radio_state.get("mode"))
|
1609
|
+
self.update_rtc_xml()
|
1602
1610
|
except ModuleNotFoundError:
|
1603
1611
|
self.pref["contest"] = 1
|
1604
1612
|
self.show_message_box("Contest plugin not found")
|
@@ -2457,7 +2465,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2457
2465
|
self.worked_list = self.database.get_calls_and_bands()
|
2458
2466
|
self.send_worked_list()
|
2459
2467
|
self.clearinputs()
|
2460
|
-
|
2468
|
+
self.update_rtc_xml()
|
2461
2469
|
cmd = {}
|
2462
2470
|
cmd["cmd"] = "UPDATELOG"
|
2463
2471
|
if self.log_window:
|
@@ -2465,6 +2473,17 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2465
2473
|
if self.check_window:
|
2466
2474
|
self.check_window.msg_from_main(cmd)
|
2467
2475
|
|
2476
|
+
def update_rtc_xml(self):
|
2477
|
+
"""Update RTC XML"""
|
2478
|
+
print("update the xml")
|
2479
|
+
if self.pref.get("send_rtc_scores", False):
|
2480
|
+
if self.contest is None:
|
2481
|
+
return
|
2482
|
+
if hasattr(self.contest, "online_score_xml"):
|
2483
|
+
if self.rtc_service is not None:
|
2484
|
+
self.rtc_service.xml = self.contest.online_score_xml(self)
|
2485
|
+
print(f"{self.rtc_service.xml=}")
|
2486
|
+
|
2468
2487
|
def new_contest_dialog(self) -> None:
|
2469
2488
|
"""
|
2470
2489
|
Show new contest dialog.
|
@@ -2898,6 +2917,31 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2898
2917
|
self.setDarkMode(False)
|
2899
2918
|
self.actionDark_Mode_2.setChecked(False)
|
2900
2919
|
|
2920
|
+
try:
|
2921
|
+
if self.rtc_thread.isRunning():
|
2922
|
+
self.rtc_service.time_to_quit = True
|
2923
|
+
self.rtc_thread.quit()
|
2924
|
+
self.rtc_thread.wait(1000)
|
2925
|
+
|
2926
|
+
except (RuntimeError, AttributeError):
|
2927
|
+
...
|
2928
|
+
|
2929
|
+
self.rtc_service = None
|
2930
|
+
|
2931
|
+
self.send_rtc_scores = self.pref.get("send_rtc_scores", False)
|
2932
|
+
self.rtc_url = self.pref.get("rtc_url", "")
|
2933
|
+
self.rtc_user = self.pref.get("rtc_user", "")
|
2934
|
+
self.rtc_pass = self.pref.get("rtc_pass", "")
|
2935
|
+
self.rtc_interval = self.pref.get("rtc_interval", 2)
|
2936
|
+
|
2937
|
+
if self.pref.get("send_rtc_scores", False):
|
2938
|
+
self.rtc_service = RTCService()
|
2939
|
+
self.rtc_service.moveToThread(self.rtc_thread)
|
2940
|
+
self.rtc_thread.started.connect(self.rtc_service.run)
|
2941
|
+
self.rtc_thread.finished.connect(self.rtc_service.deleteLater)
|
2942
|
+
# self.rtc_service.poll_callback.connect(self.rtc_result)
|
2943
|
+
self.rtc_thread.start()
|
2944
|
+
|
2901
2945
|
try:
|
2902
2946
|
if self.radio_thread.isRunning():
|
2903
2947
|
self.rig_control.time_to_quit = True
|
@@ -3046,6 +3090,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
3046
3090
|
self.esm_dict["MYCALL"] = fkey_dict.get(self.pref.get("esm_mycall", "DISABLED"))
|
3047
3091
|
self.esm_dict["QSOB4"] = fkey_dict.get(self.pref.get("esm_qsob4", "DISABLED"))
|
3048
3092
|
|
3093
|
+
self.update_rtc_xml()
|
3094
|
+
|
3049
3095
|
def dark_mode_state_changed(self) -> None:
|
3050
3096
|
"""Called when the Dark Mode menu state is changed."""
|
3051
3097
|
self.pref["darkmode"] = self.actionDark_Mode_2.isChecked()
|
not1mm/data/configuration.ui
CHANGED
@@ -2173,6 +2173,76 @@
|
|
2173
2173
|
</property>
|
2174
2174
|
</widget>
|
2175
2175
|
</item>
|
2176
|
+
<item>
|
2177
|
+
<widget class="Line" name="line">
|
2178
|
+
<property name="orientation">
|
2179
|
+
<enum>Qt::Horizontal</enum>
|
2180
|
+
</property>
|
2181
|
+
</widget>
|
2182
|
+
</item>
|
2183
|
+
<item>
|
2184
|
+
<widget class="QCheckBox" name="send_rtc_scores">
|
2185
|
+
<property name="text">
|
2186
|
+
<string>Use RTC score reporting</string>
|
2187
|
+
</property>
|
2188
|
+
</widget>
|
2189
|
+
</item>
|
2190
|
+
<item>
|
2191
|
+
<widget class="QComboBox" name="rtc_url">
|
2192
|
+
<item>
|
2193
|
+
<property name="text">
|
2194
|
+
<string>https://hamscore.com/postxml/</string>
|
2195
|
+
</property>
|
2196
|
+
</item>
|
2197
|
+
<item>
|
2198
|
+
<property name="text">
|
2199
|
+
<string>https://contestonlinescore.com/post/</string>
|
2200
|
+
</property>
|
2201
|
+
</item>
|
2202
|
+
<item>
|
2203
|
+
<property name="text">
|
2204
|
+
<string>http://contest.run</string>
|
2205
|
+
</property>
|
2206
|
+
</item>
|
2207
|
+
</widget>
|
2208
|
+
</item>
|
2209
|
+
<item>
|
2210
|
+
<widget class="QLineEdit" name="rtc_user">
|
2211
|
+
<property name="placeholderText">
|
2212
|
+
<string>username</string>
|
2213
|
+
</property>
|
2214
|
+
</widget>
|
2215
|
+
</item>
|
2216
|
+
<item>
|
2217
|
+
<widget class="QLineEdit" name="rtc_pass">
|
2218
|
+
<property name="echoMode">
|
2219
|
+
<enum>QLineEdit::EchoMode::Password</enum>
|
2220
|
+
</property>
|
2221
|
+
<property name="placeholderText">
|
2222
|
+
<string>password</string>
|
2223
|
+
</property>
|
2224
|
+
</widget>
|
2225
|
+
</item>
|
2226
|
+
<item>
|
2227
|
+
<widget class="QLabel" name="label_28">
|
2228
|
+
<property name="text">
|
2229
|
+
<string>Score posting interval (minutes)</string>
|
2230
|
+
</property>
|
2231
|
+
<property name="alignment">
|
2232
|
+
<set>Qt::AlignCenter</set>
|
2233
|
+
</property>
|
2234
|
+
</widget>
|
2235
|
+
</item>
|
2236
|
+
<item>
|
2237
|
+
<widget class="QLineEdit" name="rtc_interval">
|
2238
|
+
<property name="text">
|
2239
|
+
<string>2</string>
|
2240
|
+
</property>
|
2241
|
+
<property name="alignment">
|
2242
|
+
<set>Qt::AlignCenter</set>
|
2243
|
+
</property>
|
2244
|
+
</widget>
|
2245
|
+
</item>
|
2176
2246
|
<item>
|
2177
2247
|
<spacer name="verticalSpacer_8">
|
2178
2248
|
<property name="orientation">
|
not1mm/lib/plugin_common.py
CHANGED
@@ -4,6 +4,58 @@ import datetime
|
|
4
4
|
from decimal import Decimal
|
5
5
|
from pathlib import Path
|
6
6
|
from not1mm.lib.ham_utility import get_adif_band
|
7
|
+
from not1mm.lib.version import __version__
|
8
|
+
|
9
|
+
|
10
|
+
def online_score_xml(self):
|
11
|
+
"""generate online xml"""
|
12
|
+
|
13
|
+
mults = self.contest.get_mults(self)
|
14
|
+
the_mults = ""
|
15
|
+
for thing in mults:
|
16
|
+
the_mults += (
|
17
|
+
f'<mult band="total" mode="ALL" type="{thing}">{mults.get(thing,0)}</mult>'
|
18
|
+
)
|
19
|
+
|
20
|
+
the_points = self.contest.just_points(self)
|
21
|
+
|
22
|
+
the_date_time = datetime.datetime.now(datetime.timezone.utc).isoformat(" ")[:19]
|
23
|
+
assisted = self.contest_settings.get("AssistedCategory", "")
|
24
|
+
bands = self.contest_settings.get("BandCategory", "")
|
25
|
+
modes = self.contest_settings.get("ModeCategory", "")
|
26
|
+
xmiter = self.contest_settings.get("TransmitterCategory", "")
|
27
|
+
ops = self.contest_settings.get("OperatorCategory", "")
|
28
|
+
overlay = self.contest_settings.get("OverlayCategory", "")
|
29
|
+
power = self.contest_settings.get("PowerCategory", "")
|
30
|
+
|
31
|
+
the_xml = (
|
32
|
+
'<?xml version="1.0"?>'
|
33
|
+
"<dynamicresults>"
|
34
|
+
f"<contest>{self.contest.cabrillo_name}</contest>"
|
35
|
+
f'<call>{self.station.get("Call", "")}</call>'
|
36
|
+
# <ops>NR9Q</ops>
|
37
|
+
f'<class power="{power}" assisted = "{assisted}" transmitter="{xmiter}" ops="{ops}" bands="{bands}" mode="{modes}" overlay="{overlay}"></class>'
|
38
|
+
f"<club>{self.station.get('Club', '').upper()}</club>"
|
39
|
+
"<soft>Not1MM</soft>"
|
40
|
+
f"<version>{__version__}</version>"
|
41
|
+
"<qth>"
|
42
|
+
# <dxcccountry>K</dxcccountry>
|
43
|
+
f"<cqzone>{self.station.get('CQZone','')}</cqzone>"
|
44
|
+
f"<iaruzone>{self.station.get('IARUZone','')}</iaruzone>"
|
45
|
+
f"<arrlsection>{self.station.get('ARRLSection', '')}</arrlsection>"
|
46
|
+
f"<stprvoth>{self.station.get('State','')}</stprvoth>"
|
47
|
+
f"<grid6>{self.station.get('GridSquare','')}</grid6>"
|
48
|
+
"</qth>"
|
49
|
+
"<breakdown>"
|
50
|
+
f'<qso band="total" mode="ALL">{self.contest.show_qso(self)}</qso>'
|
51
|
+
f"{the_mults}"
|
52
|
+
f'<point band="total" mode="ALL">{the_points}</point>'
|
53
|
+
"</breakdown>"
|
54
|
+
f"<score>{self.contest.calc_score(self)}</score>"
|
55
|
+
f"<timestamp>{the_date_time}</timestamp>"
|
56
|
+
"</dynamicresults>"
|
57
|
+
)
|
58
|
+
return the_xml
|
7
59
|
|
8
60
|
|
9
61
|
def get_points(self):
|
@@ -21,10 +73,9 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
21
73
|
"""
|
22
74
|
now = datetime.datetime.now()
|
23
75
|
date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
|
76
|
+
station_callsign = self.station.get("Call", "").upper()
|
24
77
|
filename = (
|
25
|
-
str(Path.home())
|
26
|
-
+ "/"
|
27
|
-
+ f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.adi"
|
78
|
+
str(Path.home()) + "/" + f"{station_callsign}_{cabrillo_name}_{date_time}.adi"
|
28
79
|
)
|
29
80
|
log = self.database.fetch_all_contacts_asc()
|
30
81
|
try:
|
@@ -71,6 +122,15 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
71
122
|
except TypeError:
|
72
123
|
...
|
73
124
|
|
125
|
+
try:
|
126
|
+
print(
|
127
|
+
f"<STATION_CALLSIGN:{len(station_callsign)}>{station_callsign}",
|
128
|
+
end="\r\n",
|
129
|
+
file=file_descriptor,
|
130
|
+
)
|
131
|
+
except TypeError:
|
132
|
+
...
|
133
|
+
|
74
134
|
try:
|
75
135
|
print(
|
76
136
|
f"<CALL:{len(hiscall)}>{hiscall.upper()}",
|
not1mm/lib/settings.py
CHANGED
@@ -41,6 +41,19 @@ class Settings(QtWidgets.QDialog):
|
|
41
41
|
def setup(self):
|
42
42
|
"""setup dialog"""
|
43
43
|
|
44
|
+
self.send_rtc_scores.setChecked(
|
45
|
+
bool(self.preference.get("send_rtc_scores", False))
|
46
|
+
)
|
47
|
+
|
48
|
+
value = self.preference.get("rtc_url", "")
|
49
|
+
index = self.rtc_url.findText(value)
|
50
|
+
if index != -1:
|
51
|
+
self.rtc_url.setCurrentIndex(index)
|
52
|
+
|
53
|
+
self.rtc_user.setText(str(self.preference.get("rtc_user", "")))
|
54
|
+
self.rtc_pass.setText(str(self.preference.get("rtc_pass", "")))
|
55
|
+
self.rtc_interval.setText(str(self.preference.get("rtc_interval", "2")))
|
56
|
+
|
44
57
|
self.use_call_history.setChecked(
|
45
58
|
bool(self.preference.get("use_call_history", False))
|
46
59
|
)
|
@@ -195,6 +208,15 @@ class Settings(QtWidgets.QDialog):
|
|
195
208
|
"""
|
196
209
|
Write preferences to json file.
|
197
210
|
"""
|
211
|
+
self.preference["send_rtc_scores"] = self.send_rtc_scores.isChecked()
|
212
|
+
self.preference["rtc_url"] = self.rtc_url.currentText()
|
213
|
+
self.preference["rtc_user"] = self.rtc_user.text()
|
214
|
+
self.preference["rtc_pass"] = self.rtc_pass.text()
|
215
|
+
try:
|
216
|
+
self.preference["rtc_interval"] = int(self.rtc_interval.text())
|
217
|
+
except ValueError:
|
218
|
+
self.preference["rtc_interval"] = 2
|
219
|
+
|
198
220
|
self.preference["use_call_history"] = self.use_call_history.isChecked()
|
199
221
|
self.preference["use_esm"] = self.use_esm.isChecked()
|
200
222
|
self.preference["esm_cq"] = self.esm_cq.currentText()
|
not1mm/lib/version.py
CHANGED
not1mm/lookupservice.py
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
not1mm Contest logger
|
4
4
|
Email: michael.bridak@gmail.com
|
5
5
|
GPL V3
|
6
|
-
Class:
|
7
|
-
Purpose:
|
6
|
+
Class: LookupService
|
7
|
+
Purpose: Lookup callsigns with online services.
|
8
8
|
"""
|
9
9
|
|
10
10
|
# pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines
|
not1mm/plugins/arrl_160m.py
CHANGED
@@ -10,7 +10,7 @@ from pathlib import Path
|
|
10
10
|
|
11
11
|
from PyQt6 import QtWidgets
|
12
12
|
|
13
|
-
from not1mm.lib.plugin_common import gen_adif
|
13
|
+
from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
|
14
14
|
from not1mm.lib.version import __version__
|
15
15
|
|
16
16
|
logger = logging.getLogger(__name__)
|
@@ -123,7 +123,48 @@ def points(self):
|
|
123
123
|
|
124
124
|
# Both in same country
|
125
125
|
|
126
|
-
|
126
|
+
# 2.1.1 Alaska (KL7 – AK) and Hawaii (KH6 – PAC), the Caribbean US possessions (KP1-KP5 -
|
127
|
+
# PR or VI), and all of the Pacific Ocean territories (KHØ-KH9 – PAC) participate as W/VE stations
|
128
|
+
# and count as ARRL sections.
|
129
|
+
if mypfx in [
|
130
|
+
"K",
|
131
|
+
"KL",
|
132
|
+
"KH0",
|
133
|
+
"KH1",
|
134
|
+
"KH2",
|
135
|
+
"KH3",
|
136
|
+
"KH4",
|
137
|
+
"KH5",
|
138
|
+
"KH6",
|
139
|
+
"KH7",
|
140
|
+
"KH8",
|
141
|
+
"KH9",
|
142
|
+
"KP1",
|
143
|
+
"KP2",
|
144
|
+
"KP3",
|
145
|
+
"KP4",
|
146
|
+
"KP5",
|
147
|
+
"VE",
|
148
|
+
] and pfx in [
|
149
|
+
"K",
|
150
|
+
"KL",
|
151
|
+
"KH0",
|
152
|
+
"KH1",
|
153
|
+
"KH2",
|
154
|
+
"KH3",
|
155
|
+
"KH4",
|
156
|
+
"KH5",
|
157
|
+
"KH6",
|
158
|
+
"KH7",
|
159
|
+
"KH8",
|
160
|
+
"KH9",
|
161
|
+
"KP1",
|
162
|
+
"KP2",
|
163
|
+
"KP3",
|
164
|
+
"KP4",
|
165
|
+
"KP5",
|
166
|
+
"VE",
|
167
|
+
]:
|
127
168
|
return 2
|
128
169
|
|
129
170
|
if mypfx.upper() != pfx.upper():
|
@@ -134,8 +175,10 @@ def points(self):
|
|
134
175
|
|
135
176
|
def show_mults(self):
|
136
177
|
"""Return display string for mults"""
|
137
|
-
|
138
|
-
|
178
|
+
mults = 0
|
179
|
+
if can_claim_dxcc(self):
|
180
|
+
result = self.database.fetch_country_count()
|
181
|
+
mults = int(result.get("dxcc_count", 0))
|
139
182
|
|
140
183
|
result = self.database.fetch_exchange1_unique_count()
|
141
184
|
mults2 = int(result.get("exch1_count", 0))
|
@@ -153,6 +196,7 @@ def show_qso(self):
|
|
153
196
|
|
154
197
|
def calc_score(self):
|
155
198
|
"""Return calculated score"""
|
199
|
+
mults = 0
|
156
200
|
result = self.database.fetch_points()
|
157
201
|
if result is not None:
|
158
202
|
score = result.get("Points", "0")
|
@@ -160,8 +204,9 @@ def calc_score(self):
|
|
160
204
|
score = "0"
|
161
205
|
contest_points = int(score)
|
162
206
|
|
163
|
-
|
164
|
-
|
207
|
+
if can_claim_dxcc(self):
|
208
|
+
result = self.database.fetch_country_count()
|
209
|
+
mults = int(result.get("dxcc_count", 0))
|
165
210
|
|
166
211
|
result = self.database.fetch_exchange1_unique_count()
|
167
212
|
mults2 = int(result.get("exch1_count", 0))
|
@@ -169,6 +214,37 @@ def calc_score(self):
|
|
169
214
|
return 0
|
170
215
|
|
171
216
|
|
217
|
+
def can_claim_dxcc(self):
|
218
|
+
""""""
|
219
|
+
result = self.cty_lookup(self.station.get("Call", ""))
|
220
|
+
if result:
|
221
|
+
mypfx = ""
|
222
|
+
for item in result.items():
|
223
|
+
mypfx = item[1].get("primary_pfx", "")
|
224
|
+
if mypfx in [
|
225
|
+
"K",
|
226
|
+
"KL",
|
227
|
+
"KH0",
|
228
|
+
"KH1",
|
229
|
+
"KH2",
|
230
|
+
"KH3",
|
231
|
+
"KH4",
|
232
|
+
"KH5",
|
233
|
+
"KH6",
|
234
|
+
"KH7",
|
235
|
+
"KH8",
|
236
|
+
"KH9",
|
237
|
+
"KP1",
|
238
|
+
"KP2",
|
239
|
+
"KP3",
|
240
|
+
"KP4",
|
241
|
+
"KP5",
|
242
|
+
"VE",
|
243
|
+
]:
|
244
|
+
return True
|
245
|
+
return False
|
246
|
+
|
247
|
+
|
172
248
|
def adif(self):
|
173
249
|
"""Call the generate ADIF function"""
|
174
250
|
gen_adif(self, cabrillo_name, "ARRL 160-Meter")
|
@@ -381,14 +457,6 @@ def cabrillo(self, file_encoding):
|
|
381
457
|
return
|
382
458
|
|
383
459
|
|
384
|
-
# def trigger_update(self):
|
385
|
-
# """Triggers the log window to update."""
|
386
|
-
# cmd = {}
|
387
|
-
# cmd["cmd"] = "UPDATELOG"
|
388
|
-
# cmd["station"] = platform.node()
|
389
|
-
# self.multicast_interface.send_as_json(cmd)
|
390
|
-
|
391
|
-
|
392
460
|
def recalculate_mults(self):
|
393
461
|
"""Recalculates multipliers after change in logged qso."""
|
394
462
|
# all_contacts = self.database.fetch_all_contacts_asc()
|
@@ -541,3 +609,19 @@ def check_call_history(self):
|
|
541
609
|
self.history_info.setText(f"{result.get('UserText','')}")
|
542
610
|
if self.other_2.text() == "":
|
543
611
|
self.other_2.setText(f"{result.get('Exch1', '')}")
|
612
|
+
|
613
|
+
|
614
|
+
def get_mults(self):
|
615
|
+
""""""
|
616
|
+
mults = {}
|
617
|
+
if can_claim_dxcc(self):
|
618
|
+
mults["country"] = self.database.fetch_country_count().get("dxcc_count", 0)
|
619
|
+
|
620
|
+
mults["state"] = self.database.fetch_exchange1_unique_count().get("exch1_count", 0)
|
621
|
+
|
622
|
+
return mults
|
623
|
+
|
624
|
+
|
625
|
+
def just_points(self):
|
626
|
+
""""""
|
627
|
+
return self.database.fetch_points().get("Points", "0")
|
not1mm/plugins/cq_ww_cw.py
CHANGED
@@ -43,7 +43,7 @@ from pathlib import Path
|
|
43
43
|
|
44
44
|
from PyQt6 import QtWidgets
|
45
45
|
|
46
|
-
from not1mm.lib.plugin_common import gen_adif, get_points
|
46
|
+
from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
|
47
47
|
from not1mm.lib.version import __version__
|
48
48
|
from not1mm.lib.ham_utility import get_logged_band
|
49
49
|
|
@@ -177,6 +177,19 @@ def points(self):
|
|
177
177
|
return 0
|
178
178
|
|
179
179
|
|
180
|
+
def get_mults(self):
|
181
|
+
""""""
|
182
|
+
mults = {}
|
183
|
+
mults["zone"] = self.database.fetch_zn_band_count().get("zb_count", 0)
|
184
|
+
mults["country"] = self.database.fetch_country_band_count().get("cb_count", 0)
|
185
|
+
return mults
|
186
|
+
|
187
|
+
|
188
|
+
def just_points(self):
|
189
|
+
""""""
|
190
|
+
return self.database.fetch_points().get("Points", "0")
|
191
|
+
|
192
|
+
|
180
193
|
def show_mults(self):
|
181
194
|
"""Return display string for mults"""
|
182
195
|
result1 = self.database.fetch_zn_band_count()
|
not1mm/plugins/cwt.py
CHANGED
@@ -33,7 +33,7 @@ from pathlib import Path
|
|
33
33
|
|
34
34
|
from PyQt6 import QtWidgets
|
35
35
|
|
36
|
-
from not1mm.lib.plugin_common import gen_adif, get_points
|
36
|
+
from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
|
37
37
|
from not1mm.lib.version import __version__
|
38
38
|
|
39
39
|
logger = logging.getLogger(__name__)
|
@@ -519,3 +519,23 @@ def check_call_history(self):
|
|
519
519
|
self.other_1.setText(f"{result.get('Name', '')}")
|
520
520
|
if self.other_2.text() == "":
|
521
521
|
self.other_2.setText(f"{result.get('Exch1', '')}")
|
522
|
+
|
523
|
+
|
524
|
+
# --------RTC Stuff-----------
|
525
|
+
def get_mults(self):
|
526
|
+
""""""
|
527
|
+
|
528
|
+
mults = {}
|
529
|
+
mults["state"] = show_mults(self)
|
530
|
+
return mults
|
531
|
+
|
532
|
+
|
533
|
+
def just_points(self):
|
534
|
+
""""""
|
535
|
+
result = self.database.fetch_points()
|
536
|
+
if result is not None:
|
537
|
+
score = result.get("Points", "0")
|
538
|
+
if score is None:
|
539
|
+
score = "0"
|
540
|
+
return int(score)
|
541
|
+
return 0
|
not1mm/plugins/icwc_mst.py
CHANGED
@@ -34,7 +34,7 @@ from pathlib import Path
|
|
34
34
|
|
35
35
|
from PyQt6 import QtWidgets
|
36
36
|
|
37
|
-
from not1mm.lib.plugin_common import gen_adif, get_points
|
37
|
+
from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
|
38
38
|
from not1mm.lib.version import __version__
|
39
39
|
|
40
40
|
logger = logging.getLogger(__name__)
|
@@ -493,3 +493,23 @@ def check_call_history(self):
|
|
493
493
|
self.history_info.setText(f"{result.get('UserText','')}")
|
494
494
|
if self.other_2.text() == "":
|
495
495
|
self.other_2.setText(f"{result.get('Name', '')}")
|
496
|
+
|
497
|
+
|
498
|
+
# --------RTC Stuff-----------
|
499
|
+
def get_mults(self):
|
500
|
+
""""""
|
501
|
+
|
502
|
+
mults = {}
|
503
|
+
mults["state"] = show_mults(self)
|
504
|
+
return mults
|
505
|
+
|
506
|
+
|
507
|
+
def just_points(self):
|
508
|
+
""""""
|
509
|
+
result = self.database.fetch_points()
|
510
|
+
if result is not None:
|
511
|
+
score = result.get("Points", "0")
|
512
|
+
if score is None:
|
513
|
+
score = "0"
|
514
|
+
return int(score)
|
515
|
+
return 0
|
not1mm/rtc_service.py
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
not1mm Contest logger
|
4
|
+
Email: michael.bridak@gmail.com
|
5
|
+
GPL V3
|
6
|
+
Class: RTCService
|
7
|
+
Purpose: Service to post 'real time' scores.
|
8
|
+
"""
|
9
|
+
|
10
|
+
# pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines
|
11
|
+
# pylint: disable=logging-fstring-interpolation, line-too-long, no-name-in-module
|
12
|
+
|
13
|
+
import datetime
|
14
|
+
import logging
|
15
|
+
import os
|
16
|
+
from json import loads
|
17
|
+
|
18
|
+
import requests
|
19
|
+
from requests.auth import HTTPBasicAuth
|
20
|
+
|
21
|
+
from PyQt6.QtCore import QObject, pyqtSignal, QThread, QEventLoop
|
22
|
+
|
23
|
+
import not1mm.fsutils as fsutils
|
24
|
+
|
25
|
+
logger = logging.getLogger(__name__)
|
26
|
+
|
27
|
+
|
28
|
+
class RTCService(QObject):
|
29
|
+
"""The RTC Service class."""
|
30
|
+
|
31
|
+
poll_callback = pyqtSignal(dict)
|
32
|
+
delta = 2 # two minutes
|
33
|
+
poll_time = datetime.datetime.now() + datetime.timedelta(minutes=delta)
|
34
|
+
time_to_quit = False
|
35
|
+
xml = ""
|
36
|
+
|
37
|
+
def __init__(self):
|
38
|
+
super().__init__()
|
39
|
+
self.pref = self.get_settings()
|
40
|
+
self.delta = self.pref.get("rtc_interval", 2)
|
41
|
+
|
42
|
+
def run(self) -> None:
|
43
|
+
"""Send score xml object to rtc scoring site."""
|
44
|
+
while not self.time_to_quit:
|
45
|
+
# if self.pref.get("send_rtc_scores", False) is True:
|
46
|
+
if datetime.datetime.now() > self.poll_time:
|
47
|
+
self.poll_time = datetime.datetime.now() + datetime.timedelta(
|
48
|
+
minutes=self.delta
|
49
|
+
)
|
50
|
+
if len(self.xml):
|
51
|
+
headers = {"Content-Type": "text/xml"}
|
52
|
+
try:
|
53
|
+
result = requests.post(
|
54
|
+
self.pref.get("rtc_url", ""),
|
55
|
+
data=self.xml,
|
56
|
+
headers=headers,
|
57
|
+
auth=HTTPBasicAuth(
|
58
|
+
self.pref.get("rtc_user", ""),
|
59
|
+
self.pref.get("rtc_pass", ""),
|
60
|
+
),
|
61
|
+
timeout=30,
|
62
|
+
)
|
63
|
+
print(f"{self.xml=}\n{result=}\n{result.text}")
|
64
|
+
except requests.exceptions.Timeout:
|
65
|
+
print("RTC post timeout.")
|
66
|
+
except requests.exceptions.RequestException as e:
|
67
|
+
print(f"An RTC post error occurred: {e}")
|
68
|
+
else:
|
69
|
+
print("No XML data")
|
70
|
+
try:
|
71
|
+
self.poll_callback.emit({"success": True})
|
72
|
+
except QEventLoop:
|
73
|
+
...
|
74
|
+
QThread.msleep(1)
|
75
|
+
|
76
|
+
def get_settings(self) -> dict:
|
77
|
+
"""Get the settings."""
|
78
|
+
if os.path.exists(fsutils.CONFIG_FILE):
|
79
|
+
with open(fsutils.CONFIG_FILE, "rt", encoding="utf-8") as file_descriptor:
|
80
|
+
return loads(file_descriptor.read())
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version: 24.12.
|
3
|
+
Version: 24.12.5.1
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
Project-URL: Homepage, https://github.com/mbridak/not1mm
|
@@ -238,6 +238,9 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
238
238
|
|
239
239
|
## Recent Changes (Polishing the Turd)
|
240
240
|
|
241
|
+
-[24-12-5-1] ARRL 160 gets rtc.
|
242
|
+
- [24-12-5] Add 'real time' score posting to external sites.
|
243
|
+
- [24-12-4] Merged PR from @alduhoo Add STATION_CALLSIGN field to ADIF output
|
241
244
|
- [24-12-3-1] Adding ARRL 160
|
242
245
|
- [24-12-3] Add button to bandmap to delete marked spots.
|
243
246
|
|
@@ -532,7 +535,7 @@ You can fill. You can fill. Everyone look at your keys.
|
|
532
535
|
|
533
536
|
### Changing station information
|
534
537
|
|
535
|
-
Station information can be changed any time by going
|
538
|
+
Station information can be changed any time by going to
|
536
539
|
`File` > `Station Settings` and editing the information.
|
537
540
|
|
538
541
|
## Selecting a contest (It's REQUIRED Russ)
|
@@ -585,10 +588,7 @@ onscreen icon for CAT status. Green good, Red bad, Grey neither.
|
|
585
588
|
|
586
589
|
Under the `CW` TAB, There are three options. `cwdaemon`, which normally uses IP
|
587
590
|
`127.0.0.1`port `6789`. `pywinkeyer` which normally uses IP `127.0.0.1` port `8000` and
|
588
|
-
`CAT` which if your radio supports it, sends Morse characters via rigctld.
|
589
|
-
as I can tell rigctld does not support setting the radios internal keyer speed. So
|
590
|
-
the CW speed control widget will not be functional and you'd need to control the
|
591
|
-
keyer speed thru the radios interface.
|
591
|
+
`CAT` which if your radio supports it, sends Morse characters via rigctld.
|
592
592
|
|
593
593
|
### Cluster
|
594
594
|
|
@@ -616,27 +616,22 @@ appear. Those without will not.
|
|
616
616
|
|
617
617
|
### Options
|
618
618
|
|
619
|
-
On the Options TAB you can
|
620
|
-
Select whether or not to use Call History info.
|
619
|
+
On the Options TAB you can:
|
621
620
|
|
622
|
-
|
621
|
+
- Select to use Enter Sends Message (ESM), and configure it's function keys.
|
622
|
+
- Select whether or not to use Call History info.
|
623
|
+
- Select whether or not to send XML score info to online scoreboards.
|
623
624
|
|
624
|
-
|
625
|
-
|
626
|
-
**Digital modes only working for:**
|
625
|
+

|
627
626
|
|
628
|
-
-
|
629
|
-
- ARRL VHF
|
630
|
-
- Weekly RTTY
|
631
|
-
- CQ WW DX RTTY
|
632
|
-
- CQ WPX RTTY
|
627
|
+
## Logging WSJT-X FT8/FT4/ETC and FLDIGI RTTY contacts
|
633
628
|
|
634
629
|
not1mm listens for WSJT-X UDP traffic on the Multicast address 224.0.0.1:2237.
|
635
630
|
No setup is needed to be done on not1mm's side. That's good because I'm lazy.
|
636
631
|
|
637
632
|
not1mm polls for fldigi QSOs via it's XMLRPC interface. It does this in a rather stupid
|
638
633
|
way. It just keeps asking what was the last QSO and compares it to the previous response.
|
639
|
-
If it's different, it's new.
|
634
|
+
If it's different, it's new.
|
640
635
|
|
641
636
|
The F1-F12 function keys be sent to fldigi via XMLRPC. Fldigi will be placed into TX
|
642
637
|
mode, the message will be sent and a ^r will be tacked onto the end to place it back into
|
@@ -649,18 +644,20 @@ Generic Contest. Make sure the Text Capture Order field says CALL EXCHANGE.
|
|
649
644
|
## Sending CW
|
650
645
|
|
651
646
|
Other than sending CW by hand, you can also send predefined CW text messages by
|
652
|
-
pressing F1 - F12. See next section on Editing macro keys.
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
647
|
+
pressing F1 - F12. See next section on Editing macro keys.
|
648
|
+
|
649
|
+
If you need to send something freeform, you can press `CTRL-SHIFT-K`, this will
|
650
|
+
expose an entry field at the bottom of the window which you can type directly into.
|
651
|
+
When you're done you can either press CTRL-SHIFT-K again, or press the Enter Key to
|
652
|
+
close the field.
|
657
653
|
|
658
654
|
## Editing macro keys
|
659
655
|
|
660
656
|
To edit the macros, choose `File` > `Edit Macros`. This will open your systems
|
661
657
|
registered text editor with current macros loaded. When your done just save the
|
662
658
|
file and close the editor. The file loaded to edit, CW, SSB or RTTY, will be
|
663
|
-
determined by your current operating mode.
|
659
|
+
determined by your current operating mode and contest. Each contest gets it's own
|
660
|
+
copy of the macros.
|
664
661
|
|
665
662
|
After editing and saving the macro file. You can force the logger to reload the
|
666
663
|
macro file by toggeling between `Run` and `S&P` states.
|
@@ -1,11 +1,12 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=fiXIUhVXM8mA0_zkr-srDZF-XvvkoFNVZ9LtqF2NYts,144644
|
3
3
|
not1mm/bandmap.py,sha256=zD3aUf36NVQCy0plAcZLNxYhSEM9xZ8J1Cu9vrcFPYA,31136
|
4
4
|
not1mm/checkwindow.py,sha256=VFAcKYTcoWhmIf91chwY6tyao9FQMWPiUkgDDkkWaog,9670
|
5
5
|
not1mm/fsutils.py,sha256=ukHKxKTeNKxKwqRaJjtzRShL4X5Xl0jRBbADyy3Ifp8,1701
|
6
6
|
not1mm/logwindow.py,sha256=TvpzQTNB92hISlUO3iWBqtlPmlebdhOkAArx0DNGcOs,43966
|
7
|
-
not1mm/lookupservice.py,sha256=
|
7
|
+
not1mm/lookupservice.py,sha256=GkY_qHZfrW6XHf8upIoaG4hCFqm0fg6Ganu9ConGrIc,2628
|
8
8
|
not1mm/radio.py,sha256=c4m7Ci38uKGKxB0JUT5uOKalI_Mm8Vmixu5D_roN5z4,5400
|
9
|
+
not1mm/rtc_service.py,sha256=Fu_Ru0GR2wcTfmbnt8cIAC5BJfPQEb4kuSTyQohZoi8,2756
|
9
10
|
not1mm/test.py,sha256=RN71m2S9MPIOJMaoCi0wZhwEhpEZunvtosZxaKahRB4,101
|
10
11
|
not1mm/vfo.py,sha256=ggPyWtxMbdSE5RwdK0nDRwDNqOxdpb_pvnzZdbzZVQE,11136
|
11
12
|
not1mm/voice_keying.py,sha256=sA3gw5_k7kShTg2qhG7HkKDM5M6KheJVRkAc_C7mxDk,3006
|
@@ -16,7 +17,7 @@ not1mm/data/alpha bravo charlie delta.txt,sha256=d5QMmSWEUAe4Rj1XbNjTPLa_5Be4Se6
|
|
16
17
|
not1mm/data/bandmap.ui,sha256=krmUYxGPRt2EeqSGrEkY2cXG79ujel3T2_2ymrrbgzg,7942
|
17
18
|
not1mm/data/check.png,sha256=UvFOLr8V-79qnjW8wUaGItXk_OSP8m8hqPevs8NDlFY,387
|
18
19
|
not1mm/data/checkwindow.ui,sha256=PRD98K0julJ9EfWqoE89dT8UPuPKQzGiWBk_efAko3o,5141
|
19
|
-
not1mm/data/configuration.ui,sha256=
|
20
|
+
not1mm/data/configuration.ui,sha256=VJv_uJp53mPK6YyVXOu0aRRtgrgFvIha_wX_7P4M9t0,72554
|
20
21
|
not1mm/data/contests.sql,sha256=4hmJCDvrbxnA_Y5S4T5o52TZieeFk6QUwFerwlFePNA,89307
|
21
22
|
not1mm/data/cty.json,sha256=dPG9K1Pm4Rxd4uJom_gQ8y-sbqiZfILpl4kBAFnOveU,4877142
|
22
23
|
not1mm/data/cwmacros.txt,sha256=NztufsX6R52gAO7VyJ2AHr7wOh41pJTwHKh5Lcs32ds,468
|
@@ -110,11 +111,11 @@ not1mm/lib/lookup.py,sha256=KECMDi9tflRDzgTLeDfDl7HGWWRHvW3HCjNHyyjoWaY,10835
|
|
110
111
|
not1mm/lib/multicast.py,sha256=KJcruI-bOuHfHXPjl3SGQhL6I9sKrygy-sdFSvxffUM,3255
|
111
112
|
not1mm/lib/n1mm.py,sha256=H54mpgJF0GAmKavM-nb5OAq2SJFWYkux4eMWWiSRxJc,6288
|
112
113
|
not1mm/lib/new_contest.py,sha256=IznTDMq7yXHB6zBoGUEC_WDYPCPpsSZW4wwMJi16zK0,816
|
113
|
-
not1mm/lib/plugin_common.py,sha256=
|
114
|
+
not1mm/lib/plugin_common.py,sha256=gpYDYRu_-w8QiLNXPLjKzE47Fhgv-q7yrLu0-BwEpVY,13141
|
114
115
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
115
|
-
not1mm/lib/settings.py,sha256=
|
116
|
+
not1mm/lib/settings.py,sha256=j5lIMLHJ-eqIaVr_QhI82gkbOl17_C-5suRkWbHYET8,14717
|
116
117
|
not1mm/lib/super_check_partial.py,sha256=hwT2NRwobu0PLDyw6ltmbmcAtGBD02CKGFbgGWjXMqA,2334
|
117
|
-
not1mm/lib/version.py,sha256=
|
118
|
+
not1mm/lib/version.py,sha256=szIJzvfgl4Q3uj53Wst_zg1KvKsYv2FK-7_N6YPVm_o,50
|
118
119
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
119
120
|
not1mm/plugins/10_10_fall_cw.py,sha256=AsvB2VUd6Qb2_FzZkSBkSd1_qeP8Dt-B-exF1Pzb9tk,14469
|
120
121
|
not1mm/plugins/10_10_spring_cw.py,sha256=nA4v0oqlp-ivvKqNPakb19I-wE_ElhvH5bCzDRx00JU,14474
|
@@ -122,7 +123,7 @@ not1mm/plugins/10_10_summer_phone.py,sha256=FNcTQoyZCeAW2i3SKYYDZWuJS1vmk1CO4XO1
|
|
122
123
|
not1mm/plugins/10_10_winter_phone.py,sha256=NRAKgu4oYzrpUtjUKWgCfZQf3b85sdVe9oyl-yD6kJo,14486
|
123
124
|
not1mm/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
124
125
|
not1mm/plugins/arrl_10m.py,sha256=-stuBD3DCdlWctxE9bWEeznZrgIfNw7VcMIE1ZmsfMo,17942
|
125
|
-
not1mm/plugins/arrl_160m.py,sha256=
|
126
|
+
not1mm/plugins/arrl_160m.py,sha256=idirBXY1XmzxdEyuodGUBsDwLN7JaNtpdix9f3lceRQ,20127
|
126
127
|
not1mm/plugins/arrl_dx_cw.py,sha256=1epTIf9TjeUCjYlpRDU54Ig3lJdXa2e5JZI9SCGE080,17400
|
127
128
|
not1mm/plugins/arrl_dx_ssb.py,sha256=IEZ6tlP9stW3Mdr5_qTBS77hjAUU43IpagyPjr0eqaQ,17403
|
128
129
|
not1mm/plugins/arrl_field_day.py,sha256=YEyXr1Ytllq12sCj54erOba0wrblwb0_bq51gj75OIQ,16478
|
@@ -138,17 +139,17 @@ not1mm/plugins/cq_160_ssb.py,sha256=_0bkvq0KvSdyTBhkqJ35VqXuaWIaDNmBGE1aQ-cxQz8,
|
|
138
139
|
not1mm/plugins/cq_wpx_cw.py,sha256=H1H4xL-hx0sqU_8fSQYnNzO0ZcOLV-KSOQT9wPvIva0,17843
|
139
140
|
not1mm/plugins/cq_wpx_rtty.py,sha256=nT2lMdAM1pRu2jNKI4FpkGei9kEGX0XcF_24FkL0lnY,20662
|
140
141
|
not1mm/plugins/cq_wpx_ssb.py,sha256=Zjga12w_ISh4aZjCYZbpwN0x0032Prc8p7aIGI7HJFQ,16410
|
141
|
-
not1mm/plugins/cq_ww_cw.py,sha256=
|
142
|
+
not1mm/plugins/cq_ww_cw.py,sha256=53N-q1mTKF4-GH-cyh-a43b4BQ2TP_PNsWWpZchxieI,18230
|
142
143
|
not1mm/plugins/cq_ww_rtty.py,sha256=Pfpr8xWJwp2NOci-WQMTUZaMpAtsUGq1jrIIUv6lQ2Y,21971
|
143
144
|
not1mm/plugins/cq_ww_ssb.py,sha256=IyPmEImq_eb5YSFuhHxiJU4EFAPB4D5dg2xED6Nu97k,17491
|
144
|
-
not1mm/plugins/cwt.py,sha256=
|
145
|
+
not1mm/plugins/cwt.py,sha256=WlZu8urd0J_4sEOKtgf-GrgHPukYT2E13GRXal8i794,17424
|
145
146
|
not1mm/plugins/darc_xmas.py,sha256=GdtAQVCLogKGzZaexJfzsZms5SbLLlO1YweFPjgvYWw,18458
|
146
147
|
not1mm/plugins/general_logging.py,sha256=NV_FCgpAEEQrVRxMDD7nQ2krJgPrhtopizxrGndtUNk,6686
|
147
148
|
not1mm/plugins/helvetia.py,sha256=SRKn7jflfYPUNrvmErDM44af5YWUe57h7JkIwFSbT0Q,19609
|
148
149
|
not1mm/plugins/iaru_fieldday_r1_cw.py,sha256=oWeFuKxvY15vRiUh2vW3z3o7mxJMae7vfpKx4OFU_yA,16816
|
149
150
|
not1mm/plugins/iaru_fieldday_r1_ssb.py,sha256=HylTAcNs0DSii5EDzMQlocjs4k7rQ579YvLrwn6sqIQ,16821
|
150
151
|
not1mm/plugins/iaru_hf.py,sha256=RcVf0UFaHX0eSpUZMMGHC0HTsOy_SwTH9Yi9SeJNQUA,15715
|
151
|
-
not1mm/plugins/icwc_mst.py,sha256=
|
152
|
+
not1mm/plugins/icwc_mst.py,sha256=iFV7iHdI8BLnag-gkQ2q0S4h9n7jXoZ0oTJxtTG14OU,16366
|
152
153
|
not1mm/plugins/jidx_cw.py,sha256=KJOE3fU0KVMqD5IqvnN3YDHPEwrMx3yJZBmCtAIP7WQ,15650
|
153
154
|
not1mm/plugins/jidx_ph.py,sha256=1l92EmDZJFRGZjR1VrISgFc8KoHVfmJvLsaVsuufIMs,14599
|
154
155
|
not1mm/plugins/k1usn_sst.py,sha256=71uO6nUf86J77qSQIiYl_H9EKa2iwyHijcMOk61q6uQ,16653
|
@@ -163,9 +164,9 @@ not1mm/plugins/ref_ssb.py,sha256=G2Gz4kApchmOZQVnBexEokSEvdb-mZWJAfyJ1D6JDGY,204
|
|
163
164
|
not1mm/plugins/stew_perry_topband.py,sha256=Gy_vv6tgkR-3vmvsUVO0pVfHMkUJSxpt7G4secn0RH8,15084
|
164
165
|
not1mm/plugins/weekly_rtty.py,sha256=PI0_AtEdZZKGAuKnP-b2EYn9xwCN1Ablk38trbNP3Rc,19603
|
165
166
|
not1mm/plugins/winter_field_day.py,sha256=9w3tDL9ZWiENSTERc3vzDbBktvI7pnyNvlH6fDjAi08,14841
|
166
|
-
not1mm-24.12.
|
167
|
-
not1mm-24.12.
|
168
|
-
not1mm-24.12.
|
169
|
-
not1mm-24.12.
|
170
|
-
not1mm-24.12.
|
171
|
-
not1mm-24.12.
|
167
|
+
not1mm-24.12.5.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
168
|
+
not1mm-24.12.5.1.dist-info/METADATA,sha256=tYCfOzNbIMOj91v3fsxr2pXNmOFtxfXN55CYFcKjGdc,35613
|
169
|
+
not1mm-24.12.5.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
170
|
+
not1mm-24.12.5.1.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
171
|
+
not1mm-24.12.5.1.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
172
|
+
not1mm-24.12.5.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|