not1mm 25.1.6__py3-none-any.whl → 25.1.23__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 +32 -0
- not1mm/data/main.ui +14 -0
- not1mm/data/ratewindow.ui +1185 -0
- not1mm/lib/database.py +4 -0
- not1mm/lib/plugin_common.py +1 -1
- not1mm/lib/version.py +1 -1
- not1mm/plugins/winter_field_day.py +2 -0
- not1mm/ratewindow.py +263 -0
- {not1mm-25.1.6.dist-info → not1mm-25.1.23.dist-info}/METADATA +22 -21
- {not1mm-25.1.6.dist-info → not1mm-25.1.23.dist-info}/RECORD +14 -12
- {not1mm-25.1.6.dist-info → not1mm-25.1.23.dist-info}/WHEEL +1 -1
- {not1mm-25.1.6.dist-info → not1mm-25.1.23.dist-info}/LICENSE +0 -0
- {not1mm-25.1.6.dist-info → not1mm-25.1.23.dist-info}/entry_points.txt +0 -0
- {not1mm-25.1.6.dist-info → not1mm-25.1.23.dist-info}/top_level.txt +0 -0
not1mm/lib/database.py
CHANGED
@@ -179,6 +179,7 @@ class DataBase:
|
|
179
179
|
");"
|
180
180
|
)
|
181
181
|
cursor.execute(sql_command)
|
182
|
+
cursor.execute("PRAGMA journal_mode=WAL")
|
182
183
|
conn.commit()
|
183
184
|
except sqlite3.OperationalError as exception:
|
184
185
|
logger.debug("%s", exception)
|
@@ -222,6 +223,7 @@ class DataBase:
|
|
222
223
|
");"
|
223
224
|
)
|
224
225
|
cursor.execute(sql_command)
|
226
|
+
cursor.execute("PRAGMA journal_mode=WAL")
|
225
227
|
conn.commit()
|
226
228
|
|
227
229
|
sql_command = "select * from Contest;"
|
@@ -271,6 +273,7 @@ class DataBase:
|
|
271
273
|
"TimeCategory NVARCHAR(20));"
|
272
274
|
)
|
273
275
|
cursor.execute(sql_command)
|
276
|
+
cursor.execute("PRAGMA journal_mode=WAL")
|
274
277
|
conn.commit()
|
275
278
|
except sqlite3.OperationalError as exception:
|
276
279
|
logger.debug("%s", exception)
|
@@ -310,6 +313,7 @@ class DataBase:
|
|
310
313
|
"PRIMARY KEY([Call]));"
|
311
314
|
)
|
312
315
|
cursor.execute(sql_command)
|
316
|
+
cursor.execute("PRAGMA journal_mode=WAL")
|
313
317
|
conn.commit()
|
314
318
|
except sqlite3.OperationalError as exception:
|
315
319
|
logger.debug("%s", exception)
|
not1mm/lib/plugin_common.py
CHANGED
@@ -89,7 +89,7 @@ def gen_adif(self, cabrillo_name: str, contest_id=""):
|
|
89
89
|
hisname = contact.get("Name", "")
|
90
90
|
the_date_and_time = contact.get("TS", "")
|
91
91
|
themode = contact.get("Mode", "")
|
92
|
-
if themode
|
92
|
+
if themode in ("CWR", "CW-R"):
|
93
93
|
themode = "CW"
|
94
94
|
if cabrillo_name in ("CQ-WW-RTTY", "WEEKLY-RTTY"):
|
95
95
|
themode = "RTTY"
|
not1mm/lib/version.py
CHANGED
@@ -330,6 +330,8 @@ def cabrillo(self, file_encoding):
|
|
330
330
|
themode = contact.get("Mode", "")
|
331
331
|
if themode == "LSB" or themode == "USB":
|
332
332
|
themode = "PH"
|
333
|
+
if themode == "RTTY":
|
334
|
+
themode = "DG"
|
333
335
|
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
334
336
|
|
335
337
|
loggeddate = the_date_and_time[:10]
|
not1mm/ratewindow.py
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
not1mm Contest logger
|
4
|
+
Email: michael.bridak@gmail.com
|
5
|
+
GPL V3
|
6
|
+
Class: RateWindow
|
7
|
+
Purpose: not sure yet
|
8
|
+
"""
|
9
|
+
# pylint: disable=no-name-in-module, unused-import, no-member, invalid-name, c-extension-no-member
|
10
|
+
# pylint: disable=logging-fstring-interpolation, line-too-long
|
11
|
+
|
12
|
+
import datetime
|
13
|
+
import time
|
14
|
+
import logging
|
15
|
+
import os
|
16
|
+
|
17
|
+
from PyQt6 import uic
|
18
|
+
from PyQt6.QtWidgets import QLabel, QWidget, QDockWidget
|
19
|
+
from PyQt6.QtGui import QMouseEvent, QColorConstants, QPalette, QColor
|
20
|
+
from PyQt6.QtCore import pyqtSignal, QTimer
|
21
|
+
|
22
|
+
import not1mm.fsutils as fsutils
|
23
|
+
from not1mm.lib.database import DataBase
|
24
|
+
|
25
|
+
from json import loads
|
26
|
+
from json.decoder import JSONDecodeError
|
27
|
+
from pathlib import Path
|
28
|
+
|
29
|
+
logger = logging.getLogger(__name__)
|
30
|
+
|
31
|
+
|
32
|
+
class RateWindow(QDockWidget):
|
33
|
+
"""The rate window. Shows something important."""
|
34
|
+
|
35
|
+
message = pyqtSignal(dict)
|
36
|
+
dbname = None
|
37
|
+
pref = {}
|
38
|
+
poll_time = datetime.datetime.now() + datetime.timedelta(milliseconds=1000)
|
39
|
+
|
40
|
+
def __init__(self):
|
41
|
+
super().__init__()
|
42
|
+
self.active = False
|
43
|
+
self.load_pref()
|
44
|
+
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
45
|
+
"current_database", "ham.db"
|
46
|
+
)
|
47
|
+
self.database = DataBase(self.dbname, fsutils.APP_DATA_PATH)
|
48
|
+
self.database.current_contest = self.pref.get("contest", 0)
|
49
|
+
|
50
|
+
uic.loadUi(fsutils.APP_DATA_PATH / "ratewindow.ui", self)
|
51
|
+
self.hide_unused()
|
52
|
+
self.timer = QTimer()
|
53
|
+
self.timer.timeout.connect(self.get_run_and_total_qs)
|
54
|
+
self.timer.start(1000)
|
55
|
+
|
56
|
+
def msg_from_main(self, packet):
|
57
|
+
""""""
|
58
|
+
if packet.get("cmd", "") == "DARKMODE":
|
59
|
+
self.setDarkMode(packet.get("state", False))
|
60
|
+
return
|
61
|
+
|
62
|
+
if self.active is False:
|
63
|
+
return
|
64
|
+
|
65
|
+
if packet.get("cmd", "") == "NEWDB":
|
66
|
+
...
|
67
|
+
# self.load_new_db()
|
68
|
+
|
69
|
+
def setActive(self, mode: bool):
|
70
|
+
self.active = bool(mode)
|
71
|
+
|
72
|
+
def setDarkMode(self, dark: bool) -> None:
|
73
|
+
"""Forces a darkmode palette."""
|
74
|
+
|
75
|
+
if dark:
|
76
|
+
darkPalette = QPalette()
|
77
|
+
darkColor = QColor(56, 56, 56)
|
78
|
+
disabledColor = QColor(127, 127, 127)
|
79
|
+
darkPalette.setColor(QPalette.ColorRole.Window, darkColor)
|
80
|
+
darkPalette.setColor(QPalette.ColorRole.WindowText, QColorConstants.White)
|
81
|
+
darkPalette.setColor(QPalette.ColorRole.Base, QColor(45, 45, 45))
|
82
|
+
darkPalette.setColor(QPalette.ColorRole.AlternateBase, darkColor)
|
83
|
+
darkPalette.setColor(QPalette.ColorRole.Text, QColorConstants.White)
|
84
|
+
darkPalette.setColor(QPalette.ColorRole.Button, darkColor)
|
85
|
+
darkPalette.setColor(QPalette.ColorRole.ButtonText, QColorConstants.White)
|
86
|
+
darkPalette.setColor(QPalette.ColorRole.BrightText, QColorConstants.Red)
|
87
|
+
darkPalette.setColor(QPalette.ColorRole.Link, QColor(42, 130, 218))
|
88
|
+
darkPalette.setColor(QPalette.ColorRole.Highlight, QColor(42, 130, 218))
|
89
|
+
darkPalette.setColor(
|
90
|
+
QPalette.ColorRole.HighlightedText, QColorConstants.Black
|
91
|
+
)
|
92
|
+
darkPalette.setColor(
|
93
|
+
QPalette.ColorGroup.Disabled,
|
94
|
+
QPalette.ColorRole.ButtonText,
|
95
|
+
disabledColor,
|
96
|
+
)
|
97
|
+
darkPalette.setColor(
|
98
|
+
QPalette.ColorGroup.Disabled,
|
99
|
+
QPalette.ColorRole.HighlightedText,
|
100
|
+
disabledColor,
|
101
|
+
)
|
102
|
+
darkPalette.setColor(
|
103
|
+
QPalette.ColorGroup.Disabled,
|
104
|
+
QPalette.ColorRole.Text,
|
105
|
+
disabledColor,
|
106
|
+
)
|
107
|
+
|
108
|
+
self.setPalette(darkPalette)
|
109
|
+
else:
|
110
|
+
palette = self.style().standardPalette()
|
111
|
+
self.setPalette(palette)
|
112
|
+
|
113
|
+
def load_pref(self) -> None:
|
114
|
+
"""
|
115
|
+
Load preference file to get current db filename and sets the initial darkmode state.
|
116
|
+
|
117
|
+
Parameters
|
118
|
+
----------
|
119
|
+
None
|
120
|
+
|
121
|
+
Returns
|
122
|
+
-------
|
123
|
+
None
|
124
|
+
"""
|
125
|
+
try:
|
126
|
+
if os.path.exists(fsutils.CONFIG_FILE):
|
127
|
+
with open(
|
128
|
+
fsutils.CONFIG_FILE, "rt", encoding="utf-8"
|
129
|
+
) as file_descriptor:
|
130
|
+
self.pref = loads(file_descriptor.read())
|
131
|
+
logger.info(f"loaded config file from {fsutils.CONFIG_FILE}")
|
132
|
+
else:
|
133
|
+
self.pref["current_database"] = "ham.db"
|
134
|
+
|
135
|
+
except (IOError, JSONDecodeError) as exception:
|
136
|
+
logger.critical("Error: %s", exception)
|
137
|
+
self.setDarkMode(self.pref.get("darkmode", False))
|
138
|
+
|
139
|
+
def get_run_and_total_qs(self):
|
140
|
+
"""get numbers"""
|
141
|
+
|
142
|
+
# last_hour
|
143
|
+
# 10_last_qso
|
144
|
+
# hundred_last_qso
|
145
|
+
# since_lasthour_label since_lasthour
|
146
|
+
# --------------------
|
147
|
+
# time_on
|
148
|
+
# time_off
|
149
|
+
# --------------------
|
150
|
+
# run_qso
|
151
|
+
# sandp_qso
|
152
|
+
# hour_run_qso
|
153
|
+
# hour_sandp_qso
|
154
|
+
# --------------------
|
155
|
+
# avg_km
|
156
|
+
# avg_pts
|
157
|
+
# --------------------
|
158
|
+
# time_by_mult
|
159
|
+
# qso_counts
|
160
|
+
# mult_counts
|
161
|
+
# mult_worth
|
162
|
+
# {'runs': 3, 'totalqs': 3}
|
163
|
+
|
164
|
+
# WHERE datetime(timestamp) > datetime(current_timestamp, '-60 minutes')
|
165
|
+
|
166
|
+
if not self.active:
|
167
|
+
return
|
168
|
+
|
169
|
+
# Get Q's in the 60 Minutes
|
170
|
+
query = f"select (julianday(MAX(ts)) - julianday(MIN(ts))) * 24 * 60 as timespan, count(*) as items from (select * from dxlog where ContestNR = {self.database.current_contest} and datetime(TS) > datetime(current_timestamp, '-60 minutes'));"
|
171
|
+
result = self.database.exec_sql(query)
|
172
|
+
|
173
|
+
if result.get("items", 0) < 1:
|
174
|
+
self.last_hour.setText("--- Q/h")
|
175
|
+
else:
|
176
|
+
try:
|
177
|
+
perhour = (60.0 / result.get("timespan", 60)) * result.get("items", 0)
|
178
|
+
self.last_hour.setText(str(f"{perhour:.2f} Q/h"))
|
179
|
+
except (ZeroDivisionError, TypeError):
|
180
|
+
...
|
181
|
+
|
182
|
+
# Get Q's per hour rate of the last 10 QSO's
|
183
|
+
query = f"SELECT (julianday(MAX(ts)) - julianday(MIN(ts))) * 24 * 60 as timespan, count(*) as items FROM ( select * from DXLOG where ContestNR = {self.database.current_contest} ORDER by ts DESC limit 10);"
|
184
|
+
result = self.database.exec_sql(query)
|
185
|
+
if result.get("items", 0) < 10:
|
186
|
+
self.ten_last_qso.setText("--- Q/h")
|
187
|
+
else:
|
188
|
+
try:
|
189
|
+
perhour = (60.0 / result.get("timespan", 60)) * result.get("items", 0)
|
190
|
+
self.ten_last_qso.setText(str(f"{perhour:.2f} Q/h"))
|
191
|
+
except (ZeroDivisionError, TypeError):
|
192
|
+
...
|
193
|
+
|
194
|
+
# Get Q's per hour rate of the last 100 QSO's
|
195
|
+
query = f"SELECT (julianday(MAX(ts)) - julianday(MIN(ts))) * 24 * 60 as timespan, count(*) as items FROM (select * from DXLOG where ContestNR = {self.database.current_contest} ORDER by ts DESC limit 100);"
|
196
|
+
result = self.database.exec_sql(query)
|
197
|
+
if result.get("items", 0) < 100:
|
198
|
+
self.hundred_last_qso.setText("--- Q/h")
|
199
|
+
else:
|
200
|
+
try:
|
201
|
+
perhour = (60.0 / result.get("timespan", 60)) * result.get("items", 0)
|
202
|
+
self.hundred_last_qso.setText(str(f"{perhour:.2f} Q/h"))
|
203
|
+
except (ZeroDivisionError, TypeError):
|
204
|
+
...
|
205
|
+
|
206
|
+
# Get rate for the current hour
|
207
|
+
query = f"SELECT strftime('%Y-%m-%d %H:00:00','now') as limit_stamp, strftime('%H:00:00','now') as current_hour, count(*) as items FROM DXLOG where ContestNR = {self.database.current_contest} and datetime(TS) > limit_stamp;"
|
208
|
+
result = self.database.exec_sql(query)
|
209
|
+
|
210
|
+
self.since_lasthour_label.setText(
|
211
|
+
f"Since {result.get('current_hour', '00:00:00')}z:"
|
212
|
+
)
|
213
|
+
self.since_lasthour.setText(f"{result.get('items', '0')} QSO")
|
214
|
+
|
215
|
+
# Get Run QSO's and S&P QSO's
|
216
|
+
query = f"select sum(IsRunQSO) as runs, count(*) as totalqs from dxlog where ContestNR = {self.database.current_contest};"
|
217
|
+
result = self.database.exec_sql(query)
|
218
|
+
try:
|
219
|
+
sandp = result.get("totalqs", 0) - result.get("runs", 0)
|
220
|
+
self.run_qso.setText(f"{result.get("runs", 0)}")
|
221
|
+
self.sandp_qso.setText(f"{sandp}")
|
222
|
+
self.qso_counts.setText(f"{result.get("totalqs", 0)} pts")
|
223
|
+
except TypeError:
|
224
|
+
...
|
225
|
+
|
226
|
+
# Get runs for the current hour
|
227
|
+
query = f"SELECT strftime('%Y-%m-%d %H:00:00','now') as limit_stamp, sum(IsRunQSO) as runs, count(*) as totalqs FROM DXLOG where ContestNR = {self.database.current_contest} and datetime(TS) > limit_stamp;"
|
228
|
+
result = self.database.exec_sql(query)
|
229
|
+
try:
|
230
|
+
sandp = result.get("totalqs", 0) - result.get("runs", 0)
|
231
|
+
self.hour_run_qso.setText(f"{result.get("runs", 0)}")
|
232
|
+
self.hour_sandp_qso.setText(f"{sandp}")
|
233
|
+
except TypeError:
|
234
|
+
...
|
235
|
+
|
236
|
+
def hide_unused(self):
|
237
|
+
self.line.hide()
|
238
|
+
self.label_10.hide()
|
239
|
+
self.time_on.hide()
|
240
|
+
self.label_12.hide()
|
241
|
+
self.time_off.hide()
|
242
|
+
|
243
|
+
self.band_mode.hide()
|
244
|
+
self.label_23.hide()
|
245
|
+
self.avg_km.hide()
|
246
|
+
self.label_25.hide()
|
247
|
+
self.avg_pts.hide()
|
248
|
+
self.best_dx.hide()
|
249
|
+
self.label_26.hide()
|
250
|
+
|
251
|
+
self.line_5.hide()
|
252
|
+
self.label_29.hide()
|
253
|
+
self.label_30.hide()
|
254
|
+
self.time_by_mult.hide()
|
255
|
+
self.label_32.hide()
|
256
|
+
self.qso_counts.hide()
|
257
|
+
self.label_34.hide()
|
258
|
+
self.mult_counts.hide()
|
259
|
+
self.label_35.hide()
|
260
|
+
self.mult_worth.hide()
|
261
|
+
|
262
|
+
self.line_6.hide()
|
263
|
+
self.label_38.hide()
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.1.
|
3
|
+
Version: 25.1.23
|
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
|
@@ -51,7 +51,6 @@ Requires-Dist: Levenshtein
|
|
51
51
|
- [The What](#the-what)
|
52
52
|
- [Target Environment](#target-environment)
|
53
53
|
- [The Why](#the-why)
|
54
|
-
- [General logging](#general-logging)
|
55
54
|
- [Current state](#current-state)
|
56
55
|
- [Code maturity](#code-maturity)
|
57
56
|
- [Data and RTTY](#data-and-rtty)
|
@@ -115,6 +114,7 @@ Requires-Dist: Levenshtein
|
|
115
114
|
- [Editing a contact](#editing-a-contact)
|
116
115
|
- [The Bandmap Window](#the-bandmap-window)
|
117
116
|
- [The Check Window](#the-check-window)
|
117
|
+
- [The Rate Window](#the-rate-window)
|
118
118
|
- [The Remote VFO Window](#the-remote-vfo-window)
|
119
119
|
- [Cabrillo](#cabrillo)
|
120
120
|
- [ADIF](#adif)
|
@@ -164,11 +164,6 @@ I'm a casual contester and could not find any contesting software for Linux that
|
|
164
164
|
I wanted to use. There is [Tucnak](http://tucnak.nagano.cz/) which is very robust
|
165
165
|
and mature. It just wasn't for me.
|
166
166
|
|
167
|
-
### General logging
|
168
|
-
|
169
|
-
In short... Don't. There are much better general purpose QSO logging programs.
|
170
|
-
Try QLog or CQRLog.
|
171
|
-
|
172
167
|
## Current state
|
173
168
|
|
174
169
|
### Code maturity
|
@@ -240,6 +235,8 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
240
235
|
|
241
236
|
## Recent Changes (Polishing the Turd)
|
242
237
|
|
238
|
+
- [25-1-23] Added a basic rate window. Changed DB to WAL mode.
|
239
|
+
- [25-1-15] Fix bug in ADIF output where mode showed as CW-R and not CW.
|
243
240
|
- [25-1-6] Altered RTTY RU UDP ADIF parse.
|
244
241
|
- [25-1-1] Added ARRL RTTY RU.
|
245
242
|
|
@@ -247,7 +244,7 @@ See [CHANGELOG.md](CHANGELOG.md) for prior changes.
|
|
247
244
|
|
248
245
|
## Flatpak
|
249
246
|
|
250
|
-
I've tried for a couple days to get
|
247
|
+
I've tried for a couple days to get Not1MM to build as a flatpak. I've failed.
|
251
248
|
It keeps failing at building numpy. If you happen to be a flatpak savant, please
|
252
249
|
feel free to look at com.github.mbridak.not1mm.yaml and python3-modules.yaml and
|
253
250
|
clue me into the black magic needed to get it to work.
|
@@ -256,7 +253,7 @@ clue me into the black magic needed to get it to work.
|
|
256
253
|
|
257
254
|
### Prerequisites
|
258
255
|
|
259
|
-
|
256
|
+
Not1MM requires:
|
260
257
|
|
261
258
|
- Python 3.9+
|
262
259
|
- PyQt6
|
@@ -268,7 +265,7 @@ You should install these through your distribution's package manager before cont
|
|
268
265
|
### Common installation recipes for Ubuntu and Fedora
|
269
266
|
|
270
267
|
I've taken the time to install some common Linux distributions into a VM and
|
271
|
-
noted the minimum steps needed to install
|
268
|
+
noted the minimum steps needed to install Not1MM.
|
272
269
|
|
273
270
|
<details>
|
274
271
|
|
@@ -392,14 +389,14 @@ python3 -m pipx ensurepath
|
|
392
389
|
|
393
390
|
#### Installing with pipx
|
394
391
|
|
395
|
-
Then installing
|
392
|
+
Then installing Not1MM is as simple as:
|
396
393
|
|
397
394
|
```bash
|
398
395
|
# Install not1mm
|
399
396
|
pipx install not1mm
|
400
397
|
```
|
401
398
|
|
402
|
-
If you need to later update
|
399
|
+
If you need to later update Not1MM, you can do so with:
|
403
400
|
|
404
401
|
```bash
|
405
402
|
# Update not1mm
|
@@ -422,7 +419,7 @@ source rebuild.sh
|
|
422
419
|
```
|
423
420
|
|
424
421
|
from the root directory. This installs a build chain and a local editable copy
|
425
|
-
of
|
422
|
+
of Not1MM.
|
426
423
|
|
427
424
|
There's two ways to launch the program from the local editable copy.
|
428
425
|
|
@@ -625,14 +622,10 @@ On the Options TAB you can:
|
|
625
622
|
|
626
623
|
## Logging WSJT-X FT8/FT4/ETC and FLDIGI RTTY contacts
|
627
624
|
|
628
|
-
|
629
|
-
No setup is needed to be done on
|
625
|
+
Not1MM listens for WSJT-X UDP traffic on the Multicast address 224.0.0.1:2237.
|
626
|
+
No setup is needed to be done on Not1MM's side. That's good because I'm lazy.
|
630
627
|
|
631
|
-
|
632
|
-
way. It just keeps asking what was the last QSO and compares it to the previous response.
|
633
|
-
If it's different, it's new.~~
|
634
|
-
|
635
|
-
not1mm watches for fldigi qso's by watching for UDP traffic from fldigi on 127.0.0.1:9876.
|
628
|
+
Not1MM watches for fldigi qso's by watching for UDP traffic from fldigi on 127.0.0.1:9876.
|
636
629
|
|
637
630
|

|
638
631
|
|
@@ -810,6 +803,14 @@ Clicking on any of these items will change the callsign field.
|
|
810
803
|
|
811
804
|

|
812
805
|
|
806
|
+
### The Rate Window
|
807
|
+
|
808
|
+
`Window`>`Rate Window`
|
809
|
+
|
810
|
+
This window contains QSO rates and counts.
|
811
|
+
|
812
|
+

|
813
|
+
|
813
814
|
### The Remote VFO Window
|
814
815
|
|
815
816
|
You can control the VFO on a remote rig by following the directions listed in
|
@@ -1,11 +1,12 @@
|
|
1
1
|
not1mm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
not1mm/__main__.py,sha256=
|
2
|
+
not1mm/__main__.py,sha256=4TslHv_xs1nYgUicgGvtK07oPvFYwtf0T6OHKsaytB8,146185
|
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
7
|
not1mm/lookupservice.py,sha256=GkY_qHZfrW6XHf8upIoaG4hCFqm0fg6Ganu9ConGrIc,2628
|
8
8
|
not1mm/radio.py,sha256=c4m7Ci38uKGKxB0JUT5uOKalI_Mm8Vmixu5D_roN5z4,5400
|
9
|
+
not1mm/ratewindow.py,sha256=eAIjya6D83SAmXH7uBArUyZiMDSYNDoRzz3Y5UVzSy4,9623
|
9
10
|
not1mm/rtc_service.py,sha256=axAwnCBuTr-QL0YwXtWvg9tjwhcFsiiEZFgFjOofX6k,2816
|
10
11
|
not1mm/test.py,sha256=RN71m2S9MPIOJMaoCi0wZhwEhpEZunvtosZxaKahRB4,101
|
11
12
|
not1mm/vfo.py,sha256=ggPyWtxMbdSE5RwdK0nDRwDNqOxdpb_pvnzZdbzZVQE,11136
|
@@ -31,7 +32,7 @@ not1mm/data/k6gte.not1mm-32.png,sha256=XdTsCa3xqwTfn26Ga7RwO_Vlbg_77RKkSc8bMxVcC
|
|
31
32
|
not1mm/data/k6gte.not1mm-64.png,sha256=6ku45Gq1g5ezh04F07osoKRtanb3e4kbx5XdIEh3N90,2925
|
32
33
|
not1mm/data/logwindow.ui,sha256=f7vULj96tHIQuR1nJMyvPHHcmVgzkhv9D1isyojsnFU,1458
|
33
34
|
not1mm/data/logwindowx.ui,sha256=CwpI-h7cI1yqyldH9quKftsdHL5lTyL9ABOcf80nfqc,1632
|
34
|
-
not1mm/data/main.ui,sha256=
|
35
|
+
not1mm/data/main.ui,sha256=LEziByl_8nNTBYR0Z-6CgqDcMbsvQVgfWOfF-B9z3MQ,63537
|
35
36
|
not1mm/data/new_contest.ui,sha256=Sc8HquH7BK0bmkypeK_HbfhArE6yaw02WONOUlRdmuA,23953
|
36
37
|
not1mm/data/not1mm.html,sha256=c9-mfjMwDt4f5pySUruz2gREW33CQ2_rCddM2z5CZQo,23273
|
37
38
|
not1mm/data/opon.ui,sha256=QDicqAk2lORG2UWsHa6jHlsGn6uzrrI2R4HSAocpPes,2258
|
@@ -39,6 +40,7 @@ not1mm/data/pickcontest.ui,sha256=4hPBszCglObThx_eIWtmK9CEcbr7WBjbB1rKZdI-o3I,17
|
|
39
40
|
not1mm/data/radio_green.png,sha256=PXlvRI2x0C8yLVkxRwrZe6tex8k9GtM-1Cj2Vy6KP7o,1234
|
40
41
|
not1mm/data/radio_grey.png,sha256=9eOtMHDpQvRYY29D7_vPeacWbwotRXZTMm8EiHE9TW0,1258
|
41
42
|
not1mm/data/radio_red.png,sha256=QvkMk7thd_hCEIyK5xGAG4xVVXivl39nwOfD8USDI20,957
|
43
|
+
not1mm/data/ratewindow.ui,sha256=yUi9PS0D96W3meNWsU1jg6vcSA_FC-1A2bInshJOTIQ,37369
|
42
44
|
not1mm/data/reddot.png,sha256=M33jEMoU8W4rQ4_MVyzzKxDPDte1ypKBch5VnUMNLKE,565
|
43
45
|
not1mm/data/rttymacros.txt,sha256=FQ2BnAChXF5w-tzmMnBOE8IgvviAEsd3cmmz4b8GOPk,467
|
44
46
|
not1mm/data/settings.ui,sha256=NyHFUb3ZFEgZ4bYB3O7qlO_0TvZwcc9SFPr7z9nF6kk,40123
|
@@ -98,7 +100,7 @@ not1mm/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
98
100
|
not1mm/lib/about.py,sha256=sWycfGcruN3SaEe4JmaJ61K6D8Itq0WxpUYT-lEcmYM,416
|
99
101
|
not1mm/lib/cat_interface.py,sha256=weOH3Gds2ISEdZ2uZkHOv5tBZu-hoSwYKlrFUlg_KK4,25202
|
100
102
|
not1mm/lib/cwinterface.py,sha256=yQL8Dif9oOIynaRItHgvcmu4mYv1TnTpqCHPtkeb09o,4472
|
101
|
-
not1mm/lib/database.py,sha256
|
103
|
+
not1mm/lib/database.py,sha256=-9iAPTXDGVUc3OfnZNZCaWRxg3u-qdJyO5jvSvrJQSk,49203
|
102
104
|
not1mm/lib/edit_contact.py,sha256=Ki9bGPpqyQQBB1cU8VIBDCal3lbXeQ6qxhzklmhE2_w,353
|
103
105
|
not1mm/lib/edit_macro.py,sha256=raKWBwsHInj5EUKmvyLQ6gqc3ZFDlstsD3xqoM4PC8E,517
|
104
106
|
not1mm/lib/edit_opon.py,sha256=j3qJ1aBsQoIOnQ9yiBl3lyeISvKTP0I_rtBYBPAfgeI,359
|
@@ -110,11 +112,11 @@ not1mm/lib/lookup.py,sha256=KECMDi9tflRDzgTLeDfDl7HGWWRHvW3HCjNHyyjoWaY,10835
|
|
110
112
|
not1mm/lib/multicast.py,sha256=KJcruI-bOuHfHXPjl3SGQhL6I9sKrygy-sdFSvxffUM,3255
|
111
113
|
not1mm/lib/n1mm.py,sha256=H54mpgJF0GAmKavM-nb5OAq2SJFWYkux4eMWWiSRxJc,6288
|
112
114
|
not1mm/lib/new_contest.py,sha256=IznTDMq7yXHB6zBoGUEC_WDYPCPpsSZW4wwMJi16zK0,816
|
113
|
-
not1mm/lib/plugin_common.py,sha256
|
115
|
+
not1mm/lib/plugin_common.py,sha256=M5reDYM-v5IjAa2yTROvZTeTDkXYHb3U52W9mc9GxwA,13213
|
114
116
|
not1mm/lib/select_contest.py,sha256=WsptLuwkouIHeocJL3oZ6-eUfEnhpwdc-x7eMZ_TIVM,359
|
115
117
|
not1mm/lib/settings.py,sha256=j5lIMLHJ-eqIaVr_QhI82gkbOl17_C-5suRkWbHYET8,14717
|
116
118
|
not1mm/lib/super_check_partial.py,sha256=hwT2NRwobu0PLDyw6ltmbmcAtGBD02CKGFbgGWjXMqA,2334
|
117
|
-
not1mm/lib/version.py,sha256=
|
119
|
+
not1mm/lib/version.py,sha256=DpSG7ODlKeORCWHhfP6siFU6x8qSgV-CRyUyC-zUp48,48
|
118
120
|
not1mm/lib/versiontest.py,sha256=8vDNptuBBunn-1IGkjNaquehqBYUJyjrPSF8Igmd4_Y,1286
|
119
121
|
not1mm/plugins/10_10_fall_cw.py,sha256=5QUyGMvGBC-HxcY_z9QbfuxSg3f7p6C9K4qhTxgZE7k,14719
|
120
122
|
not1mm/plugins/10_10_spring_cw.py,sha256=XjYFM263WYyG6nVQzPObW4YC7Z9L93rixSOcVsxPvH4,14722
|
@@ -162,10 +164,10 @@ not1mm/plugins/ref_cw.py,sha256=sj69Jjtm1gA9juQTRVSe3BdcCqcQXMaJMD5D1kr5QOs,2072
|
|
162
164
|
not1mm/plugins/ref_ssb.py,sha256=vfS9-mcnbw2znRvU4jh20JqI9BXap8jV65OV5mbCkCk,20939
|
163
165
|
not1mm/plugins/stew_perry_topband.py,sha256=D1hekmMbx-i4BhaP2uzOK3OzaVVMMdgcN3RmfweNqHo,15341
|
164
166
|
not1mm/plugins/weekly_rtty.py,sha256=huZszbZsIh4vF3cP80UyPzy3qxIoHdEiT1b6KuvwgYc,20083
|
165
|
-
not1mm/plugins/winter_field_day.py,sha256=
|
166
|
-
not1mm-25.1.
|
167
|
-
not1mm-25.1.
|
168
|
-
not1mm-25.1.
|
169
|
-
not1mm-25.1.
|
170
|
-
not1mm-25.1.
|
171
|
-
not1mm-25.1.
|
167
|
+
not1mm/plugins/winter_field_day.py,sha256=JK4r1vfxs7aADR7ZYbjZniz3f5s3_ipSQDZ0GRNWC7I,15222
|
168
|
+
not1mm-25.1.23.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
169
|
+
not1mm-25.1.23.dist-info/METADATA,sha256=lzLvwahSNXPAMD5QtDB906desmijbfpV8mItXBeknvA,35691
|
170
|
+
not1mm-25.1.23.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
171
|
+
not1mm-25.1.23.dist-info/entry_points.txt,sha256=pMcZk_0dxFgLkcUkF0Q874ojpwOmF3OL6EKw9LgvocM,47
|
172
|
+
not1mm-25.1.23.dist-info/top_level.txt,sha256=0YmTxEcDzQlzXub-lXASvoLpg_mt1c2thb5cVkDf5J4,7
|
173
|
+
not1mm-25.1.23.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|