not1mm 25.6.8__tar.gz → 25.6.10__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 (201) hide show
  1. {not1mm-25.6.8 → not1mm-25.6.10}/PKG-INFO +3 -1
  2. {not1mm-25.6.8 → not1mm-25.6.10}/README.md +2 -0
  3. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/dxcc_tracker.ui +1 -1
  4. not1mm-25.6.10/not1mm/dxcc_tracker.py +139 -0
  5. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/database.py +28 -0
  6. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/ham_utility.py +8 -5
  7. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/version.py +1 -1
  8. not1mm-25.6.10/not1mm/test.py +5 -0
  9. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm.egg-info/PKG-INFO +3 -1
  10. {not1mm-25.6.8 → not1mm-25.6.10}/pyproject.toml +1 -1
  11. not1mm-25.6.8/not1mm/dxcc_tracker.py +0 -132
  12. not1mm-25.6.8/not1mm/test.py +0 -37
  13. {not1mm-25.6.8 → not1mm-25.6.10}/LICENSE +0 -0
  14. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/__init__.py +0 -0
  15. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/__main__.py +0 -0
  16. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/bandmap.py +0 -0
  17. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/checkwindow.py +0 -0
  18. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/JetBrainsMono-Thin.ttf +0 -0
  19. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/MASTER.SCP +0 -0
  20. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/about.ui +0 -0
  21. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/alpha bravo charlie delta.txt +0 -0
  22. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/bandmap.ui +0 -0
  23. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/check.png +0 -0
  24. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/checkwindow.ui +0 -0
  25. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/cloud_green.png +0 -0
  26. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/cloud_red.png +0 -0
  27. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/configuration.ui +0 -0
  28. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/contests.sql +0 -0
  29. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/cty.json +0 -0
  30. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/cwmacros.txt +0 -0
  31. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/donors.html +0 -0
  32. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/editcontact.ui +0 -0
  33. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/editmacro.ui +0 -0
  34. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/greendot.png +0 -0
  35. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/k6gte-not1mm.desktop +0 -0
  36. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/k6gte.not1mm-128.png +0 -0
  37. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/k6gte.not1mm-32.png +0 -0
  38. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/k6gte.not1mm-64.png +0 -0
  39. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/logwindow.ui +0 -0
  40. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/logwindowx.ui +0 -0
  41. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/main.ui +0 -0
  42. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/new_contest.ui +0 -0
  43. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/not1mm.html +0 -0
  44. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/opon.ui +0 -0
  45. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/0.wav +0 -0
  46. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/1.wav +0 -0
  47. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/2.wav +0 -0
  48. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/3.wav +0 -0
  49. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/4.wav +0 -0
  50. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/5.wav +0 -0
  51. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/6.wav +0 -0
  52. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/7.wav +0 -0
  53. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/73.wav +0 -0
  54. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/8.wav +0 -0
  55. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/9.wav +0 -0
  56. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/a.wav +0 -0
  57. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/again.wav +0 -0
  58. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/b.wav +0 -0
  59. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/c.wav +0 -0
  60. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/contest.wav +0 -0
  61. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/cq.wav +0 -0
  62. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/cq2.wav +0 -0
  63. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/d.wav +0 -0
  64. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/e.wav +0 -0
  65. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/f.wav +0 -0
  66. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/g.wav +0 -0
  67. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/h.wav +0 -0
  68. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/i.wav +0 -0
  69. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/j.wav +0 -0
  70. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/k.wav +0 -0
  71. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/k6gte.wav +0 -0
  72. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/l.wav +0 -0
  73. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/m.wav +0 -0
  74. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/mynumber.wav +0 -0
  75. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/n.wav +0 -0
  76. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/nil.wav +0 -0
  77. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/o.wav +0 -0
  78. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/p.wav +0 -0
  79. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/q.wav +0 -0
  80. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/r.wav +0 -0
  81. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/roger.wav +0 -0
  82. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/s.wav +0 -0
  83. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/space.wav +0 -0
  84. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/t.wav +0 -0
  85. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/thankyou.wav +0 -0
  86. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
  87. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/u.wav +0 -0
  88. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/v.wav +0 -0
  89. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/w.wav +0 -0
  90. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/x.wav +0 -0
  91. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/y.wav +0 -0
  92. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/yourcall.wav +0 -0
  93. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/phonetics/z.wav +0 -0
  94. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/pickcontest.ui +0 -0
  95. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/radio_green.png +0 -0
  96. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/radio_grey.png +0 -0
  97. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/radio_red.png +0 -0
  98. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/ratewindow.ui +0 -0
  99. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/reddot.png +0 -0
  100. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/rttymacros.txt +0 -0
  101. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/settings.ui +0 -0
  102. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/splash.png +0 -0
  103. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/ssbmacros.txt +0 -0
  104. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/statistics.ui +0 -0
  105. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/data/vfo.ui +0 -0
  106. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/fsutils.py +0 -0
  107. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/__init__.py +0 -0
  108. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/about.py +0 -0
  109. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/cat_interface.py +0 -0
  110. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/cwinterface.py +0 -0
  111. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/edit_contact.py +0 -0
  112. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/edit_macro.py +0 -0
  113. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/edit_opon.py +0 -0
  114. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/edit_station.py +0 -0
  115. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/fldigi_sendstring.py +0 -0
  116. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/ft8_watcher.py +0 -0
  117. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/lookup.py +0 -0
  118. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/multicast.py +0 -0
  119. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/n1mm.py +0 -0
  120. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/new_contest.py +0 -0
  121. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/plugin_common.py +0 -0
  122. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/select_contest.py +0 -0
  123. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/settings.py +0 -0
  124. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/super_check_partial.py +0 -0
  125. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lib/versiontest.py +0 -0
  126. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/logwindow.py +0 -0
  127. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/lookupservice.py +0 -0
  128. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/10_10_fall_cw.py +0 -0
  129. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/10_10_spring_cw.py +0 -0
  130. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/10_10_summer_phone.py +0 -0
  131. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/10_10_winter_phone.py +0 -0
  132. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/__init__.py +0 -0
  133. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ari_40_80.py +0 -0
  134. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ari_dx.py +0 -0
  135. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_10m.py +0 -0
  136. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_160m.py +0 -0
  137. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_dx_cw.py +0 -0
  138. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_dx_ssb.py +0 -0
  139. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_field_day.py +0 -0
  140. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_rtty_ru.py +0 -0
  141. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_ss_cw.py +0 -0
  142. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_ss_phone.py +0 -0
  143. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_vhf_jan.py +0 -0
  144. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_vhf_jun.py +0 -0
  145. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/arrl_vhf_sep.py +0 -0
  146. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/canada_day.py +0 -0
  147. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_160_cw.py +0 -0
  148. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_160_ssb.py +0 -0
  149. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_wpx_cw.py +0 -0
  150. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_wpx_rtty.py +0 -0
  151. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_wpx_ssb.py +0 -0
  152. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_ww_cw.py +0 -0
  153. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_ww_rtty.py +0 -0
  154. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cq_ww_ssb.py +0 -0
  155. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/cwt.py +0 -0
  156. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/darc_vhf.py +0 -0
  157. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/darc_xmas.py +0 -0
  158. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ea_majistad_cw.py +0 -0
  159. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ea_majistad_ssb.py +0 -0
  160. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ea_rtty.py +0 -0
  161. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/es_field_day.py +0 -0
  162. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/es_open.py +0 -0
  163. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/general_logging.py +0 -0
  164. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/helvetia.py +0 -0
  165. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/iaru_fieldday_r1_cw.py +0 -0
  166. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/iaru_fieldday_r1_ssb.py +0 -0
  167. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/iaru_hf.py +0 -0
  168. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/icwc_mst.py +0 -0
  169. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/jidx_cw.py +0 -0
  170. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/jidx_ph.py +0 -0
  171. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/k1usn_sst.py +0 -0
  172. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/labre_rs_digi.py +0 -0
  173. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/lz-dx.py +0 -0
  174. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/naqp_cw.py +0 -0
  175. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/naqp_rtty.py +0 -0
  176. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/naqp_ssb.py +0 -0
  177. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/phone_weekly_test.py +0 -0
  178. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/raem.py +0 -0
  179. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/randomgram.py +0 -0
  180. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ref_cw.py +0 -0
  181. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ref_ssb.py +0 -0
  182. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/sac_cw.py +0 -0
  183. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/sac_ssb.py +0 -0
  184. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/spdx.py +0 -0
  185. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/stew_perry_topband.py +0 -0
  186. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/ukeidx.py +0 -0
  187. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/vhf_sprint.py +0 -0
  188. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/weekly_rtty.py +0 -0
  189. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/plugins/winter_field_day.py +0 -0
  190. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/radio.py +0 -0
  191. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/ratewindow.py +0 -0
  192. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/rtc_service.py +0 -0
  193. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/statistics.py +0 -0
  194. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/vfo.py +0 -0
  195. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm/voice_keying.py +0 -0
  196. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm.egg-info/SOURCES.txt +0 -0
  197. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm.egg-info/dependency_links.txt +0 -0
  198. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm.egg-info/entry_points.txt +0 -0
  199. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm.egg-info/requires.txt +0 -0
  200. {not1mm-25.6.8 → not1mm-25.6.10}/not1mm.egg-info/top_level.txt +0 -0
  201. {not1mm-25.6.8 → not1mm-25.6.10}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: not1mm
