not1mm 24.5.1__tar.gz → 24.5.9__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 (157) hide show
  1. {not1mm-24.5.1 → not1mm-24.5.9}/PKG-INFO +8 -3
  2. {not1mm-24.5.1 → not1mm-24.5.9}/README.md +7 -2
  3. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/__main__.py +18 -10
  4. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/bandmap.py +3 -1
  5. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/checkwindow.py +5 -1
  6. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/new_contest.ui +5 -0
  7. not1mm-24.5.9/not1mm/lib/playsound.py +296 -0
  8. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/version.py +1 -1
  9. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/logwindow.py +5 -1
  10. not1mm-24.5.9/not1mm/playsoundtest.py +15 -0
  11. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/10_10_fall_cw.py +2 -0
  12. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/10_10_spring_cw.py +2 -0
  13. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/10_10_summer_phone.py +2 -0
  14. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/10_10_winter_phone.py +2 -0
  15. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_10m.py +2 -0
  16. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_dx_cw.py +2 -0
  17. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_dx_ssb.py +2 -0
  18. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_ss_cw.py +2 -0
  19. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_ss_phone.py +2 -0
  20. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_vhf_jan.py +2 -0
  21. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_vhf_jun.py +2 -0
  22. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_vhf_sep.py +2 -0
  23. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/canada_day.py +2 -0
  24. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cq_160_cw.py +2 -0
  25. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cq_160_ssb.py +2 -0
  26. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cq_wpx_cw.py +39 -0
  27. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cq_wpx_ssb.py +2 -0
  28. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cq_ww_cw.py +2 -0
  29. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cq_ww_ssb.py +2 -0
  30. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/cwt.py +26 -0
  31. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/general_logging.py +2 -0
  32. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/iaru_hf.py +2 -0
  33. not1mm-24.5.9/not1mm/plugins/icwc_mst.py +372 -0
  34. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/jidx_cw.py +31 -0
  35. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/jidx_ph.py +2 -0
  36. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/naqp_cw.py +32 -0
  37. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/naqp_ssb.py +2 -0
  38. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/stew_perry_topband.py +2 -0
  39. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/radio.py +12 -9
  40. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/vfo.py +5 -1
  41. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/voice_keying.py +3 -0
  42. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm.egg-info/PKG-INFO +8 -3
  43. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm.egg-info/SOURCES.txt +3 -0
  44. {not1mm-24.5.1 → not1mm-24.5.9}/pyproject.toml +1 -1
  45. {not1mm-24.5.1 → not1mm-24.5.9}/LICENSE +0 -0
  46. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/__init__.py +0 -0
  47. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/JetBrainsMono-Regular.ttf +0 -0
  48. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/MASTER.SCP +0 -0
  49. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/about.ui +0 -0
  50. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/alpha bravo charlie delta.txt +0 -0
  51. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/bandmap.ui +0 -0
  52. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/check.png +0 -0
  53. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/checkwindow.ui +0 -0
  54. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/configuration.ui +0 -0
  55. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/contests.sql +0 -0
  56. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/cty.json +0 -0
  57. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/cwmacros.txt +0 -0
  58. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/donors.html +0 -0
  59. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/editcontact.ui +0 -0
  60. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/editmacro.ui +0 -0
  61. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/greendot.png +0 -0
  62. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/k6gte-not1mm.desktop +0 -0
  63. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/k6gte.not1mm-128.png +0 -0
  64. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/k6gte.not1mm-32.png +0 -0
  65. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/k6gte.not1mm-64.png +0 -0
  66. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/logwindow.ui +0 -0
  67. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/logwindowx.ui +0 -0
  68. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/main.ui +0 -0
  69. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/not1mm.html +0 -0
  70. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/opon.ui +0 -0
  71. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/0.wav +0 -0
  72. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/1.wav +0 -0
  73. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/2.wav +0 -0
  74. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/3.wav +0 -0
  75. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/4.wav +0 -0
  76. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/5.wav +0 -0
  77. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/6.wav +0 -0
  78. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/7.wav +0 -0
  79. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/73.wav +0 -0
  80. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/8.wav +0 -0
  81. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/9.wav +0 -0
  82. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/a.wav +0 -0
  83. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/again.wav +0 -0
  84. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/b.wav +0 -0
  85. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/c.wav +0 -0
  86. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/contest.wav +0 -0
  87. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/cq.wav +0 -0
  88. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/d.wav +0 -0
  89. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/e.wav +0 -0
  90. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/f.wav +0 -0
  91. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/g.wav +0 -0
  92. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/h.wav +0 -0
  93. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/i.wav +0 -0
  94. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/j.wav +0 -0
  95. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/k.wav +0 -0
  96. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/k6gte.wav +0 -0
  97. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/l.wav +0 -0
  98. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/m.wav +0 -0
  99. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/mynumber.wav +0 -0
  100. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/n.wav +0 -0
  101. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/nil.wav +0 -0
  102. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/o.wav +0 -0
  103. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/p.wav +0 -0
  104. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/q.wav +0 -0
  105. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/r.wav +0 -0
  106. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/roger.wav +0 -0
  107. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/s.wav +0 -0
  108. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/space.wav +0 -0
  109. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/t.wav +0 -0
  110. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/thankyou.wav +0 -0
  111. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
  112. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/u.wav +0 -0
  113. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/v.wav +0 -0
  114. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/w.wav +0 -0
  115. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/x.wav +0 -0
  116. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/y.wav +0 -0
  117. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/yourcall.wav +0 -0
  118. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/phonetics/z.wav +0 -0
  119. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/pickcontest.ui +0 -0
  120. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/radio_green.png +0 -0
  121. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/radio_grey.png +0 -0
  122. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/radio_red.png +0 -0
  123. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/reddot.png +0 -0
  124. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/settings.ui +0 -0
  125. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/ssbmacros.txt +0 -0
  126. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/data/vfo.ui +0 -0
  127. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/fsutils.py +0 -0
  128. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/__init__.py +0 -0
  129. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/about.py +0 -0
  130. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/cat_interface.py +0 -0
  131. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/cwinterface.py +0 -0
  132. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/database.py +0 -0
  133. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/edit_contact.py +0 -0
  134. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/edit_macro.py +0 -0
  135. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/edit_opon.py +0 -0
  136. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/edit_station.py +0 -0
  137. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/ft8_watcher.py +0 -0
  138. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/ham_utility.py +0 -0
  139. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/lookup.py +0 -0
  140. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/multicast.py +0 -0
  141. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/n1mm.py +0 -0
  142. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/new_contest.py +0 -0
  143. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/plugin_common.py +0 -0
  144. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/select_contest.py +0 -0
  145. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/settings.py +0 -0
  146. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/super_check_partial.py +0 -0
  147. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/lib/versiontest.py +0 -0
  148. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/__init__.py +0 -0
  149. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_field_day.py +0 -0
  150. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/arrl_rtty_ru.py +0 -0
  151. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/phone_weekly_test.py +0 -0
  152. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm/plugins/winter_field_day.py +0 -0
  153. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm.egg-info/dependency_links.txt +0 -0
  154. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm.egg-info/entry_points.txt +0 -0
  155. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm.egg-info/requires.txt +0 -0
  156. {not1mm-24.5.1 → not1mm-24.5.9}/not1mm.egg-info/top_level.txt +0 -0
  157. {not1mm-24.5.1 → not1mm-24.5.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 24.5.1
3
+ Version: 24.5.9
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
@@ -169,6 +169,7 @@ I wish to thank those who've contributed to the project.
169
169
  - CQ World Wide SSB
170
170
  - CWOps CWT
171
171
  - IARU HF
172
+ - ICWC MST
172
173
  - Japan International DX CW
173
174
  - Japan International DX SSB
174
175
  - NAQP CW
@@ -180,6 +181,7 @@ I wish to thank those who've contributed to the project.
180
181
 
181
182
  ## Recent Changes
182
183
 
184
+ - [24-5-9] Add ICWC MST.
183
185
  - [24-5-1] Moved the voice keying into it's own thread.
184
186
 
185
187
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
@@ -212,8 +214,11 @@ noted the minimum steps needed to install not1mm.
212
214
  ```bash
213
215
  sudo apt update
214
216
  sudo apt upgrade
215
- sudo apt install -y libportaudio2 python3-pip python3-pyqt6 python3-numpy
216
- pip install -U not1mm
217
+ sudo apt install -y python3-pip python3-numpy libxcb-cursor0 libportaudio2
218
+ python3 -m pip install -U pip
219
+ # Logout and back in
220
+ pip3 install PyQt6
221
+ pip3 install not1mm
217
222
  ```
218
223
 
219
224
  #### Ubuntu 23.04
@@ -137,6 +137,7 @@ I wish to thank those who've contributed to the project.
137
137
  - CQ World Wide SSB
138
138
  - CWOps CWT
139
139
  - IARU HF
140
+ - ICWC MST
140
141
  - Japan International DX CW
141
142
  - Japan International DX SSB
142
143
  - NAQP CW
@@ -148,6 +149,7 @@ I wish to thank those who've contributed to the project.
148
149
 
149
150
  ## Recent Changes
150
151
 
152
+ - [24-5-9] Add ICWC MST.
151
153
  - [24-5-1] Moved the voice keying into it's own thread.
152
154
 
153
155
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
@@ -180,8 +182,11 @@ noted the minimum steps needed to install not1mm.
180
182
  ```bash
181
183
  sudo apt update
182
184
  sudo apt upgrade
183
- sudo apt install -y libportaudio2 python3-pip python3-pyqt6 python3-numpy
184
- pip install -U not1mm
185
+ sudo apt install -y python3-pip python3-numpy libxcb-cursor0 libportaudio2
186
+ python3 -m pip install -U pip
187
+ # Logout and back in
188
+ pip3 install PyQt6
189
+ pip3 install not1mm
185
190
  ```
186
191
 
187
192
  #### Ubuntu 23.04
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- NOT1MM Logger
3
+ not1mm Contest logger
4
+ Email: michael.bridak@gmail.com
5
+ GPL V3
6
+ Purpose: Provides main logging window and a crap ton more.
4
7
  """
5
8
  # pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines, no-name-in-module
6
9
  # pylint: disable=logging-fstring-interpolation, logging-not-lazy, line-too-long, bare-except
@@ -1247,6 +1250,7 @@ class MainWindow(QtWidgets.QMainWindow):
1247
1250
  else:
1248
1251
  self.cw_speed.hide()
1249
1252
 
1253
+ self.clearinputs()
1250
1254
  cmd = {}
1251
1255
  cmd["cmd"] = "NEWDB"
1252
1256
  cmd["station"] = platform.node()
@@ -1848,6 +1852,7 @@ class MainWindow(QtWidgets.QMainWindow):
1848
1852
  self.contact = self.database.empty_contact
1849
1853
  self.heading_distance.setText("")
1850
1854
  self.dx_entity.setText("")
1855
+
1851
1856
  if self.contest:
1852
1857
  mults = self.contest.show_mults(self)
1853
1858
  qsos = self.contest.show_qso(self)
@@ -1856,13 +1861,16 @@ class MainWindow(QtWidgets.QMainWindow):
1856
1861
  score = self.contest.calc_score(self)
1857
1862
  self.score.setText(str(score))
1858
1863
  self.contest.reset_label(self)
1864
+ if self.contest.name != "ICWC Medium Speed Test":
1865
+ if self.current_mode == "CW":
1866
+ self.sent.setText("599")
1867
+ self.receive.setText("599")
1868
+ else:
1869
+ self.sent.setText("59")
1870
+ self.receive.setText("59")
1871
+ else:
1872
+ self.sent.setText("")
1859
1873
  self.callsign.clear()
1860
- if self.current_mode == "CW":
1861
- self.sent.setText("599")
1862
- self.receive.setText("599")
1863
- else:
1864
- self.sent.setText("59")
1865
- self.receive.setText("59")
1866
1874
  self.other_1.clear()
1867
1875
  self.other_2.clear()
1868
1876
  self.callsign.setFocus()
@@ -3010,15 +3018,16 @@ class MainWindow(QtWidgets.QMainWindow):
3010
3018
  if mode == "CW":
3011
3019
  if self.current_mode != "CW":
3012
3020
  self.current_mode = "CW"
3013
- # self.mode.setText("CW")
3014
3021
  self.sent.setText("599")
3015
3022
  self.receive.setText("599")
3016
3023
  self.read_cw_macros()
3024
+ if self.contest:
3025
+ if self.contest.name == "ICWC Medium Speed Test":
3026
+ self.contest.prefill(self)
3017
3027
  return
3018
3028
  if mode == "SSB":
3019
3029
  if self.current_mode != "SSB":
3020
3030
  self.current_mode = "SSB"
3021
- # self.mode.setText("SSB")
3022
3031
  self.sent.setText("59")
3023
3032
  self.receive.setText("59")
3024
3033
  self.read_cw_macros()
@@ -3026,7 +3035,6 @@ class MainWindow(QtWidgets.QMainWindow):
3026
3035
  if mode == "RTTY":
3027
3036
  if self.current_mode != "RTTY":
3028
3037
  self.current_mode = "RTTY"
3029
- # self.mode.setText("RTTY")
3030
3038
  self.sent.setText("59")
3031
3039
  self.receive.setText("59")
3032
3040
 
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- K6GTE Contest logger
3
+ not1mm Contest logger
4
4
  Email: michael.bridak@gmail.com
5
5
  GPL V3
6
+ Class: BandMapWindow
7
+ Purpose: Onscreen widget to show realtime spots from an AR cluster.
6
8
  """
7
9
 
8
10
  # pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Check Window
3
+ not1mm Contest logger
4
+ Email: michael.bridak@gmail.com
5
+ GPL V3
6
+ Class: CheckWindow
7
+ Purpose: Onscreen widget to show possible matches to callsigns entered in the main window.
4
8
  """
5
9
  # pylint: disable=no-name-in-module, unused-import, no-member, invalid-name, c-extension-no-member
6
10
  # pylint: disable=logging-fstring-interpolation, line-too-long
@@ -297,6 +297,11 @@
297
297
  <string>CWT</string>
298
298
  </property>
299
299
  </item>
300
+ <item>
301
+ <property name="text">
302
+ <string>ICWC MST</string>
303
+ </property>
304
+ </item>
300
305
  <item>
301
306
  <property name="text">
302
307
  <string>IARU HF</string>
@@ -0,0 +1,296 @@
1
+ import logging
2
+ from platform import system
3
+
4
+ logger = logging.getLogger(__name__)
5
+
6
+
7
+ class PlaysoundException(Exception):
8
+ pass
9
+
10
+
11
+ def _canonicalizePath(path):
12
+ """
13
+ Support passing in a pathlib.Path-like object by converting to str.
14
+ """
15
+ import sys
16
+
17
+ if sys.version_info[0] >= 3:
18
+ return str(path)
19
+ else:
20
+ # On earlier Python versions, str is a byte string, so attempting to
21
+ # convert a unicode string to str will fail. Leave it alone in this case.
22
+ return path
23
+
24
+
25
+ def _playsoundWin(sound, block=True):
26
+ """
27
+ Utilizes windll.winmm. Tested and known to work with MP3 and WAVE on
28
+ Windows 7 with Python 2.7. Probably works with more file formats.
29
+ Probably works on Windows XP thru Windows 10. Probably works with all
30
+ versions of Python.
31
+
32
+ Inspired by (but not copied from) Michael Gundlach <gundlach@gmail.com>'s mp3play:
33
+ https://github.com/michaelgundlach/mp3play
34
+
35
+ I never would have tried using windll.winmm without seeing his code.
36
+ """
37
+ sound = '"' + _canonicalizePath(sound) + '"'
38
+
39
+ from ctypes import create_unicode_buffer, windll, wintypes
40
+
41
+ windll.winmm.mciSendStringW.argtypes = [
42
+ wintypes.LPCWSTR,
43
+ wintypes.LPWSTR,
44
+ wintypes.UINT,
45
+ wintypes.HANDLE,
46
+ ]
47
+ windll.winmm.mciGetErrorStringW.argtypes = [
48
+ wintypes.DWORD,
49
+ wintypes.LPWSTR,
50
+ wintypes.UINT,
51
+ ]
52
+
53
+ def winCommand(*command):
54
+ bufLen = 600
55
+ buf = create_unicode_buffer(bufLen)
56
+ command = " ".join(command)
57
+ errorCode = int(
58
+ windll.winmm.mciSendStringW(command, buf, bufLen - 1, 0)
59
+ ) # use widestring version of the function
60
+ if errorCode:
61
+ errorBuffer = create_unicode_buffer(bufLen)
62
+ windll.winmm.mciGetErrorStringW(
63
+ errorCode, errorBuffer, bufLen - 1
64
+ ) # use widestring version of the function
65
+ exceptionMessage = (
66
+ "\n Error " + str(errorCode) + " for command:"
67
+ "\n " + command + "\n " + errorBuffer.value
68
+ )
69
+ logger.error(exceptionMessage)
70
+ raise PlaysoundException(exceptionMessage)
71
+ return buf.value
72
+
73
+ try:
74
+ logger.debug("Starting")
75
+ winCommand("open {}".format(sound))
76
+ winCommand("play {}{}".format(sound, " wait" if block else ""))
77
+ logger.debug("Returning")
78
+ finally:
79
+ try:
80
+ winCommand("close {}".format(sound))
81
+ except PlaysoundException:
82
+ logger.warning("Failed to close the file: {}".format(sound))
83
+ # If it fails, there's nothing more that can be done...
84
+ pass
85
+
86
+
87
+ def _handlePathOSX(sound):
88
+ sound = _canonicalizePath(sound)
89
+
90
+ if "://" not in sound:
91
+ if not sound.startswith("/"):
92
+ from os import getcwd
93
+
94
+ sound = getcwd() + "/" + sound
95
+ sound = "file://" + sound
96
+
97
+ try:
98
+ # Don't double-encode it.
99
+ sound.encode("ascii")
100
+ return sound.replace(" ", "%20")
101
+ except UnicodeEncodeError:
102
+ try:
103
+ from urllib.parse import quote # Try the Python 3 import first...
104
+ except ImportError:
105
+ from urllib import (
106
+ quote,
107
+ ) # Try using the Python 2 import before giving up entirely...
108
+
109
+ parts = sound.split("://", 1)
110
+ return parts[0] + "://" + quote(parts[1].encode("utf-8")).replace(" ", "%20")
111
+
112
+
113
+ def _playsoundOSX(sound, block=True):
114
+ """
115
+ Utilizes AppKit.NSSound. Tested and known to work with MP3 and WAVE on
116
+ OS X 10.11 with Python 2.7. Probably works with anything QuickTime supports.
117
+ Probably works on OS X 10.5 and newer. Probably works with all versions of
118
+ Python.
119
+
120
+ Inspired by (but not copied from) Aaron's Stack Overflow answer here:
121
+ http://stackoverflow.com/a/34568298/901641
122
+
123
+ I never would have tried using AppKit.NSSound without seeing his code.
124
+ """
125
+ try:
126
+ from AppKit import NSSound
127
+ except ImportError:
128
+ logger.warning(
129
+ "playsound could not find a copy of AppKit - falling back to using macOS's system copy."
130
+ )
131
+ sys.path.append(
132
+ "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC"
133
+ )
134
+ from AppKit import NSSound
135
+
136
+ from Foundation import NSURL
137
+ from time import sleep
138
+
139
+ sound = _handlePathOSX(sound)
140
+ url = NSURL.URLWithString_(sound)
141
+ if not url:
142
+ raise PlaysoundException("Cannot find a sound with filename: " + sound)
143
+
144
+ for i in range(5):
145
+ nssound = NSSound.alloc().initWithContentsOfURL_byReference_(url, True)
146
+ if nssound:
147
+ break
148
+ else:
149
+ logger.debug("Failed to load sound, although url was good... " + sound)
150
+ else:
151
+ raise PlaysoundException(
152
+ "Could not load sound with filename, although URL was good... " + sound
153
+ )
154
+ nssound.play()
155
+
156
+ if block:
157
+ sleep(nssound.duration())
158
+
159
+
160
+ def _playsoundNix(sound, block=True):
161
+ """Play a sound using GStreamer.
162
+
163
+ Inspired by this:
164
+ https://gstreamer.freedesktop.org/documentation/tutorials/playback/playbin-usage.html
165
+ """
166
+ sound = _canonicalizePath(sound)
167
+
168
+ # pathname2url escapes non-URL-safe characters
169
+ from os.path import abspath, exists
170
+
171
+ try:
172
+ from urllib.request import pathname2url
173
+ except ImportError:
174
+ # python 2
175
+ from urllib import pathname2url
176
+
177
+ import gi
178
+
179
+ gi.require_version("Gst", "1.0")
180
+ from gi.repository import Gst
181
+
182
+ Gst.init(None)
183
+
184
+ playbin = Gst.ElementFactory.make("playbin", "playbin")
185
+ if sound.startswith(("http://", "https://")):
186
+ playbin.props.uri = sound
187
+ else:
188
+ path = abspath(sound)
189
+ if not exists(path):
190
+ raise PlaysoundException("File not found: {}".format(path))
191
+ playbin.props.uri = "file://" + pathname2url(path)
192
+
193
+ set_result = playbin.set_state(Gst.State.PLAYING)
194
+ if set_result != Gst.StateChangeReturn.ASYNC:
195
+ raise PlaysoundException("playbin.set_state returned " + repr(set_result))
196
+
197
+ # FIXME: use some other bus method than poll() with block=False
198
+ # https://lazka.github.io/pgi-docs/#Gst-1.0/classes/Bus.html
199
+ logger.debug("Starting play")
200
+ if block:
201
+ bus = playbin.get_bus()
202
+ try:
203
+ bus.poll(Gst.MessageType.EOS, Gst.CLOCK_TIME_NONE)
204
+ finally:
205
+ playbin.set_state(Gst.State.NULL)
206
+
207
+ logger.debug("Finishing play")
208
+
209
+
210
+ def _playsoundAnotherPython(otherPython, sound, block=True, macOS=False):
211
+ """
212
+ Mostly written so that when this is run on python3 on macOS, it can invoke
213
+ python2 on macOS... but maybe this idea could be useful on linux, too.
214
+ """
215
+ from inspect import getsourcefile
216
+ from os.path import abspath, exists
217
+ from subprocess import check_call
218
+ from threading import Thread
219
+
220
+ sound = _canonicalizePath(sound)
221
+
222
+ class PropogatingThread(Thread):
223
+ def run(self):
224
+ self.exc = None
225
+ try:
226
+ self.ret = self._target(*self._args, **self._kwargs)
227
+ except BaseException as e:
228
+ self.exc = e
229
+
230
+ def join(self, timeout=None):
231
+ super().join(timeout)
232
+ if self.exc:
233
+ raise self.exc
234
+ return self.ret
235
+
236
+ # Check if the file exists...
237
+ if not exists(abspath(sound)):
238
+ raise PlaysoundException("Cannot find a sound with filename: " + sound)
239
+
240
+ playsoundPath = abspath(getsourcefile(lambda: 0))
241
+ t = PropogatingThread(
242
+ target=lambda: check_call(
243
+ [otherPython, playsoundPath, _handlePathOSX(sound) if macOS else sound]
244
+ )
245
+ )
246
+ t.start()
247
+ if block:
248
+ t.join()
249
+
250
+
251
+ system = system()
252
+
253
+ if system == "Windows":
254
+ playsound = _playsoundWin
255
+ elif system == "Darwin":
256
+ playsound = _playsoundOSX
257
+ import sys
258
+
259
+ if sys.version_info[0] > 2:
260
+ try:
261
+ from AppKit import NSSound
262
+ except ImportError:
263
+ logger.warning(
264
+ "playsound is relying on a python 2 subprocess. Please use `pip3 install PyObjC` if you want playsound to run more efficiently."
265
+ )
266
+ playsound = lambda sound, block=True: _playsoundAnotherPython(
267
+ "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python",
268
+ sound,
269
+ block,
270
+ macOS=True,
271
+ )
272
+ else:
273
+ playsound = _playsoundNix
274
+ if (
275
+ __name__ != "__main__"
276
+ ): # Ensure we don't infinitely recurse trying to get another python instance.
277
+ try:
278
+ import gi
279
+
280
+ gi.require_version("Gst", "1.0")
281
+ from gi.repository import Gst
282
+ except:
283
+ logger.warning(
284
+ "playsound is relying on another python subprocess. Please use `pip install pygobject` if you want playsound to run more efficiently."
285
+ )
286
+ playsound = lambda sound, block=True: _playsoundAnotherPython(
287
+ "/usr/bin/python3", sound, block, macOS=False
288
+ )
289
+
290
+ del system
291
+
292
+ if __name__ == "__main__":
293
+ # block is always True if you choose to run this from the command line.
294
+ from sys import argv
295
+
296
+ playsound(argv[1])
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "24.5.1"
3
+ __version__ = "24.5.9"
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Display current log
3
+ not1mm Contest logger
4
+ Email: michael.bridak@gmail.com
5
+ GPL V3
6
+ Class: LogWindow
7
+ Purpose: Onscreen widget to show and edit logged contacts.
4
8
  """
5
9
  # pylint: disable=no-name-in-module, unused-import, no-member, c-extension-no-member
6
10
  # pylint: disable=logging-fstring-interpolation, too-many-lines
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ NOT1MM Logger
4
+ Purpose: test alternative sound playing interface
5
+ """
6
+ # pylint: disable=unused-import, c-extension-no-member, no-member, invalid-name, too-many-lines, no-name-in-module
7
+ # pylint: disable=logging-fstring-interpolation, logging-not-lazy, line-too-long, bare-except
8
+
9
+ from not1mm.lib.playsound import playsound
10
+
11
+ import not1mm.fsutils as fsutils
12
+
13
+ filename = fsutils.APP_DATA_PATH / "phonetics/cq.wav"
14
+
15
+ playsound(filename, True)
@@ -48,6 +48,8 @@ def interface(self):
48
48
  self.field2.show()
49
49
  self.field3.hide()
50
50
  self.field4.show()
51
+ self.snt_label.setText("SNT")
52
+ self.field1.setAccessibleName("RST Sent")
51
53
  label = self.field4.findChild(QtWidgets.QLabel)
52
54
  label.setText("Name 1010# SPC")
53
55
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -47,6 +47,8 @@ def interface(self):
47
47
  self.field2.show()
48
48
  self.field3.hide()
49
49
  self.field4.show()
50
+ self.snt_label.setText("SNT")
51
+ self.field1.setAccessibleName("RST Sent")
50
52
  label = self.field4.findChild(QtWidgets.QLabel)
51
53
  label.setText("Name 1010# SPC")
52
54
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -49,6 +49,8 @@ def interface(self):
49
49
  self.field2.show()
50
50
  self.field3.hide()
51
51
  self.field4.show()
52
+ self.snt_label.setText("SNT")
53
+ self.field1.setAccessibleName("RST Sent")
52
54
  label = self.field4.findChild(QtWidgets.QLabel)
53
55
  label.setText("Name 1010# SPC")
54
56
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -49,6 +49,8 @@ def interface(self):
49
49
  self.field2.show()
50
50
  self.field3.hide()
51
51
  self.field4.show()
52
+ self.snt_label.setText("SNT")
53
+ self.field1.setAccessibleName("RST Sent")
52
54
  label = self.field4.findChild(QtWidgets.QLabel)
53
55
  label.setText("Name 1010# SPC")
54
56
  self.field4.setAccessibleName("Name 10 10 # SPC")
@@ -94,6 +94,8 @@ def interface(self):
94
94
  self.field2.show()
95
95
  self.field3.show()
96
96
  self.field4.show()
97
+ self.snt_label.setText("SNT")
98
+ self.field1.setAccessibleName("RST Sent")
97
99
  label = self.field3.findChild(QtWidgets.QLabel)
98
100
  label.setText("SentNR")
99
101
  self.field3.setAccessibleName("Sent Number")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  label = self.field4.findChild(QtWidgets.QLabel)
57
59
  label.setText("Power")
58
60
  self.field4.setAccessibleName("Power")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  label = self.field4.findChild(QtWidgets.QLabel)
57
59
  label.setText("Power")
58
60
  self.field4.setAccessibleName("Power")
@@ -52,6 +52,8 @@ def interface(self):
52
52
  self.field2.show()
53
53
  self.field3.show()
54
54
  self.field4.show()
55
+ self.snt_label.setText("SNT")
56
+ self.field1.setAccessibleName("RST Sent")
55
57
  label = self.field3.findChild(QtWidgets.QLabel)
56
58
  label.setText("SentNR")
57
59
  self.field3.setAccessibleName("Sent Number")
@@ -52,6 +52,8 @@ def interface(self):
52
52
  self.field2.show()
53
53
  self.field3.show()
54
54
  self.field4.show()
55
+ self.snt_label.setText("SNT")
56
+ self.field1.setAccessibleName("RST Sent")
55
57
  label = self.field3.findChild(QtWidgets.QLabel)
56
58
  label.setText("SentNR")
57
59
  self.field3.setAccessibleName("Sent Number")
@@ -83,6 +83,8 @@ def interface(self):
83
83
  self.field2.show()
84
84
  self.field3.show()
85
85
  self.field4.show()
86
+ self.snt_label.setText("SNT")
87
+ self.field1.setAccessibleName("RST Sent")
86
88
  label = self.field3.findChild(QtWidgets.QLabel)
87
89
  label.setText("SentNR")
88
90
  self.field3.setAccessibleName("Sent Grid")
@@ -51,6 +51,8 @@ def interface(self):
51
51
  self.field2.show()
52
52
  self.field3.show()
53
53
  self.field4.show()
54
+ self.snt_label.setText("SNT")
55
+ self.field1.setAccessibleName("RST Sent")
54
56
  label = self.field3.findChild(QtWidgets.QLabel)
55
57
  label.setText("SentNR")
56
58
  self.field3.setAccessibleName("Sent Grid")
@@ -51,6 +51,8 @@ def interface(self):
51
51
  self.field2.show()
52
52
  self.field3.show()
53
53
  self.field4.show()
54
+ self.snt_label.setText("SNT")
55
+ self.field1.setAccessibleName("RST Sent")
54
56
  label = self.field3.findChild(QtWidgets.QLabel)
55
57
  label.setText("SentNR")
56
58
  self.field3.setAccessibleName("Sent Grid")
@@ -84,6 +84,8 @@ def interface(self):
84
84
  self.field2.show()
85
85
  self.field3.show()
86
86
  self.field4.show()
87
+ self.snt_label.setText("SNT")
88
+ self.field1.setAccessibleName("RST Sent")
87
89
  label = self.field3.findChild(QtWidgets.QLabel)
88
90
  label.setText("SentNR")
89
91
  self.field3.setAccessibleName("Sent Number")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  # self.other_label.setText("SentNR")
57
59
  # self.field3.setAccessibleName("Sent Number")
58
60
  self.exch_label.setText("ST/Prov/CQ Zone")
@@ -53,6 +53,8 @@ def interface(self):
53
53
  self.field2.show()
54
54
  self.field3.hide()
55
55
  self.field4.show()
56
+ self.snt_label.setText("SNT")
57
+ self.field1.setAccessibleName("RST Sent")
56
58
  # self.other_label.setText("SentNR")
57
59
  # self.field3.setAccessibleName("Sent Number")
58
60
  self.exch_label.setText("ST/Prov/CQ Zone")