not1mm 24.8.27__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.
Files changed (162) hide show
  1. {not1mm-24.8.27 → not1mm-24.9.3}/PKG-INFO +12 -10
  2. {not1mm-24.8.27 → not1mm-24.9.3}/README.md +11 -9
  3. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/__main__.py +61 -35
  4. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/database.py +2 -16
  5. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/version.py +1 -1
  6. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_field_day.py +14 -3
  7. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cq_160_cw.py +2 -2
  8. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cq_160_ssb.py +2 -2
  9. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/helvetia.py +2 -2
  10. not1mm-24.9.3/not1mm/plugins/ref_cw.py +502 -0
  11. not1mm-24.9.3/not1mm/test.py +10 -0
  12. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm.egg-info/PKG-INFO +12 -10
  13. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm.egg-info/SOURCES.txt +1 -0
  14. {not1mm-24.8.27 → not1mm-24.9.3}/pyproject.toml +1 -1
  15. not1mm-24.8.27/not1mm/test.py +0 -13
  16. {not1mm-24.8.27 → not1mm-24.9.3}/LICENSE +0 -0
  17. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/__init__.py +0 -0
  18. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/bandmap.py +0 -0
  19. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/checkwindow.py +0 -0
  20. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/JetBrainsMono-Regular.ttf +0 -0
  21. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/MASTER.SCP +0 -0
  22. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/about.ui +0 -0
  23. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/alpha bravo charlie delta.txt +0 -0
  24. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/bandmap.ui +0 -0
  25. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/check.png +0 -0
  26. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/checkwindow.ui +0 -0
  27. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/configuration.ui +0 -0
  28. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/contests.sql +0 -0
  29. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/cty.json +0 -0
  30. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/cwmacros.txt +0 -0
  31. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/donors.html +0 -0
  32. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/editcontact.ui +0 -0
  33. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/editmacro.ui +0 -0
  34. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/greendot.png +0 -0
  35. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/k6gte-not1mm.desktop +0 -0
  36. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/k6gte.not1mm-128.png +0 -0
  37. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/k6gte.not1mm-32.png +0 -0
  38. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/k6gte.not1mm-64.png +0 -0
  39. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/logwindow.ui +0 -0
  40. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/logwindowx.ui +0 -0
  41. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/main.ui +0 -0
  42. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/new_contest.ui +0 -0
  43. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/not1mm.html +0 -0
  44. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/opon.ui +0 -0
  45. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/0.wav +0 -0
  46. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/1.wav +0 -0
  47. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/2.wav +0 -0
  48. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/3.wav +0 -0
  49. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/4.wav +0 -0
  50. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/5.wav +0 -0
  51. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/6.wav +0 -0
  52. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/7.wav +0 -0
  53. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/73.wav +0 -0
  54. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/8.wav +0 -0
  55. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/9.wav +0 -0
  56. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/a.wav +0 -0
  57. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/again.wav +0 -0
  58. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/b.wav +0 -0
  59. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/c.wav +0 -0
  60. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/contest.wav +0 -0
  61. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/cq.wav +0 -0
  62. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/d.wav +0 -0
  63. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/e.wav +0 -0
  64. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/f.wav +0 -0
  65. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/g.wav +0 -0
  66. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/h.wav +0 -0
  67. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/i.wav +0 -0
  68. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/j.wav +0 -0
  69. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/k.wav +0 -0
  70. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/k6gte.wav +0 -0
  71. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/l.wav +0 -0
  72. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/m.wav +0 -0
  73. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/mynumber.wav +0 -0
  74. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/n.wav +0 -0
  75. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/nil.wav +0 -0
  76. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/o.wav +0 -0
  77. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/p.wav +0 -0
  78. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/q.wav +0 -0
  79. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/r.wav +0 -0
  80. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/roger.wav +0 -0
  81. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/s.wav +0 -0
  82. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/space.wav +0 -0
  83. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/t.wav +0 -0
  84. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/thankyou.wav +0 -0
  85. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
  86. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/u.wav +0 -0
  87. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/v.wav +0 -0
  88. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/w.wav +0 -0
  89. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/x.wav +0 -0
  90. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/y.wav +0 -0
  91. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/yourcall.wav +0 -0
  92. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/phonetics/z.wav +0 -0
  93. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/pickcontest.ui +0 -0
  94. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/radio_green.png +0 -0
  95. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/radio_grey.png +0 -0
  96. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/radio_red.png +0 -0
  97. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/reddot.png +0 -0
  98. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/settings.ui +0 -0
  99. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/splash.png +0 -0
  100. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/ssbmacros.txt +0 -0
  101. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/data/vfo.ui +0 -0
  102. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/fsutils.py +0 -0
  103. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/__init__.py +0 -0
  104. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/about.py +0 -0
  105. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/cat_interface.py +0 -0
  106. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/cwinterface.py +0 -0
  107. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/edit_contact.py +0 -0
  108. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/edit_macro.py +0 -0
  109. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/edit_opon.py +0 -0
  110. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/edit_station.py +0 -0
  111. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/ft8_watcher.py +0 -0
  112. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/ham_utility.py +0 -0
  113. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/lookup.py +0 -0
  114. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/multicast.py +0 -0
  115. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/n1mm.py +0 -0
  116. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/new_contest.py +0 -0
  117. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/playsound.py +0 -0
  118. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/plugin_common.py +0 -0
  119. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/select_contest.py +0 -0
  120. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/settings.py +0 -0
  121. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/super_check_partial.py +0 -0
  122. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/lib/versiontest.py +0 -0
  123. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/logwindow.py +0 -0
  124. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/10_10_fall_cw.py +0 -0
  125. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/10_10_spring_cw.py +0 -0
  126. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/10_10_summer_phone.py +0 -0
  127. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/10_10_winter_phone.py +0 -0
  128. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/__init__.py +0 -0
  129. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_10m.py +0 -0
  130. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_dx_cw.py +0 -0
  131. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_dx_ssb.py +0 -0
  132. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_rtty_ru.py +0 -0
  133. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_ss_cw.py +0 -0
  134. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_ss_phone.py +0 -0
  135. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_vhf_jan.py +0 -0
  136. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_vhf_jun.py +0 -0
  137. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/arrl_vhf_sep.py +0 -0
  138. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/canada_day.py +0 -0
  139. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cq_wpx_cw.py +0 -0
  140. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cq_wpx_ssb.py +0 -0
  141. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cq_ww_cw.py +0 -0
  142. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cq_ww_ssb.py +0 -0
  143. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/cwt.py +0 -0
  144. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/general_logging.py +0 -0
  145. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/iaru_hf.py +0 -0
  146. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/icwc_mst.py +0 -0
  147. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/jidx_cw.py +0 -0
  148. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/jidx_ph.py +0 -0
  149. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/k1usn_sst.py +0 -0
  150. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/naqp_cw.py +0 -0
  151. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/naqp_ssb.py +0 -0
  152. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/phone_weekly_test.py +0 -0
  153. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/stew_perry_topband.py +0 -0
  154. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/plugins/winter_field_day.py +0 -0
  155. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/radio.py +0 -0
  156. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/vfo.py +0 -0
  157. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm/voice_keying.py +0 -0
  158. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm.egg-info/dependency_links.txt +0 -0
  159. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm.egg-info/entry_points.txt +0 -0
  160. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm.egg-info/requires.txt +0 -0
  161. {not1mm-24.8.27 → not1mm-24.9.3}/not1mm.egg-info/top_level.txt +0 -0
  162. {not1mm-24.8.27 → 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.8.27
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
@@ -100,6 +100,7 @@ Requires-Dist: Levenshtein
100
100
  - [Cluster](#cluster)
101
101
  - [N1MM Packets](#n1mm-packets)
102
102
  - [Bands](#bands)
103
+ - [Logging WSJT-X FT8/FT4 contacts](#logging-wsjt-x-ft8ft4-contacts)
103
104
  - [Sending CW](#sending-cw)
104
105
  - [Editing macro keys](#editing-macro-keys)
105
106
  - [Macro substitutions](#macro-substitutions)
@@ -225,11 +226,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
225
226
 
226
227
  ## Recent Changes
227
228
 
228
- - [24-8-27] Added Helvetia contest.
229
- - [24-8-22] Add loading splash screen.
230
- - [24-8-20] Added K1USN Slow Speed Test
231
- - [24-8-17-1] Did an oops. Fixed the oops.
232
- - [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.
233
230
 
234
231
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
235
232
 
@@ -250,7 +247,7 @@ not1mm requires:
250
247
  - PyQt6
251
248
  - libportaudio2
252
249
  - libxcb-cursor0 (maybe... Depends on the distro)
253
-
250
+
254
251
  You should install these through your distribution's package manager before continuing.
255
252
 
256
253
  ### Common installation recipes for Ubuntu and Fedora
@@ -337,9 +334,7 @@ pamac build not1mm-git
337
334
  #### Mint
338
335
 
339
336
  ```bash
340
- sudo apt install python3-pip
341
- sudo apt install pipx
342
- sudo apt install libxcb-cursor0
337
+ sudo apt install python3-pip pipx libxcb-cursor0
343
338
  pipx install not1mm
344
339
  pipx ensurepath
345
340
  ```
@@ -608,6 +603,13 @@ appear. Those without will not.
608
603
 
609
604
  ![Bands Configuration Screen](https://github.com/mbridak/not1mm/raw/master/pic/configure_bands.png)
610
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
+
611
613
  ## Sending CW
612
614
 
613
615
  Other than sending CW by hand, you can also send predefined CW text messages by
@@ -69,6 +69,7 @@
69
69
  - [Cluster](#cluster)
70
70
  - [N1MM Packets](#n1mm-packets)
71
71
  - [Bands](#bands)
72
+ - [Logging WSJT-X FT8/FT4 contacts](#logging-wsjt-x-ft8ft4-contacts)
72
73
  - [Sending CW](#sending-cw)
73
74
  - [Editing macro keys](#editing-macro-keys)
74
75
  - [Macro substitutions](#macro-substitutions)
@@ -194,11 +195,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
194
195
 
195
196
  ## Recent Changes
196
197
 
197
- - [24-8-27] Added Helvetia contest.
198
- - [24-8-22] Add loading splash screen.
199
- - [24-8-20] Added K1USN Slow Speed Test
200
- - [24-8-17-1] Did an oops. Fixed the oops.
201
- - [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.
202
199
 
203
200
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
204
201
 
@@ -219,7 +216,7 @@ not1mm requires:
219
216
  - PyQt6
220
217
  - libportaudio2
221
218
  - libxcb-cursor0 (maybe... Depends on the distro)
222
-
219
+
223
220
  You should install these through your distribution's package manager before continuing.
224
221
 
225
222
  ### Common installation recipes for Ubuntu and Fedora
@@ -306,9 +303,7 @@ pamac build not1mm-git
306
303
  #### Mint
307
304
 
308
305
  ```bash
309
- sudo apt install python3-pip
310
- sudo apt install pipx
311
- sudo apt install libxcb-cursor0
306
+ sudo apt install python3-pip pipx libxcb-cursor0
312
307
  pipx install not1mm
313
308
  pipx ensurepath
314
309
  ```
@@ -577,6 +572,13 @@ appear. Those without will not.
577
572
 
578
573
  ![Bands Configuration Screen](https://github.com/mbridak/not1mm/raw/master/pic/configure_bands.png)
579
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
+
580
582
  ## Sending CW
581
583
 
582
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
 
@@ -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
- data_path = fsutils.APP_DATA_PATH / "main.ui"
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
- with open(fsutils.APP_DATA_PATH / "cty.json", "rt", encoding="utf-8") as c_file:
463
- self.ctyfile = loads(c_file.read())
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
- with open(
1291
- fsutils.APP_DATA_PATH / "cty.json", "rt", encoding="utf-8"
1292
- ) as ctyfile:
1293
- self.ctyfile = loads(ctyfile.read())
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["Freq"] = round(float(self.radio_state.get("vfoa", 0.0)) / 1000, 2)
1902
- self.contact["QSXFreq"] = round(
1903
- float(self.radio_state.get("vfoa", 0.0)) / 1000, 2
1904
- )
1905
- self.contact["Mode"] = self.radio_state.get("mode", "")
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
- self.pref = loads(file_descriptor.read())
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("read_cw_macros: copying default macro file.")
3201
- copyfile(
3202
- fsutils.APP_DATA_PATH / macro_file, fsutils.USER_DATA_PATH / macro_file
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("read_cw_macros: copying default macro file.")
3225
- copyfile(
3226
- fsutils.APP_DATA_PATH / macro_file, fsutils.USER_DATA_PATH / macro_file
3227
- )
3228
- with open(
3229
- fsutils.USER_DATA_PATH / macro_file, "r", encoding="utf-8"
3230
- ) as file_descriptor:
3231
- for line in file_descriptor:
3232
- try:
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
- except ValueError as err:
3239
- logger.info("read_cw_macros: %s", err)
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]}")
@@ -886,28 +886,14 @@ class DataBase:
886
886
  logger.debug("%s", exception)
887
887
  return {}
888
888
 
889
- def fetch_mult1_count(self) -> dict:
889
+ def fetch_mult_count(self, mult: int) -> dict:
890
890
  """return QSO count"""
891
891
  try:
892
892
  with sqlite3.connect(self.database) as conn:
893
893
  conn.row_factory = self.row_factory
894
894
  cursor = conn.cursor()
895
895
  cursor.execute(
896
- f"select count(*) as count from dxlog where IsMultiplier1 = 1 and ContestNR = {self.current_contest};"
897
- )
898
- return cursor.fetchone()
899
- except sqlite3.OperationalError as exception:
900
- logger.debug("%s", exception)
901
- return {}
902
-
903
- def fetch_mult2_count(self) -> dict:
904
- """return QSO count"""
905
- try:
906
- with sqlite3.connect(self.database) as conn:
907
- conn.row_factory = self.row_factory
908
- cursor = conn.cursor()
909
- cursor.execute(
910
- f"select count(*) as count from dxlog where IsMultiplier2 = 1 and ContestNR = {self.current_contest};"
896
+ f"select count(*) as count from dxlog where IsMultiplier{mult} = 1 and ContestNR = {self.current_contest};"
911
897
  )
912
898
  return cursor.fetchone()
913
899
  except sqlite3.OperationalError as exception:
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.8.27"
3
+ __version__ = "24.9.3"
@@ -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 == "LSB" or themode == "USB":
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"] = "FT8"
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.fetch_mult1_count()
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.fetch_mult1_count()
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.fetch_mult1_count()
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.fetch_mult1_count()
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
@@ -250,8 +250,8 @@ def points(self):
250
250
 
251
251
  def show_mults(self):
252
252
  """Return display string for mults"""
253
- return int(self.database.fetch_mult1_count().get("count", 0)) + int(
254
- self.database.fetch_mult2_count().get("count", 0)
253
+ return int(self.database.fetch_mult_count(1).get("count", 0)) + int(
254
+ self.database.fetch_mult_count(2).get("count", 0)
255
255
  )
256
256
 
257
257