3
- Version: 25.6.8
3
+ Version: 25.6.10
4
4
  Summary: NOT1MM Logger
5
5
  Author-email: Michael Bridak <michael.bridak@gmail.com>
6
6
  License: GPL-3.0-or-later
@@ -245,7 +245,9 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
245
245
 
246
246
  ## Recent Changes
247
247
 
248
+ - [25-6-10] Merged PR from @dj1yfk correcting WPX prefix calculation.
248
249
  - [25-6-8] Revmoved SQLite WAL mode.
250
+ - Rewrote DXCC tracker.
249
251
  - [25-6-7] Fix focus issue when dxcc widget is active.
250
252
  - [25-6-4] Add a DXCC/Band widget.
251
253
  - [25-6-3] Fix crash caused by SSL cert expiration from supercheckpartial.com.
@@ -213,7 +213,9 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
213
213
 
214
214
  ## Recent Changes
215
215
 
216
+ - [25-6-10] Merged PR from @dj1yfk correcting WPX prefix calculation.
216
217
  - [25-6-8] Revmoved SQLite WAL mode.
218
+ - Rewrote DXCC tracker.
217
219
  - [25-6-7] Fix focus issue when dxcc widget is active.
218
220
  - [25-6-4] Add a DXCC/Band widget.
219
221
  - [25-6-3] Fix crash caused by SSL cert expiration from supercheckpartial.com.
