not1mm 24.8.20__tar.gz → 24.9.3__tar.gz
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-24.8.20 → not1mm-24.9.3}/PKG-INFO +37 -7
- {not1mm-24.8.20 → not1mm-24.9.3}/README.md +36 -6
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/__main__.py +77 -39
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/new_contest.ui +6 -1
- not1mm-24.9.3/not1mm/data/splash.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/database.py +20 -3
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/ham_utility.py +26 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/version.py +1 -1
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_field_day.py +14 -3
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cq_160_cw.py +2 -2
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cq_160_ssb.py +2 -2
- not1mm-24.9.3/not1mm/plugins/helvetia.py +497 -0
- not1mm-24.9.3/not1mm/plugins/ref_cw.py +502 -0
- not1mm-24.9.3/not1mm/test.py +10 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm.egg-info/PKG-INFO +37 -7
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm.egg-info/SOURCES.txt +4 -1
- {not1mm-24.8.20 → not1mm-24.9.3}/pyproject.toml +1 -1
- not1mm-24.8.20/not1mm/playsoundtest.py +0 -15
- {not1mm-24.8.20 → not1mm-24.9.3}/LICENSE +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/__init__.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/bandmap.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/checkwindow.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/JetBrainsMono-Regular.ttf +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/MASTER.SCP +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/about.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/alpha bravo charlie delta.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/bandmap.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/check.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/checkwindow.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/configuration.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/contests.sql +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/cty.json +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/cwmacros.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/donors.html +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/editcontact.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/editmacro.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/greendot.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/k6gte-not1mm.desktop +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/k6gte.not1mm-128.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/k6gte.not1mm-32.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/k6gte.not1mm-64.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/logwindow.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/logwindowx.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/main.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/not1mm.html +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/opon.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/0.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/1.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/2.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/3.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/4.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/5.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/6.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/7.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/73.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/8.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/9.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/a.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/again.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/b.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/c.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/contest.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/cq.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/d.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/e.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/f.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/g.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/h.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/i.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/j.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/k.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/k6gte.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/l.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/m.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/mynumber.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/n.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/nil.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/o.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/p.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/q.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/r.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/roger.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/s.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/space.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/t.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/thankyou.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/u.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/v.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/w.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/x.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/y.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/yourcall.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/phonetics/z.wav +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/pickcontest.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/radio_green.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/radio_grey.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/radio_red.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/reddot.png +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/settings.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/ssbmacros.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/data/vfo.ui +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/fsutils.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/__init__.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/about.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/cat_interface.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/cwinterface.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/edit_contact.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/edit_macro.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/edit_opon.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/edit_station.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/ft8_watcher.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/lookup.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/multicast.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/n1mm.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/new_contest.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/playsound.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/plugin_common.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/select_contest.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/settings.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/super_check_partial.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/lib/versiontest.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/logwindow.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/10_10_fall_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/10_10_spring_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/10_10_summer_phone.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/10_10_winter_phone.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/__init__.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_10m.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_dx_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_dx_ssb.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_rtty_ru.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_ss_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_ss_phone.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_vhf_jan.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_vhf_jun.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/arrl_vhf_sep.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/canada_day.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cq_wpx_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cq_wpx_ssb.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cq_ww_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cq_ww_ssb.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/cwt.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/general_logging.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/iaru_hf.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/icwc_mst.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/jidx_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/jidx_ph.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/k1usn_sst.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/naqp_cw.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/naqp_ssb.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/phone_weekly_test.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/stew_perry_topband.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/plugins/winter_field_day.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/radio.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/vfo.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm/voice_keying.py +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm.egg-info/dependency_links.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm.egg-info/entry_points.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm.egg-info/requires.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/not1mm.egg-info/top_level.txt +0 -0
- {not1mm-24.8.20 → not1mm-24.9.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: not1mm
|
3
|
-
Version: 24.
|
3
|
+
Version: 24.9.3
|
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
|
@@ -69,6 +69,7 @@ Requires-Dist: Levenshtein
|
|
69
69
|
- [Fedora 38 \& 39](#fedora-38--39)
|
70
70
|
- [Fedora 40](#fedora-40)
|
71
71
|
- [Manjaro](#manjaro)
|
72
|
+
- [Mint](#mint)
|
72
73
|
- [Python, PyPI, pip and pipx](#python-pypi-pip-and-pipx)
|
73
74
|
- [Bootstrapping pipx](#bootstrapping-pipx)
|
74
75
|
- [Installing with pipx](#installing-with-pipx)
|
@@ -99,6 +100,7 @@ Requires-Dist: Levenshtein
|
|
99
100
|
- [Cluster](#cluster)
|
100
101
|
- [N1MM Packets](#n1mm-packets)
|
101
102
|
- [Bands](#bands)
|
103
|
+
- [Logging WSJT-X FT8/FT4 contacts](#logging-wsjt-x-ft8ft4-contacts)
|
102
104
|
- [Sending CW](#sending-cw)
|
103
105
|
- [Editing macro keys](#editing-macro-keys)
|
104
106
|
- [Macro substitutions](#macro-substitutions)
|
@@ -209,6 +211,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
209
211
|
- CQ World Wide CW
|
210
212
|
- CQ World Wide SSB
|
211
213
|
- CWOps CWT
|
214
|
+
- Helvetia
|
212
215
|
- IARU HF
|
213
216
|
- ICWC MST
|
214
217
|
- Japan International DX CW
|
@@ -223,9 +226,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
223
226
|
|
224
227
|
## Recent Changes
|
225
228
|
|
226
|
-
- [24-
|
227
|
-
- [24-8-17-1] Did an oops. Fixed the oops.
|
228
|
-
- [24-8-17] Removed some cruft. Made dockable widgets not floatable since Wayland breaks this.
|
229
|
+
- [24-9-3] Added WSJT-X FT8 mode contacts to ARRL Field Day.
|
229
230
|
|
230
231
|
See [CHANGELOG.md](CHANGELOG.md) for prior changes.
|
231
232
|
|
@@ -240,8 +241,14 @@ clue me into the black magic needed to get it to work.
|
|
240
241
|
|
241
242
|
### Prerequisites
|
242
243
|
|
243
|
-
not1mm requires
|
244
|
-
|
244
|
+
not1mm requires:
|
245
|
+
|
246
|
+
- Python 3.9+
|
247
|
+
- PyQt6
|
248
|
+
- libportaudio2
|
249
|
+
- libxcb-cursor0 (maybe... Depends on the distro)
|
250
|
+
|
251
|
+
You should install these through your distribution's package manager before continuing.
|
245
252
|
|
246
253
|
### Common installation recipes for Ubuntu and Fedora
|
247
254
|
|
@@ -318,6 +325,20 @@ pip install not1mm
|
|
318
325
|
pamac build not1mm-git
|
319
326
|
```
|
320
327
|
|
328
|
+
</details>
|
329
|
+
|
330
|
+
<details>
|
331
|
+
|
332
|
+
<summary><b>Mint 22</b></summary>
|
333
|
+
|
334
|
+
#### Mint
|
335
|
+
|
336
|
+
```bash
|
337
|
+
sudo apt install python3-pip pipx libxcb-cursor0
|
338
|
+
pipx install not1mm
|
339
|
+
pipx ensurepath
|
340
|
+
```
|
341
|
+
|
321
342
|
</details>
|
322
343
|
<br>
|
323
344
|
|
@@ -429,7 +450,9 @@ qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it
|
|
429
450
|
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
|
430
451
|
```
|
431
452
|
|
432
|
-
|
453
|
+
You can use your package manager to load libxcb-cursor0.
|
454
|
+
|
455
|
+
If that's not an option, you can export an environment variable and launch the app like this:
|
433
456
|
|
434
457
|
`mbridak@vm:~$ export QT_QPA_PLATFORM=wayland; not1mm`
|
435
458
|
|
@@ -580,6 +603,13 @@ appear. Those without will not.
|
|
580
603
|
|
581
604
|

|
582
605
|
|
606
|
+
## Logging WSJT-X FT8/FT4 contacts
|
607
|
+
|
608
|
+
**Currently only working for ARRL Field Day.**
|
609
|
+
|
610
|
+
not1mm listens for WSJT-X UDP traffic on the default localhost:2237. No setup is
|
611
|
+
needed to be done on not1mm's side.
|
612
|
+
|
583
613
|
## Sending CW
|
584
614
|
|
585
615
|
Other than sending CW by hand, you can also send predefined CW text messages by
|
@@ -38,6 +38,7 @@
|
|
38
38
|
- [Fedora 38 \& 39](#fedora-38--39)
|
39
39
|
- [Fedora 40](#fedora-40)
|
40
40
|
- [Manjaro](#manjaro)
|
41
|
+
- [Mint](#mint)
|
41
42
|
- [Python, PyPI, pip and pipx](#python-pypi-pip-and-pipx)
|
42
43
|
- [Bootstrapping pipx](#bootstrapping-pipx)
|
43
44
|
- [Installing with pipx](#installing-with-pipx)
|
@@ -68,6 +69,7 @@
|
|
68
69
|
- [Cluster](#cluster)
|
69
70
|
- [N1MM Packets](#n1mm-packets)
|
70
71
|
- [Bands](#bands)
|
72
|
+
- [Logging WSJT-X FT8/FT4 contacts](#logging-wsjt-x-ft8ft4-contacts)
|
71
73
|
- [Sending CW](#sending-cw)
|
72
74
|
- [Editing macro keys](#editing-macro-keys)
|
73
75
|
- [Macro substitutions](#macro-substitutions)
|
@@ -178,6 +180,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
178
180
|
- CQ World Wide CW
|
179
181
|
- CQ World Wide SSB
|
180
182
|
- CWOps CWT
|
183
|
+
- Helvetia
|
181
184
|
- IARU HF
|
182
185
|
- ICWC MST
|
183
186
|
- Japan International DX CW
|
@@ -192,9 +195,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
192
195
|
|
193
196
|
## Recent Changes
|
194
197
|
|
195
|
-
- [24-
|
196
|
-
- [24-8-17-1] Did an oops. Fixed the oops.
|
197
|
-
- [24-8-17] Removed some cruft. Made dockable widgets not floatable since Wayland breaks this.
|
198
|
+
- [24-9-3] Added WSJT-X FT8 mode contacts to ARRL Field Day.
|
198
199
|
|
199
200
|
See [CHANGELOG.md](CHANGELOG.md) for prior changes.
|
200
201
|
|
@@ -209,8 +210,14 @@ clue me into the black magic needed to get it to work.
|
|
209
210
|
|
210
211
|
### Prerequisites
|
211
212
|
|
212
|
-
not1mm requires
|
213
|
-
|
213
|
+
not1mm requires:
|
214
|
+
|
215
|
+
- Python 3.9+
|
216
|
+
- PyQt6
|
217
|
+
- libportaudio2
|
218
|
+
- libxcb-cursor0 (maybe... Depends on the distro)
|
219
|
+
|
220
|
+
You should install these through your distribution's package manager before continuing.
|
214
221
|
|
215
222
|
### Common installation recipes for Ubuntu and Fedora
|
216
223
|
|
@@ -287,6 +294,20 @@ pip install not1mm
|
|
287
294
|
pamac build not1mm-git
|
288
295
|
```
|
289
296
|
|
297
|
+
</details>
|
298
|
+
|
299
|
+
<details>
|
300
|
+
|
301
|
+
<summary><b>Mint 22</b></summary>
|
302
|
+
|
303
|
+
#### Mint
|
304
|
+
|
305
|
+
```bash
|
306
|
+
sudo apt install python3-pip pipx libxcb-cursor0
|
307
|
+
pipx install not1mm
|
308
|
+
pipx ensurepath
|
309
|
+
```
|
310
|
+
|
290
311
|
</details>
|
291
312
|
<br>
|
292
313
|
|
@@ -398,7 +419,9 @@ qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it
|
|
398
419
|
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
|
399
420
|
```
|
400
421
|
|
401
|
-
|
422
|
+
You can use your package manager to load libxcb-cursor0.
|
423
|
+
|
424
|
+
If that's not an option, you can export an environment variable and launch the app like this:
|
402
425
|
|
403
426
|
`mbridak@vm:~$ export QT_QPA_PLATFORM=wayland; not1mm`
|
404
427
|
|
@@ -549,6 +572,13 @@ appear. Those without will not.
|
|
549
572
|
|
550
573
|

|
551
574
|
|
575
|
+
## Logging WSJT-X FT8/FT4 contacts
|
576
|
+
|
577
|
+
**Currently only working for ARRL Field Day.**
|
578
|
+
|
579
|
+
not1mm listens for WSJT-X UDP traffic on the default localhost:2237. No setup is
|
580
|
+
needed to be done on not1mm's side.
|
581
|
+
|
552
582
|
## Sending CW
|
553
583
|
|
554
584
|
Other than sending CW by hand, you can also send predefined CW text messages by
|
@@ -23,6 +23,7 @@ import threading
|
|
23
23
|
import uuid
|
24
24
|
|
25
25
|
from json import dumps, loads
|
26
|
+
from json.decoder import JSONDecodeError
|
26
27
|
from pathlib import Path
|
27
28
|
from shutil import copyfile
|
28
29
|
|
@@ -35,9 +36,9 @@ except OSError as exception:
|
|
35
36
|
print("portaudio is not installed")
|
36
37
|
sd = None
|
37
38
|
from PyQt6 import QtCore, QtGui, QtWidgets, uic
|
38
|
-
from PyQt6.QtCore import QDir, Qt, QThread, QSettings
|
39
|
-
from PyQt6.QtGui import QFontDatabase, QColorConstants, QPalette, QColor
|
40
|
-
from PyQt6.QtWidgets import QFileDialog
|
39
|
+
from PyQt6.QtCore import QDir, Qt, QThread, QSettings, QCoreApplication
|
40
|
+
from PyQt6.QtGui import QFontDatabase, QColorConstants, QPalette, QColor, QPixmap
|
41
|
+
from PyQt6.QtWidgets import QFileDialog, QSplashScreen
|
41
42
|
|
42
43
|
from not1mm.lib.about import About
|
43
44
|
from not1mm.lib.cwinterface import CW
|
@@ -186,8 +187,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
186
187
|
)
|
187
188
|
self.setCorner(Qt.Corner.TopLeftCorner, Qt.DockWidgetArea.LeftDockWidgetArea)
|
188
189
|
self.setCorner(Qt.Corner.BottomLeftCorner, Qt.DockWidgetArea.LeftDockWidgetArea)
|
189
|
-
|
190
|
-
uic.loadUi(data_path, self)
|
190
|
+
uic.loadUi(fsutils.APP_DATA_PATH / "main.ui", self)
|
191
191
|
self.cw_entry.hide()
|
192
192
|
self.leftdot.hide()
|
193
193
|
self.rightdot.hide()
|
@@ -459,8 +459,15 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
459
459
|
self.setWindowIcon(
|
460
460
|
QtGui.QIcon(str(fsutils.APP_DATA_PATH / "k6gte.not1mm-32.png"))
|
461
461
|
)
|
462
|
-
|
463
|
-
|
462
|
+
|
463
|
+
try:
|
464
|
+
with open(
|
465
|
+
fsutils.APP_DATA_PATH / "cty.json", "rt", encoding="utf-8"
|
466
|
+
) as c_file:
|
467
|
+
self.ctyfile = loads(c_file.read())
|
468
|
+
except (IOError, JSONDecodeError, TypeError):
|
469
|
+
logging.CRITICAL("There was an error parsing the BigCity file.")
|
470
|
+
|
464
471
|
self.readpreferences()
|
465
472
|
|
466
473
|
self.voice_process = Voice()
|
@@ -491,9 +498,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
491
498
|
self.make_op_dir()
|
492
499
|
|
493
500
|
self.clearinputs()
|
494
|
-
|
495
|
-
if self.pref.get("contest"):
|
496
|
-
self.load_contest()
|
501
|
+
self.load_contest()
|
497
502
|
self.read_cw_macros()
|
498
503
|
|
499
504
|
# Featureset for wayland
|
@@ -1287,10 +1292,15 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1287
1292
|
if updated:
|
1288
1293
|
cty.dump(fsutils.APP_DATA_PATH / "cty.json")
|
1289
1294
|
self.show_message_box("cty file updated.")
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1295
|
+
try:
|
1296
|
+
with open(
|
1297
|
+
fsutils.APP_DATA_PATH / "cty.json", "rt", encoding="utf-8"
|
1298
|
+
) as ctyfile:
|
1299
|
+
self.ctyfile = loads(ctyfile.read())
|
1300
|
+
except (IOError, JSONDecodeError, TypeError) as err:
|
1301
|
+
logging.CRITICAL(
|
1302
|
+
f"There was an error {err} parsing the BigCity file."
|
1303
|
+
)
|
1294
1304
|
else:
|
1295
1305
|
self.show_message_box("An Error occured updating file.")
|
1296
1306
|
else:
|
@@ -1898,11 +1908,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
1898
1908
|
" "
|
1899
1909
|
)[:19]
|
1900
1910
|
self.contact["Call"] = self.callsign.text()
|
1901
|
-
self.contact
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1911
|
+
if self.contact.get("Mode") not in ("FT8", "FT4"):
|
1912
|
+
self.contact["Freq"] = round(
|
1913
|
+
float(self.radio_state.get("vfoa", 0.0)) / 1000, 2
|
1914
|
+
)
|
1915
|
+
self.contact["QSXFreq"] = round(
|
1916
|
+
float(self.radio_state.get("vfoa", 0.0)) / 1000, 2
|
1917
|
+
)
|
1918
|
+
self.contact["Mode"] = self.radio_state.get("mode", "")
|
1906
1919
|
self.contact["ContestName"] = self.contest.cabrillo_name
|
1907
1920
|
self.contact["ContestNR"] = self.pref.get("contest", "0")
|
1908
1921
|
self.contact["StationPrefix"] = self.station.get("Call", "")
|
@@ -2093,7 +2106,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2093
2106
|
|
2094
2107
|
def save_settings(self) -> None:
|
2095
2108
|
"""
|
2096
|
-
Save settings to database.
|
2109
|
+
Save Station settings to database.
|
2097
2110
|
|
2098
2111
|
Parameters
|
2099
2112
|
----------
|
@@ -2322,7 +2335,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2322
2335
|
with open(fsutils.CONFIG_FILE, "wt", encoding="utf-8") as file_descriptor:
|
2323
2336
|
file_descriptor.write(dumps(self.pref, indent=4))
|
2324
2337
|
# logger.info("writing: %s", self.pref)
|
2325
|
-
except IOError as exception:
|
2338
|
+
except (IOError, TypeError, ValueError) as exception:
|
2326
2339
|
logger.critical("writepreferences: %s", exception)
|
2327
2340
|
|
2328
2341
|
def readpreferences(self) -> None:
|
@@ -2344,7 +2357,12 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2344
2357
|
with open(
|
2345
2358
|
fsutils.CONFIG_FILE, "rt", encoding="utf-8"
|
2346
2359
|
) as file_descriptor:
|
2347
|
-
|
2360
|
+
try:
|
2361
|
+
self.pref = loads(file_descriptor.read())
|
2362
|
+
except (JSONDecodeError, TypeError):
|
2363
|
+
logging.CRITICAL(
|
2364
|
+
"There was an error parsing the preference file."
|
2365
|
+
)
|
2348
2366
|
logger.info("%s", self.pref)
|
2349
2367
|
else:
|
2350
2368
|
logger.info("No preference file. Writing preference.")
|
@@ -2354,7 +2372,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
2354
2372
|
self.pref = self.pref_ref.copy()
|
2355
2373
|
file_descriptor.write(dumps(self.pref, indent=4))
|
2356
2374
|
logger.info("%s", self.pref)
|
2357
|
-
except IOError as exception:
|
2375
|
+
except (IOError, TypeError, ValueError) as exception:
|
2358
2376
|
logger.critical("Error: %s", exception)
|
2359
2377
|
|
2360
2378
|
self.look_up = None
|
@@ -3197,10 +3215,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
3197
3215
|
else:
|
3198
3216
|
macro_file = "ssbmacros.txt"
|
3199
3217
|
if not (fsutils.USER_DATA_PATH / macro_file).exists():
|
3200
|
-
logger.debug("
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3218
|
+
logger.debug("copying default macro file.")
|
3219
|
+
try:
|
3220
|
+
copyfile(
|
3221
|
+
fsutils.APP_DATA_PATH / macro_file,
|
3222
|
+
fsutils.USER_DATA_PATH / macro_file,
|
3223
|
+
)
|
3224
|
+
except IOError as err:
|
3225
|
+
logger.critical(f"Error {err} copying macro file.")
|
3204
3226
|
try:
|
3205
3227
|
fsutils.openFileWithOS(fsutils.USER_DATA_PATH / macro_file)
|
3206
3228
|
except FileNotFoundError | PermissionError | OSError as err:
|
@@ -3221,22 +3243,26 @@ class MainWindow(QtWidgets.QMainWindow):
|
|
3221
3243
|
macro_file = "ssbmacros.txt"
|
3222
3244
|
|
3223
3245
|
if not (fsutils.USER_DATA_PATH / macro_file).exists():
|
3224
|
-
logger.debug("
|
3225
|
-
|
3226
|
-
|
3227
|
-
|
3228
|
-
|
3229
|
-
|
3230
|
-
|
3231
|
-
|
3232
|
-
|
3246
|
+
logger.debug("copying default macro file.")
|
3247
|
+
try:
|
3248
|
+
copyfile(
|
3249
|
+
fsutils.APP_DATA_PATH / macro_file,
|
3250
|
+
fsutils.USER_DATA_PATH / macro_file,
|
3251
|
+
)
|
3252
|
+
except IOError as err:
|
3253
|
+
logger.critical(f"Error {err} copying macro file.")
|
3254
|
+
try:
|
3255
|
+
with open(
|
3256
|
+
fsutils.USER_DATA_PATH / macro_file, "r", encoding="utf-8"
|
3257
|
+
) as file_descriptor:
|
3258
|
+
for line in file_descriptor:
|
3233
3259
|
mode, fkey, buttonname, cwtext = line.split("|")
|
3234
3260
|
if mode.strip().upper() == "R" and self.pref.get("run_state"):
|
3235
3261
|
self.fkeys[fkey.strip()] = (buttonname.strip(), cwtext.strip())
|
3236
3262
|
if mode.strip().upper() != "R" and not self.pref.get("run_state"):
|
3237
3263
|
self.fkeys[fkey.strip()] = (buttonname.strip(), cwtext.strip())
|
3238
|
-
|
3239
|
-
|
3264
|
+
except (IOError, ValueError) as err:
|
3265
|
+
logger.info("read_cw_macros: %s", err)
|
3240
3266
|
keys = self.fkeys.keys()
|
3241
3267
|
if "F1" in keys:
|
3242
3268
|
self.F1.setText(f"F1: {self.fkeys['F1'][0]}")
|
@@ -3398,12 +3424,24 @@ logging.basicConfig(
|
|
3398
3424
|
logging.getLogger("PyQt6.uic.uiparser").setLevel("INFO")
|
3399
3425
|
logging.getLogger("PyQt6.uic.properties").setLevel("INFO")
|
3400
3426
|
app = QtWidgets.QApplication(sys.argv)
|
3427
|
+
|
3428
|
+
pixmap = QPixmap(f"{os.fspath(fsutils.APP_DATA_PATH)}/splash.png")
|
3429
|
+
splash = QSplashScreen(pixmap)
|
3430
|
+
splash.show()
|
3431
|
+
app.processEvents()
|
3432
|
+
splash.showMessage(
|
3433
|
+
"Starting Up",
|
3434
|
+
alignment=Qt.AlignmentFlag.AlignBottom | Qt.AlignmentFlag.AlignCenter,
|
3435
|
+
color=QColor(255, 255, 0),
|
3436
|
+
)
|
3437
|
+
QCoreApplication.processEvents()
|
3438
|
+
|
3401
3439
|
families = load_fonts_from_dir(os.fspath(fsutils.APP_DATA_PATH))
|
3402
3440
|
logger.info(f"font families {families}")
|
3403
3441
|
window = MainWindow()
|
3404
3442
|
window.callsign.setFocus()
|
3405
3443
|
window.show()
|
3406
|
-
|
3444
|
+
splash.finish(window)
|
3407
3445
|
|
3408
3446
|
if __name__ == "__main__":
|
3409
3447
|
run()
|
@@ -297,6 +297,11 @@
|
|
297
297
|
<string>CWT</string>
|
298
298
|
</property>
|
299
299
|
</item>
|
300
|
+
<item>
|
301
|
+
<property name="text">
|
302
|
+
<string>HELVETIA</string>
|
303
|
+
</property>
|
304
|
+
</item>
|
300
305
|
<item>
|
301
306
|
<property name="text">
|
302
307
|
<string>ICWC MST</string>
|
@@ -356,7 +361,7 @@
|
|
356
361
|
</property>
|
357
362
|
<property name="time">
|
358
363
|
<time>
|
359
|
-
<hour>
|
364
|
+
<hour>0</hour>
|
360
365
|
<minute>0</minute>
|
361
366
|
<second>0</second>
|
362
367
|
</time>
|
Binary file
|
@@ -567,7 +567,7 @@ class DataBase:
|
|
567
567
|
def fetch_country_band_count(self) -> dict:
|
568
568
|
"""
|
569
569
|
returns dict with count of unique NR.
|
570
|
-
{
|
570
|
+
{cb_count: count}
|
571
571
|
"""
|
572
572
|
try:
|
573
573
|
with sqlite3.connect(self.database) as conn:
|
@@ -581,6 +581,23 @@ class DataBase:
|
|
581
581
|
logger.debug("%s", exception)
|
582
582
|
return {}
|
583
583
|
|
584
|
+
def fetch_country_count(self) -> dict:
|
585
|
+
"""
|
586
|
+
Fetch count of unique countries
|
587
|
+
{dxcc_count: count}
|
588
|
+
"""
|
589
|
+
try:
|
590
|
+
with sqlite3.connect(self.database) as conn:
|
591
|
+
conn.row_factory = self.row_factory
|
592
|
+
cursor = conn.cursor()
|
593
|
+
cursor.execute(
|
594
|
+
f"select count(DISTINCT(CountryPrefix)) as dxcc_count from dxlog where ContestNR = {self.current_contest};"
|
595
|
+
)
|
596
|
+
return cursor.fetchone()
|
597
|
+
except sqlite3.OperationalError as exception:
|
598
|
+
logger.debug("%s", exception)
|
599
|
+
return {}
|
600
|
+
|
584
601
|
def fetch_arrldx_country_band_count(self) -> dict:
|
585
602
|
"""
|
586
603
|
returns dict with count of unique NR.
|
@@ -869,14 +886,14 @@ class DataBase:
|
|
869
886
|
logger.debug("%s", exception)
|
870
887
|
return {}
|
871
888
|
|
872
|
-
def
|
889
|
+
def fetch_mult_count(self, mult: int) -> dict:
|
873
890
|
"""return QSO count"""
|
874
891
|
try:
|
875
892
|
with sqlite3.connect(self.database) as conn:
|
876
893
|
conn.row_factory = self.row_factory
|
877
894
|
cursor = conn.cursor()
|
878
895
|
cursor.execute(
|
879
|
-
f"select count(*) as count from dxlog where
|
896
|
+
f"select count(*) as count from dxlog where IsMultiplier{mult} = 1 and ContestNR = {self.current_contest};"
|
880
897
|
)
|
881
898
|
return cursor.fetchone()
|
882
899
|
except sqlite3.OperationalError as exception:
|
@@ -373,3 +373,29 @@ def distance_with_latlon(grid1: str, lat2: float, lon2: float) -> float:
|
|
373
373
|
logger.debug("lat1:%d lon1:%d lat2:%d lon2:%d", lat1, lon1, lat2, lon2)
|
374
374
|
# lat2, lon2 = gridtolatlon(grid2)
|
375
375
|
return round(haversine(lon1, lat1, lon2, lat2))
|
376
|
+
|
377
|
+
|
378
|
+
def parse_udc(filename: str) -> dict:
|
379
|
+
"""
|
380
|
+
simply parses a n1mm style udc file and returns a dict with key value pairs.
|
381
|
+
"""
|
382
|
+
|
383
|
+
udc_contest = {}
|
384
|
+
the_good_stuff = False
|
385
|
+
|
386
|
+
try:
|
387
|
+
with open(filename, "r", encoding="utf-8") as file_descriptor:
|
388
|
+
for line in file_descriptor:
|
389
|
+
if "[CONTEST]" in line.upper():
|
390
|
+
the_good_stuff = True
|
391
|
+
continue
|
392
|
+
if "=" in line and the_good_stuff is True:
|
393
|
+
try:
|
394
|
+
key, value = line.split("=")
|
395
|
+
udc_contest[key.strip()] = value.strip()
|
396
|
+
except ValueError:
|
397
|
+
...
|
398
|
+
except FileNotFoundError:
|
399
|
+
logger.debug("UDC file not found.")
|
400
|
+
return {}
|
401
|
+
return udc_contest
|
@@ -8,6 +8,7 @@ import logging
|
|
8
8
|
from pathlib import Path
|
9
9
|
from PyQt6 import QtWidgets
|
10
10
|
|
11
|
+
from not1mm.lib.ham_utility import get_logged_band
|
11
12
|
from not1mm.lib.plugin_common import gen_adif, get_points
|
12
13
|
from not1mm.lib.version import __version__
|
13
14
|
|
@@ -114,7 +115,7 @@ def points(self):
|
|
114
115
|
_mode = self.contact.get("Mode", "")
|
115
116
|
if _mode in "SSB, USB, LSB, FM, AM":
|
116
117
|
return 1
|
117
|
-
if _mode in "CW, RTTY":
|
118
|
+
if _mode in "CW, RTTY, FT8":
|
118
119
|
return 2
|
119
120
|
return 0
|
120
121
|
|
@@ -295,8 +296,10 @@ def cabrillo(self):
|
|
295
296
|
for contact in log:
|
296
297
|
the_date_and_time = contact.get("TS", "")
|
297
298
|
themode = contact.get("Mode", "")
|
298
|
-
if themode
|
299
|
+
if themode in ("LSB", "USB"):
|
299
300
|
themode = "PH"
|
301
|
+
if themode in ("FT8", "FT4"):
|
302
|
+
themode = "DG"
|
300
303
|
frequency = str(int(contact.get("Freq", "0"))).rjust(5)
|
301
304
|
|
302
305
|
loggeddate = the_date_and_time[:10]
|
@@ -362,7 +365,15 @@ def ft8_handler(the_packet: dict):
|
|
362
365
|
ALTEREGO.contact["RCV"] = ALTEREGO.receive.text()
|
363
366
|
ALTEREGO.contact["Exchange1"] = the_packet.get("CLASS", "ERR")
|
364
367
|
ALTEREGO.contact["Sect"] = the_packet.get("ARRL_SECT", "ERR")
|
365
|
-
ALTEREGO.contact["Mode"] = "
|
368
|
+
ALTEREGO.contact["Mode"] = the_packet.get("MODE", "ERR")
|
369
|
+
ALTEREGO.contact["Freq"] = round(float(the_packet.get("FREQ", "0.0")) * 1000, 2)
|
370
|
+
ALTEREGO.contact["QSXFreq"] = round(
|
371
|
+
float(the_packet.get("FREQ", "0.0")) * 1000, 2
|
372
|
+
)
|
373
|
+
ALTEREGO.contact["Band"] = get_logged_band(
|
374
|
+
str(int(float(the_packet.get("FREQ", "0.0")) * 1000000))
|
375
|
+
)
|
366
376
|
ALTEREGO.other_1.setText(the_packet.get("CLASS", "ERR"))
|
367
377
|
ALTEREGO.other_2.setText(the_packet.get("ARRL_SECT", "ERR"))
|
368
378
|
print(f"\n{ALTEREGO.contact=}\n")
|
379
|
+
ALTEREGO.save_contact()
|
@@ -177,7 +177,7 @@ def points(self):
|
|
177
177
|
|
178
178
|
def show_mults(self):
|
179
179
|
"""Return display string for mults"""
|
180
|
-
result = self.database.
|
180
|
+
result = self.database.fetch_mult_count(1)
|
181
181
|
count = result.get("count", 0)
|
182
182
|
return count
|
183
183
|
|
@@ -198,7 +198,7 @@ def calc_score(self):
|
|
198
198
|
if score is None:
|
199
199
|
score = "0"
|
200
200
|
contest_points = int(score)
|
201
|
-
result = self.database.
|
201
|
+
result = self.database.fetch_mult_count(1)
|
202
202
|
mults = int(result.get("count", 0))
|
203
203
|
return contest_points * mults
|
204
204
|
return 0
|
@@ -177,7 +177,7 @@ def points(self):
|
|
177
177
|
|
178
178
|
def show_mults(self):
|
179
179
|
"""Return display string for mults"""
|
180
|
-
result = self.database.
|
180
|
+
result = self.database.fetch_mult_count(1)
|
181
181
|
count = result.get("count", 0)
|
182
182
|
return count
|
183
183
|
|
@@ -198,7 +198,7 @@ def calc_score(self):
|
|
198
198
|
if score is None:
|
199
199
|
score = "0"
|
200
200
|
contest_points = int(score)
|
201
|
-
result = self.database.
|
201
|
+
result = self.database.fetch_mult_count(1)
|
202
202
|
mults = int(result.get("count", 0))
|
203
203
|
return contest_points * mults
|
204
204
|
return 0
|