not1mm 24.12.15__tar.gz → 25.1.1__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 (178) hide show
  1. {not1mm-24.12.15 → not1mm-25.1.1}/PKG-INFO +4 -16
  2. {not1mm-24.12.15 → not1mm-25.1.1}/README.md +3 -15
  3. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/__main__.py +4 -1
  4. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/new_contest.ui +5 -0
  5. not1mm-25.1.1/not1mm/lib/version.py +3 -0
  6. not1mm-25.1.1/not1mm/plugins/arrl_rtty_ru.py +543 -0
  7. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/general_logging.py +23 -14
  8. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm.egg-info/PKG-INFO +4 -16
  9. {not1mm-24.12.15 → not1mm-25.1.1}/pyproject.toml +1 -1
  10. not1mm-24.12.15/not1mm/lib/version.py +0 -3
  11. not1mm-24.12.15/not1mm/plugins/arrl_rtty_ru.py +0 -291
  12. {not1mm-24.12.15 → not1mm-25.1.1}/LICENSE +0 -0
  13. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/__init__.py +0 -0
  14. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/bandmap.py +0 -0
  15. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/checkwindow.py +0 -0
  16. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/JetBrainsMono-ExtraLight.ttf +0 -0
  17. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/MASTER.SCP +0 -0
  18. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/about.ui +0 -0
  19. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/alpha bravo charlie delta.txt +0 -0
  20. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/bandmap.ui +0 -0
  21. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/check.png +0 -0
  22. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/checkwindow.ui +0 -0
  23. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/configuration.ui +0 -0
  24. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/contests.sql +0 -0
  25. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/cty.json +0 -0
  26. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/cwmacros.txt +0 -0
  27. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/donors.html +0 -0
  28. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/editcontact.ui +0 -0
  29. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/editmacro.ui +0 -0
  30. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/greendot.png +0 -0
  31. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/k6gte-not1mm.desktop +0 -0
  32. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/k6gte.not1mm-128.png +0 -0
  33. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/k6gte.not1mm-32.png +0 -0
  34. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/k6gte.not1mm-64.png +0 -0
  35. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/logwindow.ui +0 -0
  36. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/logwindowx.ui +0 -0
  37. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/main.ui +0 -0
  38. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/not1mm.html +0 -0
  39. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/opon.ui +0 -0
  40. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/0.wav +0 -0
  41. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/1.wav +0 -0
  42. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/2.wav +0 -0
  43. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/3.wav +0 -0
  44. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/4.wav +0 -0
  45. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/5.wav +0 -0
  46. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/6.wav +0 -0
  47. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/7.wav +0 -0
  48. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/73.wav +0 -0
  49. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/8.wav +0 -0
  50. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/9.wav +0 -0
  51. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/a.wav +0 -0
  52. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/again.wav +0 -0
  53. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/b.wav +0 -0
  54. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/c.wav +0 -0
  55. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/contest.wav +0 -0
  56. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/cq.wav +0 -0
  57. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/cq2.wav +0 -0
  58. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/d.wav +0 -0
  59. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/e.wav +0 -0
  60. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/f.wav +0 -0
  61. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/g.wav +0 -0
  62. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/h.wav +0 -0
  63. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/i.wav +0 -0
  64. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/j.wav +0 -0
  65. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/k.wav +0 -0
  66. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/k6gte.wav +0 -0
  67. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/l.wav +0 -0
  68. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/m.wav +0 -0
  69. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/mynumber.wav +0 -0
  70. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/n.wav +0 -0
  71. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/nil.wav +0 -0
  72. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/o.wav +0 -0
  73. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/p.wav +0 -0
  74. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/q.wav +0 -0
  75. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/r.wav +0 -0
  76. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/roger.wav +0 -0
  77. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/s.wav +0 -0
  78. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/space.wav +0 -0
  79. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/t.wav +0 -0
  80. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/thankyou.wav +0 -0
  81. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
  82. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/u.wav +0 -0
  83. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/v.wav +0 -0
  84. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/w.wav +0 -0
  85. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/x.wav +0 -0
  86. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/y.wav +0 -0
  87. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/yourcall.wav +0 -0
  88. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/phonetics/z.wav +0 -0
  89. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/pickcontest.ui +0 -0
  90. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/radio_green.png +0 -0
  91. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/radio_grey.png +0 -0
  92. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/radio_red.png +0 -0
  93. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/reddot.png +0 -0
  94. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/rttymacros.txt +0 -0
  95. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/settings.ui +0 -0
  96. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/splash.png +0 -0
  97. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/ssbmacros.txt +0 -0
  98. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/data/vfo.ui +0 -0
  99. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/fsutils.py +0 -0
  100. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/__init__.py +0 -0
  101. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/about.py +0 -0
  102. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/cat_interface.py +0 -0
  103. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/cwinterface.py +0 -0
  104. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/database.py +0 -0
  105. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/edit_contact.py +0 -0
  106. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/edit_macro.py +0 -0
  107. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/edit_opon.py +0 -0
  108. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/edit_station.py +0 -0
  109. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/fldigi_sendstring.py +0 -0
  110. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/ft8_watcher.py +0 -0
  111. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/ham_utility.py +0 -0
  112. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/lookup.py +0 -0
  113. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/multicast.py +0 -0
  114. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/n1mm.py +0 -0
  115. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/new_contest.py +0 -0
  116. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/plugin_common.py +0 -0
  117. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/select_contest.py +0 -0
  118. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/settings.py +0 -0
  119. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/super_check_partial.py +0 -0
  120. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lib/versiontest.py +0 -0
  121. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/logwindow.py +0 -0
  122. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/lookupservice.py +0 -0
  123. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/10_10_fall_cw.py +0 -0
  124. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/10_10_spring_cw.py +0 -0
  125. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/10_10_summer_phone.py +0 -0
  126. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/10_10_winter_phone.py +0 -0
  127. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/__init__.py +0 -0
  128. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_10m.py +0 -0
  129. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_160m.py +0 -0
  130. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_dx_cw.py +0 -0
  131. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_dx_ssb.py +0 -0
  132. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_field_day.py +0 -0
  133. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_ss_cw.py +0 -0
  134. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_ss_phone.py +0 -0
  135. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_vhf_jan.py +0 -0
  136. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_vhf_jun.py +0 -0
  137. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/arrl_vhf_sep.py +0 -0
  138. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/canada_day.py +0 -0
  139. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_160_cw.py +0 -0
  140. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_160_ssb.py +0 -0
  141. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_wpx_cw.py +0 -0
  142. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_wpx_rtty.py +0 -0
  143. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_wpx_ssb.py +0 -0
  144. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_ww_cw.py +0 -0
  145. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_ww_rtty.py +0 -0
  146. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cq_ww_ssb.py +0 -0
  147. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/cwt.py +0 -0
  148. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/darc_xmas.py +0 -0
  149. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/helvetia.py +0 -0
  150. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/iaru_fieldday_r1_cw.py +0 -0
  151. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/iaru_fieldday_r1_ssb.py +0 -0
  152. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/iaru_hf.py +0 -0
  153. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/icwc_mst.py +0 -0
  154. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/jidx_cw.py +0 -0
  155. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/jidx_ph.py +0 -0
  156. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/k1usn_sst.py +0 -0
  157. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/lz-dx.py +0 -0
  158. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/naqp_cw.py +0 -0
  159. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/naqp_rtty.py +0 -0
  160. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/naqp_ssb.py +0 -0
  161. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/phone_weekly_test.py +0 -0
  162. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/raem.py +0 -0
  163. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/ref_cw.py +0 -0
  164. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/ref_ssb.py +0 -0
  165. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/stew_perry_topband.py +0 -0
  166. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/weekly_rtty.py +0 -0
  167. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/plugins/winter_field_day.py +0 -0
  168. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/radio.py +0 -0
  169. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/rtc_service.py +0 -0
  170. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/test.py +0 -0
  171. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/vfo.py +0 -0
  172. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm/voice_keying.py +0 -0
  173. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm.egg-info/SOURCES.txt +0 -0
  174. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm.egg-info/dependency_links.txt +0 -0
  175. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm.egg-info/entry_points.txt +0 -0
  176. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm.egg-info/requires.txt +0 -0
  177. {not1mm-24.12.15 → not1mm-25.1.1}/not1mm.egg-info/top_level.txt +0 -0
  178. {not1mm-24.12.15 → not1mm-25.1.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: not1mm
3
- Version: 24.12.15
3
+ Version: 25.1.1
4
4
  Summary: NOT1MM Logger
5
5
  Author-email: Michael Bridak <michael.bridak@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/mbridak/not1mm
@@ -214,6 +214,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
214
214
  - ARRL 160M
215
215
  - ARRL DX CW, SSB
216
216
  - ARRL Field Day
217
+ - ARRL RTTY Roundup
217
218
  - ARRL Sweepstakes CW, SSB
218
219
  - ARRL VHF January, June, September
219
220
  - CQ 160 CW, SSB
@@ -239,21 +240,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
239
240
 
240
241
  ## Recent Changes (Polishing the Turd)
241
242
 
242
- - [24-12-15] Fixed Button focus policy in the bandmap window.
243
- - [24-12-14] Changed method of detecting fldigi QSOs. See docs.
244
- - [24-12-12] Add a try exception for a unicode decode error.
245
- - [24-12-11-1] Add RTC to RAC Canada Day, ARRL VHF, ARRL Field Day, ARRL SS, ARRL DX, 10 10
246
- - [24-12-11] Add RTC to IARU HF, IARU Field Day, DARC XMAS, CQ WW, CQ WPX
247
- - [24-12-9] Add RTC to Winter Field Day, Stew Perry, REF, RAEM, NAQP, LZ-DX, JIDX
248
- - [24-12-8-2] Add RTC to ARRL 10M, Tweaked cabrillo file output.
249
- - [24-12-8-1] Changed cabrillo names for Weekly RTTY, CW Ops CWT and K1USN SST.
250
- - [24-12-8] Fix: Weekly RTTY mults. Add RTC to Weekly RTTY.
251
- - [24-12-6] Add RTC to K1USN.
252
- -[24-12-5-1] ARRL 160 gets rtc.
253
- - [24-12-5] Add 'real time' score posting to external sites.
254
- - [24-12-4] Merged PR from @alduhoo Add STATION_CALLSIGN field to ADIF output
255
- - [24-12-3-1] Adding ARRL 160
256
- - [24-12-3] Add button to bandmap to delete marked spots.
243
+ - [25-1-1] Added ARRL RTTY RU.
257
244
 
258
245
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
259
246
 
@@ -688,6 +675,7 @@ You can include a limited set of substitution instructions.
688
675
  | {SNT} | Sends 5nn (cw) or 599 (ssb) |
689
676
  | {SENTNR} | Sends whats in the SentNR field. |
690
677
  | {EXCH} | Sends what's in the Sent Exchange field when contest is defined. |
678
+ | {LOGIT} | Log the contact after macro pressed. |
691
679
  | '#' | Sends serial number. |
692
680
 
693
681
  ### Macro use with voice
@@ -183,6 +183,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
183
183
  - ARRL 160M
184
184
  - ARRL DX CW, SSB
185
185
  - ARRL Field Day
186
+ - ARRL RTTY Roundup
186
187
  - ARRL Sweepstakes CW, SSB
187
188
  - ARRL VHF January, June, September
188
189
  - CQ 160 CW, SSB
@@ -208,21 +209,7 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
208
209
 
209
210
  ## Recent Changes (Polishing the Turd)
210
211
 
211
- - [24-12-15] Fixed Button focus policy in the bandmap window.
212
- - [24-12-14] Changed method of detecting fldigi QSOs. See docs.
213
- - [24-12-12] Add a try exception for a unicode decode error.
214
- - [24-12-11-1] Add RTC to RAC Canada Day, ARRL VHF, ARRL Field Day, ARRL SS, ARRL DX, 10 10
215
- - [24-12-11] Add RTC to IARU HF, IARU Field Day, DARC XMAS, CQ WW, CQ WPX
216
- - [24-12-9] Add RTC to Winter Field Day, Stew Perry, REF, RAEM, NAQP, LZ-DX, JIDX
217
- - [24-12-8-2] Add RTC to ARRL 10M, Tweaked cabrillo file output.
218
- - [24-12-8-1] Changed cabrillo names for Weekly RTTY, CW Ops CWT and K1USN SST.
219
- - [24-12-8] Fix: Weekly RTTY mults. Add RTC to Weekly RTTY.
220
- - [24-12-6] Add RTC to K1USN.
221
- -[24-12-5-1] ARRL 160 gets rtc.
222
- - [24-12-5] Add 'real time' score posting to external sites.
223
- - [24-12-4] Merged PR from @alduhoo Add STATION_CALLSIGN field to ADIF output
224
- - [24-12-3-1] Adding ARRL 160
225
- - [24-12-3] Add button to bandmap to delete marked spots.
212
+ - [25-1-1] Added ARRL RTTY RU.
226
213
 
227
214
  See [CHANGELOG.md](CHANGELOG.md) for prior changes.
228
215
 
@@ -657,6 +644,7 @@ You can include a limited set of substitution instructions.
657
644
  | {SNT} | Sends 5nn (cw) or 599 (ssb) |
658
645
  | {SENTNR} | Sends whats in the SentNR field. |
659
646
  | {EXCH} | Sends what's in the Sent Exchange field when contest is defined. |
647
+ | {LOGIT} | Log the contact after macro pressed. |
660
648
  | '#' | Sends serial number. |
661
649
 
662
650
  ### Macro use with voice
@@ -1742,7 +1742,7 @@ class MainWindow(QtWidgets.QMainWindow):
1742
1742
  """
1743
1743
 
1744
1744
  self.show_message_box(
1745
- "[CTRL-Esc]\tStops cwdaemon from sending Morse.\n"
1745
+ "[ESC]\tStops cwdaemon from sending Morse.\n"
1746
1746
  "[PgUp]\tIncreases the cw sending speed.\n"
1747
1747
  "[PgDown]\tDecreases the cw sending speed.\n"
1748
1748
  "[Arrow-Up] Jump to the next spot above the current VFO cursor\n"
@@ -2731,6 +2731,9 @@ class MainWindow(QtWidgets.QMainWindow):
2731
2731
  macro = macro.replace(
2732
2732
  "{EXCH}", self.contest_settings.get("SentExchange", "xxx")
2733
2733
  )
2734
+ if "{LOGIT}" in macro:
2735
+ macro = macro.replace("{LOGIT}", "")
2736
+ self.save_contact()
2734
2737
  return macro
2735
2738
 
2736
2739
  def ptt_on(self) -> None:
@@ -237,6 +237,11 @@
237
237
  <string>ARRL FIELD DAY</string>
238
238
  </property>
239
239
  </item>
240
+ <item>
241
+ <property name="text">
242
+ <string>ARRL RTTY RU</string>
243
+ </property>
244
+ </item>
240
245
  <item>
241
246
  <property name="text">
242
247
  <string>ARRL SS CW</string>
@@ -0,0 +1,3 @@
1
+ """It's the version"""
2
+
3
+ __version__ = "25.1.1"
@@ -0,0 +1,543 @@
1
+ """
2
+ Mode: RTTY
3
+ Bands: 80, 40, 20, 15, 10m
4
+ Classes: Single Op (QRP/Low/High)
5
+ Single Op Unlimited (QRP/Low/High)
6
+ Single Op Overlay: (Limited Antennas)
7
+ Multi-Single (Low/High)
8
+ Multi-Two
9
+ Multi-Multi
10
+ Max operating hours: 24 hours
11
+ Max power: HP: 1500 watts
12
+ LP: 100 watts
13
+ Exchange: W/VE: RST + (state/province)
14
+ non-W/VE: RST + Serial No.
15
+ Work stations: Once per band
16
+ QSO Points: 1 point per QSO
17
+ Multipliers: Each US state+DC (except KH6/KL7) once only
18
+ Each VE province/territory once only
19
+ Each DXCC country (including KH6/KL7) once only
20
+ Score Calculation: Total score = total QSO points x total mults
21
+ Submit logs by: 2359Z January 12, 2025
22
+ E-mail logs to: (none)
23
+ Upload log at: https://contest-log-submission.arrl.org/
24
+ Mail logs to: RTTY Roundup
25
+ ARRL
26
+ 225 Main St.
27
+ Newington, CT 06111
28
+ USA
29
+ Find rules at: https://www.arrl.org/rtty-roundup
30
+
31
+
32
+ """
33
+
34
+ # pylint: disable=invalid-name, unused-argument, unused-variable, c-extension-no-member
35
+
36
+ import datetime
37
+ import logging
38
+
39
+ from pathlib import Path
40
+ from PyQt6 import QtWidgets
41
+
42
+ from not1mm.lib.plugin_common import gen_adif, get_points, online_score_xml
43
+ from not1mm.lib.version import __version__
44
+
45
+ logger = logging.getLogger(__name__)
46
+
47
+ EXCHANGE_HINT = "State/Province or #"
48
+
49
+ name = "ARRL RTTY Roundup"
50
+ mode = "RTTY" # CW SSB BOTH RTTY
51
+ cabrillo_name = "ARRL-RTTY"
52
+
53
+ columns = [
54
+ "YYYY-MM-DD HH:MM:SS",
55
+ "Call",
56
+ "Freq",
57
+ "Snt",
58
+ "Rcv",
59
+ "SentNr",
60
+ "RcvNr",
61
+ "PTS",
62
+ ]
63
+
64
+ advance_on_space = [True, True, True, True, True]
65
+
66
+ # 1 once per contest, 2 work each band, 3 each band/mode, 4 no dupe checking
67
+ dupe_type = 2
68
+
69
+
70
+ def init_contest(self):
71
+ """setup plugin"""
72
+ set_tab_next(self)
73
+ set_tab_prev(self)
74
+ interface(self)
75
+ self.next_field = self.other_2
76
+
77
+
78
+ def interface(self):
79
+ """Setup user interface"""
80
+ self.field1.show()
81
+ self.field2.show()
82
+ self.field3.show()
83
+ self.field4.show()
84
+ self.snt_label.setText("SNT")
85
+ self.field1.setAccessibleName("RST Sent")
86
+ # label = self.field3.findChild(QtWidgets.QLabel)
87
+ self.other_label.setText("SentNR")
88
+ self.field3.setAccessibleName("Sent Number")
89
+ # label = self.field4.findChild(QtWidgets.QLabel)
90
+ self.exch_label.setText("State|Prov|SN")
91
+ self.field4.setAccessibleName("State Province or Serial Number")
92
+
93
+
94
+ def reset_label(self):
95
+ """reset label after field cleared"""
96
+
97
+
98
+ def set_tab_next(self):
99
+ """Set TAB Advances"""
100
+ self.tab_next = {
101
+ self.callsign: self.sent,
102
+ self.sent: self.receive,
103
+ self.receive: self.other_1,
104
+ self.other_1: self.other_2,
105
+ self.other_2: self.callsign,
106
+ }
107
+
108
+
109
+ def set_tab_prev(self):
110
+ """Set TAB Advances"""
111
+ self.tab_prev = {
112
+ self.callsign: self.other_2,
113
+ self.sent: self.callsign,
114
+ self.receive: self.sent,
115
+ self.other_1: self.receive,
116
+ self.other_2: self.other_1,
117
+ }
118
+
119
+
120
+ def validate(self):
121
+ """doc"""
122
+ # exchange = self.other_2.text().upper().split()
123
+ # if len(exchange) == 3:
124
+ # if exchange[0].isalpha() and exchange[1].isdigit() and exchange[2].isalpha():
125
+ # return True
126
+ # return False
127
+ return True
128
+
129
+
130
+ def set_contact_vars(self):
131
+ """Contest Specific"""
132
+ self.contact["SNT"] = self.sent.text()
133
+ self.contact["RCV"] = self.receive.text()
134
+ self.contact["NR"] = self.other_2.text().upper()
135
+ self.contact["SentNr"] = self.other_1.text()
136
+
137
+
138
+ def predupe(self):
139
+ """called after callsign entered"""
140
+
141
+
142
+ def prefill(self):
143
+ """Fill sentnr"""
144
+ result = self.database.get_serial()
145
+ serial_nr = str(result.get("serial_nr", "1")).zfill(3)
146
+ if serial_nr == "None":
147
+ serial_nr = "001"
148
+
149
+ exchange = self.contest_settings.get("SentExchange", "").replace("#", serial_nr)
150
+ if len(self.other_1.text()) == 0:
151
+ self.other_1.setText(exchange)
152
+
153
+
154
+ def points(self):
155
+ """Calc point"""
156
+ return 1
157
+
158
+
159
+ def show_mults(self, rtc=None):
160
+ """Return display string for mults"""
161
+ # CountryPrefix, integer
162
+
163
+ us_ve = 0
164
+ dx = 0
165
+
166
+ sql = (
167
+ "select count(DISTINCT(NR || ':' || Mode)) as mult_count "
168
+ f"from dxlog where ContestNR = {self.database.current_contest} and typeof(NR) = 'text';"
169
+ )
170
+ result = self.database.exec_sql(sql)
171
+ if result:
172
+ us_ve = result.get("mult_count", 0)
173
+
174
+ # DX
175
+ sql = (
176
+ "select count(DISTINCT(CountryPrefix || ':' || Mode)) as mult_count "
177
+ f"from dxlog where ContestNR = {self.database.current_contest} "
178
+ "and typeof(NR) = 'integer';"
179
+ )
180
+ result = self.database.exec_sql(sql)
181
+ if result:
182
+ dx = result.get("mult_count", 0)
183
+
184
+ if rtc is not None:
185
+ return dx, us_ve
186
+
187
+ return us_ve + dx
188
+
189
+
190
+ def show_qso(self):
191
+ """Return qso count"""
192
+ result = self.database.fetch_qso_count()
193
+ if result:
194
+ return int(result.get("qsos", 0))
195
+ return 0
196
+
197
+
198
+ def calc_score(self):
199
+ """Return calculated score"""
200
+ # Multipliers: Each US State + DC once per mode
201
+ _points = get_points(self)
202
+ _mults = show_mults(self)
203
+ _power_mult = 1
204
+ # if self.contest_settings.get("PowerCategory", "") == "QRP":
205
+ # _power_mult = 2
206
+ return _points * _power_mult * _mults
207
+
208
+
209
+ def adif(self):
210
+ """Call the generate ADIF function"""
211
+ gen_adif(self, cabrillo_name)
212
+
213
+
214
+ def output_cabrillo_line(line_to_output, ending, file_descriptor, file_encoding):
215
+ """"""
216
+ print(
217
+ line_to_output.encode(file_encoding, errors="ignore").decode(),
218
+ end=ending,
219
+ file=file_descriptor,
220
+ )
221
+
222
+
223
+ def cabrillo(self, file_encoding):
224
+ """Generates Cabrillo file. Maybe."""
225
+ # https://www.cqwpx.com/cabrillo.htm
226
+ logger.debug("******Cabrillo*****")
227
+ logger.debug("Station: %s", f"{self.station}")
228
+ logger.debug("Contest: %s", f"{self.contest_settings}")
229
+ now = datetime.datetime.now()
230
+ date_time = now.strftime("%Y-%m-%d_%H-%M-%S")
231
+ filename = (
232
+ str(Path.home())
233
+ + "/"
234
+ + f"{self.station.get('Call', '').upper()}_{cabrillo_name}_{date_time}.log"
235
+ )
236
+ logger.debug("%s", filename)
237
+ log = self.database.fetch_all_contacts_asc()
238
+ try:
239
+ with open(filename, "w", encoding=file_encoding) as file_descriptor:
240
+ output_cabrillo_line(
241
+ "START-OF-LOG: 3.0",
242
+ "\r\n",
243
+ file_descriptor,
244
+ file_encoding,
245
+ )
246
+ output_cabrillo_line(
247
+ f"CREATED-BY: Not1MM v{__version__}",
248
+ "\r\n",
249
+ file_descriptor,
250
+ file_encoding,
251
+ )
252
+ output_cabrillo_line(
253
+ f"CONTEST: {cabrillo_name}",
254
+ "\r\n",
255
+ file_descriptor,
256
+ file_encoding,
257
+ )
258
+ if self.station.get("Club", ""):
259
+ output_cabrillo_line(
260
+ f"CLUB: {self.station.get('Club', '')}",
261
+ "\r\n",
262
+ file_descriptor,
263
+ file_encoding,
264
+ )
265
+ output_cabrillo_line(
266
+ f"CALLSIGN: {self.station.get('Call','')}",
267
+ "\r\n",
268
+ file_descriptor,
269
+ file_encoding,
270
+ )
271
+ output_cabrillo_line(
272
+ f"LOCATION: {self.station.get('ARRLSection', '')}",
273
+ "\r\n",
274
+ file_descriptor,
275
+ file_encoding,
276
+ )
277
+ output_cabrillo_line(
278
+ f"CATEGORY-OPERATOR: {self.contest_settings.get('OperatorCategory','')}",
279
+ "\r\n",
280
+ file_descriptor,
281
+ file_encoding,
282
+ )
283
+ output_cabrillo_line(
284
+ f"CATEGORY-ASSISTED: {self.contest_settings.get('AssistedCategory','')}",
285
+ "\r\n",
286
+ file_descriptor,
287
+ file_encoding,
288
+ )
289
+ output_cabrillo_line(
290
+ f"CATEGORY-BAND: {self.contest_settings.get('BandCategory','')}",
291
+ "\r\n",
292
+ file_descriptor,
293
+ file_encoding,
294
+ )
295
+ mode = self.contest_settings.get("ModeCategory", "")
296
+ if mode in ["SSB+CW", "SSB+CW+DIGITAL"]:
297
+ mode = "MIXED"
298
+ output_cabrillo_line(
299
+ f"CATEGORY-MODE: {mode}",
300
+ "\r\n",
301
+ file_descriptor,
302
+ file_encoding,
303
+ )
304
+ output_cabrillo_line(
305
+ f"CATEGORY-TRANSMITTER: {self.contest_settings.get('TransmitterCategory','')}",
306
+ "\r\n",
307
+ file_descriptor,
308
+ file_encoding,
309
+ )
310
+ if self.contest_settings.get("OverlayCategory", "") != "N/A":
311
+ output_cabrillo_line(
312
+ f"CATEGORY-OVERLAY: {self.contest_settings.get('OverlayCategory','')}",
313
+ "\r\n",
314
+ file_descriptor,
315
+ file_encoding,
316
+ )
317
+ output_cabrillo_line(
318
+ f"GRID-LOCATOR: {self.station.get('GridSquare','')}",
319
+ "\r\n",
320
+ file_descriptor,
321
+ file_encoding,
322
+ )
323
+ output_cabrillo_line(
324
+ f"CATEGORY-POWER: {self.contest_settings.get('PowerCategory','')}",
325
+ "\r\n",
326
+ file_descriptor,
327
+ file_encoding,
328
+ )
329
+
330
+ output_cabrillo_line(
331
+ f"CLAIMED-SCORE: {calc_score(self)}",
332
+ "\r\n",
333
+ file_descriptor,
334
+ file_encoding,
335
+ )
336
+ ops = f"@{self.station.get('Call','')}"
337
+ list_of_ops = self.database.get_ops()
338
+ for op in list_of_ops:
339
+ ops += f", {op.get('Operator', '')}"
340
+ output_cabrillo_line(
341
+ f"OPERATORS: {ops}",
342
+ "\r\n",
343
+ file_descriptor,
344
+ file_encoding,
345
+ )
346
+ output_cabrillo_line(
347
+ f"NAME: {self.station.get('Name', '')}",
348
+ "\r\n",
349
+ file_descriptor,
350
+ file_encoding,
351
+ )
352
+ output_cabrillo_line(
353
+ f"ADDRESS: {self.station.get('Street1', '')}",
354
+ "\r\n",
355
+ file_descriptor,
356
+ file_encoding,
357
+ )
358
+ output_cabrillo_line(
359
+ f"ADDRESS-CITY: {self.station.get('City', '')}",
360
+ "\r\n",
361
+ file_descriptor,
362
+ file_encoding,
363
+ )
364
+ output_cabrillo_line(
365
+ f"ADDRESS-STATE-PROVINCE: {self.station.get('State', '')}",
366
+ "\r\n",
367
+ file_descriptor,
368
+ file_encoding,
369
+ )
370
+ output_cabrillo_line(
371
+ f"ADDRESS-POSTALCODE: {self.station.get('Zip', '')}",
372
+ "\r\n",
373
+ file_descriptor,
374
+ file_encoding,
375
+ )
376
+ output_cabrillo_line(
377
+ f"ADDRESS-COUNTRY: {self.station.get('Country', '')}",
378
+ "\r\n",
379
+ file_descriptor,
380
+ file_encoding,
381
+ )
382
+ output_cabrillo_line(
383
+ f"EMAIL: {self.station.get('Email', '')}",
384
+ "\r\n",
385
+ file_descriptor,
386
+ file_encoding,
387
+ )
388
+ for contact in log:
389
+ the_date_and_time = contact.get("TS", "")
390
+ themode = contact.get("Mode", "")
391
+ if themode == "LSB" or themode == "USB":
392
+ themode = "PH"
393
+ frequency = str(int(contact.get("Freq", "0"))).rjust(5)
394
+
395
+ loggeddate = the_date_and_time[:10]
396
+ loggedtime = the_date_and_time[11:13] + the_date_and_time[14:16]
397
+ output_cabrillo_line(
398
+ f"QSO: {frequency} {themode} {loggeddate} {loggedtime} "
399
+ f"{contact.get('StationPrefix', '').ljust(13)} "
400
+ f"{str(contact.get('SNT', '')).ljust(3)} "
401
+ f"{str(contact.get('SentNr', '')).ljust(6)} "
402
+ f"{contact.get('Call', '').ljust(13)} "
403
+ f"{str(contact.get('RCV', '')).ljust(3)} "
404
+ f"{str(contact.get('NR', '')).ljust(6)}",
405
+ "\r\n",
406
+ file_descriptor,
407
+ file_encoding,
408
+ )
409
+ output_cabrillo_line("END-OF-LOG:", "\r\n", file_descriptor, file_encoding)
410
+ self.show_message_box(f"Cabrillo saved to: {filename}")
411
+ except IOError as exception:
412
+ logger.critical("cabrillo: IO error: %s, writing to %s", exception, filename)
413
+ self.show_message_box(f"Error saving Cabrillo: {exception} {filename}")
414
+ return
415
+
416
+
417
+ def recalculate_mults(self):
418
+ """Recalculates multipliers after change in logged qso."""
419
+
420
+
421
+ def process_esm(self, new_focused_widget=None, with_enter=False):
422
+ """ESM State Machine"""
423
+
424
+ # self.pref["run_state"]
425
+
426
+ # -----===== Assigned F-Keys =====-----
427
+ # self.esm_dict["CQ"]
428
+ # self.esm_dict["EXCH"]
429
+ # self.esm_dict["QRZ"]
430
+ # self.esm_dict["AGN"]
431
+ # self.esm_dict["HISCALL"]
432
+ # self.esm_dict["MYCALL"]
433
+ # self.esm_dict["QSOB4"]
434
+
435
+ # ----==== text fields ====----
436
+ # self.callsign
437
+ # self.sent
438
+ # self.receive
439
+ # self.other_1
440
+ # self.other_2
441
+
442
+ if new_focused_widget is not None:
443
+ self.current_widget = self.inputs_dict.get(new_focused_widget)
444
+
445
+ # print(f"checking esm {self.current_widget=} {with_enter=} {self.pref.get("run_state")=}")
446
+
447
+ for a_button in [
448
+ self.esm_dict["CQ"],
449
+ self.esm_dict["EXCH"],
450
+ self.esm_dict["QRZ"],
451
+ self.esm_dict["AGN"],
452
+ self.esm_dict["HISCALL"],
453
+ self.esm_dict["MYCALL"],
454
+ self.esm_dict["QSOB4"],
455
+ ]:
456
+ if a_button is not None:
457
+ self.restore_button_color(a_button)
458
+
459
+ buttons_to_send = []
460
+
461
+ if self.pref.get("run_state"):
462
+ if self.current_widget == "callsign":
463
+ if len(self.callsign.text()) < 3:
464
+ self.make_button_green(self.esm_dict["CQ"])
465
+ buttons_to_send.append(self.esm_dict["CQ"])
466
+ elif len(self.callsign.text()) > 2:
467
+ self.make_button_green(self.esm_dict["HISCALL"])
468
+ self.make_button_green(self.esm_dict["EXCH"])
469
+ buttons_to_send.append(self.esm_dict["HISCALL"])
470
+ buttons_to_send.append(self.esm_dict["EXCH"])
471
+
472
+ elif self.current_widget in ["other_2"]:
473
+ if self.other_2.text() == "":
474
+ self.make_button_green(self.esm_dict["AGN"])
475
+ buttons_to_send.append(self.esm_dict["AGN"])
476
+ else:
477
+ self.make_button_green(self.esm_dict["QRZ"])
478
+ buttons_to_send.append(self.esm_dict["QRZ"])
479
+ buttons_to_send.append("LOGIT")
480
+
481
+ if with_enter is True and bool(len(buttons_to_send)):
482
+ for button in buttons_to_send:
483
+ if button:
484
+ if button == "LOGIT":
485
+ self.save_contact()
486
+ continue
487
+ if button == self.esm_dict["HISCALL"]:
488
+ self.process_function_key(button, rttysendrx=False)
489
+ continue
490
+ self.process_function_key(button)
491
+ else:
492
+ if self.current_widget == "callsign":
493
+ if len(self.callsign.text()) > 2:
494
+ self.make_button_green(self.esm_dict["MYCALL"])
495
+ buttons_to_send.append(self.esm_dict["MYCALL"])
496
+
497
+ elif self.current_widget in ["other_2"]:
498
+ if self.other_2.text() == "":
499
+ self.make_button_green(self.esm_dict["AGN"])
500
+ buttons_to_send.append(self.esm_dict["AGN"])
501
+ else:
502
+ self.make_button_green(self.esm_dict["EXCH"])
503
+ buttons_to_send.append(self.esm_dict["EXCH"])
504
+ buttons_to_send.append("LOGIT")
505
+
506
+ if with_enter is True and bool(len(buttons_to_send)):
507
+ for button in buttons_to_send:
508
+ if button:
509
+ if button == "LOGIT":
510
+ self.save_contact()
511
+ continue
512
+ self.process_function_key(button)
513
+
514
+
515
+ def populate_history_info_line(self):
516
+ result = self.database.fetch_call_history(self.callsign.text())
517
+ if result:
518
+ self.history_info.setText(
519
+ f"{result.get('Call', '')}, {result.get('Name', '')}, {result.get('State', '')}, {result.get('UserText','...')}"
520
+ )
521
+ else:
522
+ self.history_info.setText("")
523
+
524
+
525
+ def check_call_history(self):
526
+ """"""
527
+ result = self.database.fetch_call_history(self.callsign.text())
528
+ if result:
529
+ self.history_info.setText(f"{result.get('UserText','')}")
530
+ if self.other_2.text() == "":
531
+ self.other_2.setText(f"{result.get('State', '')}")
532
+
533
+
534
+ def get_mults(self):
535
+ """"""
536
+ mults = {}
537
+ mults["country"], mults["state"] = show_mults(self, rtc=True)
538
+ return mults
539
+
540
+
541
+ def just_points(self):
542
+ """"""
543
+ return get_points(self)