@@ -16,7 +16,7 @@
16
16
  <widget class="QWidget" name="centralwidget">
17
17
  <layout class="QVBoxLayout" name="verticalLayout">
18
18
  <item>
19
- <widget class="QTableView" name="tableView">
19
+ <widget class="QTableWidget" name="dxcc_table">
20
20
  <property name="focusPolicy">
21
21
  <enum>Qt::FocusPolicy::NoFocus</enum>
22
22
  </property>
@@ -0,0 +1,139 @@
1
+ from PyQt6.QtWidgets import QDockWidget
2
+ from PyQt6.QtGui import QBrush, QColor
3
+
4
+ # from PyQt6.QtCore import Qt
5
+ from PyQt6.QtCore import pyqtSignal
6
+ from PyQt6 import uic, QtWidgets
7
+ import not1mm.fsutils as fsutils
8
+ from not1mm.lib.database import DataBase
9
+ import os
10
+ from json import loads
11
+
12
+ import logging
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class DXCCWindow(QDockWidget):
18
+ message = pyqtSignal(dict)
19
+ dbname = None
20
+ db = None
21
+ model = None
22
+ pref = {}
23
+ columns = {
24
+ 0: "DXCC",
25
+ 1: "160m",
26
+ 2: "80m",
27
+ 3: "40m",
28
+ 4: "20m",
29
+ 5: "15m",
30
+ 6: "10m",
31
+ 7: "Total",
32
+ }
33
+
34
+ def __init__(self):
35
+ super().__init__()
36
+ self.active = False
37
+ uic.loadUi(fsutils.APP_DATA_PATH / "dxcc_tracker.ui", self)
38
+ self.dxcc_table.setColumnCount(len(self.columns))
39
+ for column_number, column_name in self.columns.items():
40
+ self.dxcc_table.setHorizontalHeaderItem(
41
+ column_number, QtWidgets.QTableWidgetItem(column_name)
42
+ )
43
+ self.setWindowTitle("DXCC Tracker")
44
+ self.load_pref()
45
+
46
+ self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
47
+ "current_database", "ham.db"
48
+ )
49
+ self.database = DataBase(self.dbname, fsutils.USER_DATA_PATH)
50
+
51
+ self.database.current_contest = self.pref.get("contest", 0)
52
+
53
+ self.get_log()
54
+ self.dxcc_table.resizeColumnsToContents()
55
+ self.dxcc_table.resizeRowsToContents()
56
+
57
+ def setActive(self, mode: bool):
58
+ self.active = bool(mode)
59
+
60
+ def get_log(self):
61
+ """dxcc_table"""
62
+
63
+ # result=[
64
+ # {'CountryPrefix': 'K', '160m': 0, '80m': 0, '40m': 0, '20m': 7, '15m': 0, '10m': 0, 'Total': 7},
65
+ # {'CountryPrefix': 'XE', '160m': 0, '80m': 0, '40m': 0, '20m': 1, '15m': 0, '10m': 0, 'Total': 1},
66
+ # {'CountryPrefix': 'G', '160m': 0, '80m': 0, '40m': 0, '20m': 1, '15m': 0, '10m': 0, 'Total': 1}
67
+ # ]
68
+
69
+ result = self.database.fetch_dxcc_by_band_count()
70
+ self.dxcc_table.setRowCount(0)
71
+ for row_number, row_data in enumerate(result):
72
+ self.dxcc_table.insertRow(row_number)
73
+ for column, data in enumerate(row_data.values()):
74
+ item = QtWidgets.QTableWidgetItem(str(data))
75
+ if column > 0 and column < 7:
76
+ if data == 0:
77
+ item.setBackground(QBrush(QColor(44, 138, 44)))
78
+ else:
79
+ item.setBackground(QBrush(QColor(155, 100, 100)))
80
+ self.dxcc_table.setItem(row_number, column, item)
81
+ self.dxcc_table.resizeColumnsToContents()
82
+ self.dxcc_table.resizeRowsToContents()
83
+
84
+ def load_pref(self) -> None:
85
+ """
86
+ Loads the preferences from the config file into the self.pref dictionary.
87
+
88
+ Parameters
89
+ ----------
90
+ None
91
+
92
+ Returns
93
+ -------
94
+ None
95
+ """
96
+ try:
97
+ if os.path.exists(fsutils.CONFIG_FILE):
98
+ with open(
99
+ fsutils.CONFIG_FILE, "rt", encoding="utf-8"
100
+ ) as file_descriptor:
101
+ self.pref = loads(file_descriptor.read())
102
+ logger.info("%s", self.pref)
103
+ else:
104
+ self.pref["current_database"] = "ham.db"
105
+
106
+ except IOError as exception:
107
+ logger.critical("Error: %s", exception)
108
+
109
+ def load_new_db(self) -> None:
110
+ """
111
+ If the database changes reload it.
112
+
113
+ Parameters
114
+ ----------
115
+ None
116
+
117
+ Returns
118
+ -------
119
+ None
120
+ """
121
+ self.load_pref()
122
+ self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
123
+ "current_database", "ham.db"
124
+ )
125
+ self.database = DataBase(self.dbname, fsutils.APP_DATA_PATH)
126
+ self.database.current_contest = self.pref.get("contest", 0)
127
+ self.contact = self.database.empty_contact
128
+ self.get_log()
129
+
130
+ def msg_from_main(self, msg):
131
+ """"""
132
+ if self.active is True:
133
+ if msg.get("cmd", "") in ("UPDATELOG", "CONTACTCHANGED", "DELETED"):
134
+ ...
135
+ self.get_log()
136
+ if msg.get("cmd", "") == "NEWDB":
137
+ ...
138
+ self.load_new_db()
139
+ self.get_log()
@@ -726,6 +726,34 @@ class DataBase:
726
726
  logger.debug("%s", exception)
727
727
  return {}
728
728
 
729
+ def fetch_dxcc_by_band_count(self) -> list:
730
+ """
731
+ Fetch list containing count of unique countries by band
732
+
733
+ """
734
+ try:
735
+ with sqlite3.connect(self.database) as conn:
736
+ conn.row_factory = self.row_factory
737
+ cursor = conn.cursor()
738
+ query = f"""
739
+ SELECT CountryPrefix,
740
+ SUM(CASE WHEN Band = 1.8 THEN 1 ELSE 0 END) AS '160m',
741
+ SUM(CASE WHEN Band = 3.5 THEN 1 ELSE 0 END) AS '80m',
742
+ SUM(CASE WHEN Band = 7.0 THEN 1 ELSE 0 END) AS '40m',
743
+ SUM(CASE WHEN Band = 14.0 THEN 1 ELSE 0 END) AS '20m',
744
+ SUM(CASE WHEN Band = 21.0 THEN 1 ELSE 0 END) AS '15m',
745
+ SUM(CASE WHEN Band = 28.0 THEN 1 ELSE 0 END) AS '10m',
746
+ COUNT(*) AS Total
747
+ FROM DXLOG where ContestNR = {self.current_contest}
748
+ GROUP BY CountryPrefix
749
+ ORDER BY Total DESC
750
+ """
751
+ cursor.execute(query)
752
+ return cursor.fetchall()
753
+ except sqlite3.OperationalError as exception:
754
+ logger.debug("%s", exception)
755
+ return {}
756
+
729
757
  def fetch_exchange1_unique_count(self) -> dict:
730
758
  """
731
759
  Fetch count of unique countries
@@ -16,19 +16,22 @@ def calculate_wpx_prefix(the_call: str) -> str:
16
16
  return ""
17
17
  if the_call in ["OPON", "CW", "SSB", "RTTY"]:
18
18
  return ""
19
- suffix_to_ignore = ["M", "MM", "P", "QRP", "A", "LH", "NLD"]
19
+ suffix_to_ignore = ["M", "MM", "P", "QRP", "A", "J", "LH", "LGT", "LS", "NLD", "T", "R", "TR" ]
20
+ for suffix in suffix_to_ignore:
21
+ the_call = re.sub("/" + suffix + "$", "", the_call)
20
22
  result = None
21
23
  working_call = the_call.split("/")
22
24
  if len(working_call) > 1:
23
25
  result = min(working_call, key=len)
24
26
  if not result.isnumeric():
25
- if result not in suffix_to_ignore:
26
- if any(chr.isdigit() for chr in result):
27
- return result
28
- return result + "0"
27
+ if any(chr.isdigit() for chr in result):
28
+ return result
29
+ return result + "0"
29
30
 
30
31
  working_call = max(working_call, key=len)
31
32
  last_digit = re.match(".+([0-9])[^0-9]*$", working_call)
33
+ if last_digit is None:
34
+ return working_call[0:2] + "0"
32
35
  position = last_digit.start(1)
33
36
  prefix = working_call[: position + 1]
34
37
  if not result:
@@ -1,3 +1,3 @@
1
1
  """It's the version"""
2
2
 
3
- __version__ = "25.6.8"
3
+ __version__ = "25.6.10"
@@ -0,0 +1,5 @@
1
+ from not1mm.lib.rot_interface import RotatorInterface
2
+
3
+ rotator = RotatorInterface()
4
+ if rotator.connected is True:
5
+ print(f"{rotator.get_position()=}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: not1mm
3
- Version: 25.6.8
3
+ Version: 25.6.10
4
4
  Summary: NOT1MM Logger
5
5
  Author-email: Michael Bridak <michael.bridak@gmail.com>
6
6
  License: GPL-3.0-or-later
@@ -245,7 +245,9 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
245
245
 
246
246
  ## Recent Changes
247
247
 
248
+ - [25-6-10] Merged PR from @dj1yfk correcting WPX prefix calculation.
248
249
  - [25-6-8] Revmoved SQLite WAL mode.
250
+ - Rewrote DXCC tracker.
249
251
  - [25-6-7] Fix focus issue when dxcc widget is active.
250
252
  - [25-6-4] Add a DXCC/Band widget.
251
253
  - [25-6-3] Fix crash caused by SSL cert expiration from supercheckpartial.com.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "not1mm"
7
- version = "25.6.8"
7
+ version = "25.6.10"
8
8
  description = "NOT1MM Logger"
9
9
  license = { text = "GPL-3.0-or-later" }
10
10
  readme = "README.md"
@@ -1,132 +0,0 @@
1
- from PyQt6.QtWidgets import QDockWidget, QTableView
2
- from PyQt6.QtSql import QSqlDatabase, QSqlQueryModel, QSqlQuery
3
- from PyQt6.QtGui import QBrush, QColor
4
- from PyQt6.QtCore import Qt
5
- from PyQt6.QtCore import pyqtSignal
6
- from PyQt6 import uic
7
- import not1mm.fsutils as fsutils
8
- import os
9
- from json import loads
10
-
11
- import logging
12
-
13
- logger = logging.getLogger(__name__)
14
-
15
-
16
- class CustomSqlModel(QSqlQueryModel):
17
- def data(self, index, role):
18
- if role == Qt.ItemDataRole.BackgroundRole:
19
- column = index.column()
20
- if column < 7: # Columns 0-6 (CountryPrefix and band columns)
21
- value = super().data(index, Qt.ItemDataRole.DisplayRole)
22
- if value and isinstance(value, (int, float)) and value > 0:
23
- return QBrush(QColor(44, 138, 44)) # Light green color
24
- elif value == 0:
25
- return QBrush(QColor(155, 100, 100)) # Light red color
26
- return super().data(index, role)
27
-
28
-
29
- class DXCCWindow(QDockWidget):
30
- message = pyqtSignal(dict)
31
- dbname = None
32
- db = None
33
- model = None
34
- pref = {}
35
-
36
- def __init__(self):
37
- super().__init__()
38
- self.active = False
39
- uic.loadUi(fsutils.APP_DATA_PATH / "dxcc_tracker.ui", self)
40
- self.setWindowTitle("DXCC Tracker")
41
- self.load_pref()
42
- self.db = QSqlDatabase.addDatabase("QSQLITE")
43
- self.tableView.verticalHeader().setVisible(False)
44
-
45
- def setActive(self, mode: bool):
46
- self.active = bool(mode)
47
-
48
- def update_model(self):
49
- self.model = CustomSqlModel(self)
50
- query = QSqlQuery(self.db)
51
- query.prepare(
52
- f"""
53
- SELECT CountryPrefix,
54
- SUM(CASE WHEN Band = 1.8 THEN 1 ELSE 0 END) AS '160m',
55
- SUM(CASE WHEN Band = 3.5 THEN 1 ELSE 0 END) AS '80m',
56
- SUM(CASE WHEN Band = 7.0 THEN 1 ELSE 0 END) AS '40m',
57
- SUM(CASE WHEN Band = 14.0 THEN 1 ELSE 0 END) AS '20m',
58
- SUM(CASE WHEN Band = 21.0 THEN 1 ELSE 0 END) AS '15m',
59
- SUM(CASE WHEN Band = 28.0 THEN 1 ELSE 0 END) AS '10m',
60
- COUNT(*) AS Total
61
- FROM DXLOG where ContestNR = {self.pref.get('contest', 1)}
62
- GROUP BY CountryPrefix
63
- ORDER BY Total DESC
64
- """
65
- )
66
- if not query.exec():
67
- print("Query failed:", query.lastError().text())
68
- else:
69
- self.model.setQuery(query)
70
- headers = ["DXCC", "160m", "80m", "40m", "20m", "15m", "10m", "Total"]
71
- for i, header in enumerate(headers):
72
- self.model.setHeaderData(i, Qt.Orientation.Horizontal, header)
73
- self.tableView.setModel(self.model)
74
- self.tableView.resizeColumnsToContents()
75
- self.tableView.resizeRowsToContents()
76
-
77
- def load_pref(self) -> None:
78
- """
79
- Loads the preferences from the config file into the self.pref dictionary.
80
-
81
- Parameters
82
- ----------
83
- None
84
-
85
- Returns
86
- -------
87
- None
88
- """
89
- try:
90
- if os.path.exists(fsutils.CONFIG_FILE):
91
- with open(
92
- fsutils.CONFIG_FILE, "rt", encoding="utf-8"
93
- ) as file_descriptor:
94
- self.pref = loads(file_descriptor.read())
95
- logger.info("%s", self.pref)
96
- else:
97
- self.pref["current_database"] = "ham.db"
98
-
99
- except IOError as exception:
100
- logger.critical("Error: %s", exception)
101
-
102
- def load_new_db(self) -> None:
103
- """
104
- If the database changes reload it.
105
-
106
- Parameters
107
- ----------
108
- None
109
-
110
- Returns
111
- -------
112
- None
113
- """
114
- self.load_pref()
115
- self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
116
- "current_database", "ham.db"
117
- )
118
-
119
- self.db.setDatabaseName(f"{self.dbname}")
120
- if not self.db.open():
121
- print("Error: Could not open database")
122
- return
123
-
124
- def msg_from_main(self, msg):
125
- """"""
126
- if msg.get("cmd", "") in ("UPDATELOG", "CONTACTCHANGED", "DELETED"):
127
- ...
128
- self.update_model()
129
- if msg.get("cmd", "") == "NEWDB":
130
- ...
131
- self.load_new_db()
132
- self.update_model()
@@ -1,37 +0,0 @@
1
- import datetime
2
-
3
-
4
- # Assume self.auto_cq_delay is defined (e.g., in milliseconds)
5
- class SomeClass:
6
- def __init__(self, auto_cq_delay_ms):
7
- self.auto_cq_delay = auto_cq_delay_ms
8
-
9
-
10
- # Example instantiation
11
- instance = SomeClass(auto_cq_delay_ms=5000) # 5 seconds delay
12
-
13
-
14
- then = datetime.datetime.now()
15
- future = datetime.datetime.now() + datetime.timedelta(milliseconds=15000)
16
-
17
-
18
- # Calculate the total duration between 'then' and 'future'
19
- total_duration = future - then
20
-
21
- while datetime.datetime.now() < future:
22
-
23
- now = datetime.datetime.now()
24
- # Calculate the elapsed duration between 'then' and 'now'
25
- elapsed_duration = now - then
26
-
27
- # Avoid division by zero if total_duration is zero (though unlikely in this scenario)
28
- if total_duration.total_seconds() > 0:
29
- # Calculate the percentage of the way 'now' is to 'future'
30
- percentage_complete = (
31
- elapsed_duration.total_seconds() / total_duration.total_seconds()
32
- ) * 100
33
- print(f"Current time is {percentage_complete:.2f}% of the way to 'future'.")
34
- else:
35
- print(
36
- "'future' is the same as or before 'then', so percentage cannot be calculated meaningfully."
37
- )
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes