not1mm 25.6.7__tar.gz → 25.6.8.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.
- {not1mm-25.6.7 → not1mm-25.6.8.1}/PKG-INFO +3 -1
- {not1mm-25.6.7 → not1mm-25.6.8.1}/README.md +2 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/dxcc_tracker.ui +1 -1
- not1mm-25.6.8.1/not1mm/dxcc_tracker.py +151 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/database.py +34 -9
- not1mm-25.6.8.1/not1mm/lib/version.py +3 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm.egg-info/PKG-INFO +3 -1
- {not1mm-25.6.7 → not1mm-25.6.8.1}/pyproject.toml +1 -1
- not1mm-25.6.7/not1mm/dxcc_tracker.py +0 -132
- not1mm-25.6.7/not1mm/lib/version.py +0 -3
- {not1mm-25.6.7 → not1mm-25.6.8.1}/LICENSE +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/__init__.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/__main__.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/bandmap.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/checkwindow.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/JetBrainsMono-Thin.ttf +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/MASTER.SCP +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/about.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/alpha bravo charlie delta.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/bandmap.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/check.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/checkwindow.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/cloud_green.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/cloud_red.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/configuration.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/contests.sql +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/cty.json +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/cwmacros.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/donors.html +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/editcontact.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/editmacro.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/greendot.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/k6gte-not1mm.desktop +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/k6gte.not1mm-128.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/k6gte.not1mm-32.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/k6gte.not1mm-64.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/logwindow.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/logwindowx.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/main.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/new_contest.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/not1mm.html +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/opon.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/0.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/1.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/2.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/3.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/4.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/5.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/6.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/7.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/73.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/8.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/9.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/a.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/again.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/b.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/c.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/contest.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/cq.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/cq2.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/d.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/e.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/f.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/g.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/h.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/i.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/j.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/k.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/k6gte.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/l.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/m.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/mynumber.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/n.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/nil.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/o.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/p.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/q.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/r.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/roger.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/s.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/space.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/t.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/thankyou.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/thankyouqrz.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/u.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/v.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/w.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/x.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/y.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/yourcall.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/phonetics/z.wav +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/pickcontest.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/radio_green.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/radio_grey.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/radio_red.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/ratewindow.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/reddot.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/rttymacros.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/settings.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/splash.png +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/ssbmacros.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/statistics.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/data/vfo.ui +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/fsutils.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/__init__.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/about.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/cat_interface.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/cwinterface.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/edit_contact.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/edit_macro.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/edit_opon.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/edit_station.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/fldigi_sendstring.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/ft8_watcher.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/ham_utility.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/lookup.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/multicast.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/n1mm.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/new_contest.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/plugin_common.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/select_contest.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/settings.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/super_check_partial.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lib/versiontest.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/logwindow.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/lookupservice.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/10_10_fall_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/10_10_spring_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/10_10_summer_phone.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/10_10_winter_phone.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/__init__.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ari_40_80.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ari_dx.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_10m.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_160m.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_dx_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_dx_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_field_day.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_rtty_ru.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_ss_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_ss_phone.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_vhf_jan.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_vhf_jun.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/arrl_vhf_sep.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/canada_day.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_160_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_160_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_wpx_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_wpx_rtty.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_wpx_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_ww_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_ww_rtty.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cq_ww_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/cwt.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/darc_vhf.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/darc_xmas.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ea_majistad_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ea_majistad_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ea_rtty.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/es_field_day.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/es_open.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/general_logging.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/helvetia.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/iaru_fieldday_r1_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/iaru_fieldday_r1_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/iaru_hf.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/icwc_mst.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/jidx_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/jidx_ph.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/k1usn_sst.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/labre_rs_digi.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/lz-dx.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/naqp_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/naqp_rtty.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/naqp_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/phone_weekly_test.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/raem.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/randomgram.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ref_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ref_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/sac_cw.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/sac_ssb.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/spdx.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/stew_perry_topband.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/ukeidx.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/vhf_sprint.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/weekly_rtty.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/plugins/winter_field_day.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/radio.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/ratewindow.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/rtc_service.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/statistics.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/test.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/vfo.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm/voice_keying.py +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm.egg-info/SOURCES.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm.egg-info/dependency_links.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm.egg-info/entry_points.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm.egg-info/requires.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/not1mm.egg-info/top_level.txt +0 -0
- {not1mm-25.6.7 → not1mm-25.6.8.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.6.
|
3
|
+
Version: 25.6.8.1
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
License: GPL-3.0-or-later
|
@@ -245,6 +245,8 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
245
245
|
|
246
246
|
## Recent Changes
|
247
247
|
|
248
|
+
- [25-6-8] Revmoved SQLite WAL mode.
|
249
|
+
- Rewrote DXCC tracker.
|
248
250
|
- [25-6-7] Fix focus issue when dxcc widget is active.
|
249
251
|
- [25-6-4] Add a DXCC/Band widget.
|
250
252
|
- [25-6-3] Fix crash caused by SSL cert expiration from supercheckpartial.com.
|
@@ -213,6 +213,8 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
213
213
|
|
214
214
|
## Recent Changes
|
215
215
|
|
216
|
+
- [25-6-8] Revmoved SQLite WAL mode.
|
217
|
+
- Rewrote DXCC tracker.
|
216
218
|
- [25-6-7] Fix focus issue when dxcc widget is active.
|
217
219
|
- [25-6-4] Add a DXCC/Band widget.
|
218
220
|
- [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="
|
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,151 @@
|
|
1
|
+
from PyQt6.QtWidgets import QDockWidget
|
2
|
+
from PyQt6.QtGui import QBrush, QColor
|
3
|
+
from PyQt6.QtCore import Qt
|
4
|
+
from PyQt6.QtCore import pyqtSignal
|
5
|
+
from PyQt6 import uic, QtWidgets
|
6
|
+
import not1mm.fsutils as fsutils
|
7
|
+
from not1mm.lib.database import DataBase
|
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
|
+
columns = {
|
36
|
+
0: "DXCC",
|
37
|
+
1: "160m",
|
38
|
+
2: "80m",
|
39
|
+
3: "40m",
|
40
|
+
4: "20m",
|
41
|
+
5: "15m",
|
42
|
+
6: "10m",
|
43
|
+
7: "Total",
|
44
|
+
}
|
45
|
+
|
46
|
+
def __init__(self):
|
47
|
+
super().__init__()
|
48
|
+
self.active = False
|
49
|
+
uic.loadUi(fsutils.APP_DATA_PATH / "dxcc_tracker.ui", self)
|
50
|
+
self.dxcc_table.setColumnCount(len(self.columns))
|
51
|
+
for column_number, column_name in self.columns.items():
|
52
|
+
self.dxcc_table.setHorizontalHeaderItem(
|
53
|
+
column_number, QtWidgets.QTableWidgetItem(column_name)
|
54
|
+
)
|
55
|
+
self.setWindowTitle("DXCC Tracker")
|
56
|
+
self.load_pref()
|
57
|
+
|
58
|
+
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
59
|
+
"current_database", "ham.db"
|
60
|
+
)
|
61
|
+
self.database = DataBase(self.dbname, fsutils.USER_DATA_PATH)
|
62
|
+
|
63
|
+
self.database.current_contest = self.pref.get("contest", 0)
|
64
|
+
|
65
|
+
self.get_log()
|
66
|
+
self.dxcc_table.resizeColumnsToContents()
|
67
|
+
self.dxcc_table.resizeRowsToContents()
|
68
|
+
|
69
|
+
def setActive(self, mode: bool):
|
70
|
+
self.active = bool(mode)
|
71
|
+
|
72
|
+
def get_log(self):
|
73
|
+
"""dxcc_table"""
|
74
|
+
|
75
|
+
# result=[
|
76
|
+
# {'CountryPrefix': 'K', '160m': 0, '80m': 0, '40m': 0, '20m': 7, '15m': 0, '10m': 0, 'Total': 7},
|
77
|
+
# {'CountryPrefix': 'XE', '160m': 0, '80m': 0, '40m': 0, '20m': 1, '15m': 0, '10m': 0, 'Total': 1},
|
78
|
+
# {'CountryPrefix': 'G', '160m': 0, '80m': 0, '40m': 0, '20m': 1, '15m': 0, '10m': 0, 'Total': 1}
|
79
|
+
# ]
|
80
|
+
|
81
|
+
result = self.database.fetch_dxcc_by_band_count()
|
82
|
+
self.dxcc_table.setRowCount(0)
|
83
|
+
for row_number, row_data in enumerate(result):
|
84
|
+
self.dxcc_table.insertRow(row_number)
|
85
|
+
for column, data in enumerate(row_data.values()):
|
86
|
+
item = QtWidgets.QTableWidgetItem(str(data))
|
87
|
+
if column > 0 and column < 7:
|
88
|
+
if data == 0:
|
89
|
+
item.setBackground(QBrush(QColor(44, 138, 44)))
|
90
|
+
else:
|
91
|
+
item.setBackground(QBrush(QColor(155, 100, 100)))
|
92
|
+
self.dxcc_table.setItem(row_number, column, item)
|
93
|
+
self.dxcc_table.resizeColumnsToContents()
|
94
|
+
self.dxcc_table.resizeRowsToContents()
|
95
|
+
|
96
|
+
def load_pref(self) -> None:
|
97
|
+
"""
|
98
|
+
Loads the preferences from the config file into the self.pref dictionary.
|
99
|
+
|
100
|
+
Parameters
|
101
|
+
----------
|
102
|
+
None
|
103
|
+
|
104
|
+
Returns
|
105
|
+
-------
|
106
|
+
None
|
107
|
+
"""
|
108
|
+
try:
|
109
|
+
if os.path.exists(fsutils.CONFIG_FILE):
|
110
|
+
with open(
|
111
|
+
fsutils.CONFIG_FILE, "rt", encoding="utf-8"
|
112
|
+
) as file_descriptor:
|
113
|
+
self.pref = loads(file_descriptor.read())
|
114
|
+
logger.info("%s", self.pref)
|
115
|
+
else:
|
116
|
+
self.pref["current_database"] = "ham.db"
|
117
|
+
|
118
|
+
except IOError as exception:
|
119
|
+
logger.critical("Error: %s", exception)
|
120
|
+
|
121
|
+
def load_new_db(self) -> None:
|
122
|
+
"""
|
123
|
+
If the database changes reload it.
|
124
|
+
|
125
|
+
Parameters
|
126
|
+
----------
|
127
|
+
None
|
128
|
+
|
129
|
+
Returns
|
130
|
+
-------
|
131
|
+
None
|
132
|
+
"""
|
133
|
+
self.load_pref()
|
134
|
+
self.dbname = fsutils.USER_DATA_PATH / self.pref.get(
|
135
|
+
"current_database", "ham.db"
|
136
|
+
)
|
137
|
+
self.database = DataBase(self.dbname, fsutils.APP_DATA_PATH)
|
138
|
+
self.database.current_contest = self.pref.get("contest", 0)
|
139
|
+
self.contact = self.database.empty_contact
|
140
|
+
self.get_log()
|
141
|
+
|
142
|
+
def msg_from_main(self, msg):
|
143
|
+
""""""
|
144
|
+
if self.active is True:
|
145
|
+
if msg.get("cmd", "") in ("UPDATELOG", "CONTACTCHANGED", "DELETED"):
|
146
|
+
...
|
147
|
+
self.get_log()
|
148
|
+
if msg.get("cmd", "") == "NEWDB":
|
149
|
+
...
|
150
|
+
self.load_new_db()
|
151
|
+
self.get_log()
|
@@ -179,7 +179,7 @@ class DataBase:
|
|
179
179
|
");"
|
180
180
|
)
|
181
181
|
cursor.execute(sql_command)
|
182
|
-
cursor.execute("PRAGMA journal_mode=
|
182
|
+
cursor.execute("PRAGMA journal_mode=DELETE")
|
183
183
|
conn.commit()
|
184
184
|
except sqlite3.OperationalError as exception:
|
185
185
|
logger.debug("%s", exception)
|
@@ -223,7 +223,7 @@ class DataBase:
|
|
223
223
|
");"
|
224
224
|
)
|
225
225
|
cursor.execute(sql_command)
|
226
|
-
cursor.execute("PRAGMA journal_mode=
|
226
|
+
cursor.execute("PRAGMA journal_mode=DELETE")
|
227
227
|
conn.commit()
|
228
228
|
|
229
229
|
sql_command = "select * from Contest;"
|
@@ -273,7 +273,7 @@ class DataBase:
|
|
273
273
|
"TimeCategory NVARCHAR(20));"
|
274
274
|
)
|
275
275
|
cursor.execute(sql_command)
|
276
|
-
cursor.execute("PRAGMA journal_mode=
|
276
|
+
cursor.execute("PRAGMA journal_mode=DELETE")
|
277
277
|
conn.commit()
|
278
278
|
except sqlite3.OperationalError as exception:
|
279
279
|
logger.debug("%s", exception)
|
@@ -313,7 +313,7 @@ class DataBase:
|
|
313
313
|
"PRIMARY KEY([Call]));"
|
314
314
|
)
|
315
315
|
cursor.execute(sql_command)
|
316
|
-
cursor.execute("PRAGMA journal_mode=
|
316
|
+
cursor.execute("PRAGMA journal_mode=DELETE")
|
317
317
|
conn.commit()
|
318
318
|
except sqlite3.OperationalError as exception:
|
319
319
|
logger.debug("%s", exception)
|
@@ -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
|
@@ -1234,7 +1262,7 @@ class DataBase:
|
|
1234
1262
|
except sqlite3.OperationalError as exception:
|
1235
1263
|
logger.debug("%s", exception)
|
1236
1264
|
return {}
|
1237
|
-
|
1265
|
+
|
1238
1266
|
def exec_sql_params_mult(self, query: str, params=None) -> dict:
|
1239
1267
|
"""Exec one off queries returning one dict"""
|
1240
1268
|
try:
|
@@ -1271,9 +1299,7 @@ class DataBase:
|
|
1271
1299
|
logger.debug("%s", exception)
|
1272
1300
|
return []
|
1273
1301
|
|
1274
|
-
def check_dupe_on_period_mode(
|
1275
|
-
self, call, band, mode, period_1, period_2
|
1276
|
-
) -> dict:
|
1302
|
+
def check_dupe_on_period_mode(self, call, band, mode, period_1, period_2) -> dict:
|
1277
1303
|
"""Checks if a call is dupe on band/mode"""
|
1278
1304
|
try:
|
1279
1305
|
with sqlite3.connect(self.database) as conn:
|
@@ -1286,4 +1312,3 @@ class DataBase:
|
|
1286
1312
|
except sqlite3.OperationalError as exception:
|
1287
1313
|
logger.debug("%s", exception)
|
1288
1314
|
return {}
|
1289
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: not1mm
|
3
|
-
Version: 25.6.
|
3
|
+
Version: 25.6.8.1
|
4
4
|
Summary: NOT1MM Logger
|
5
5
|
Author-email: Michael Bridak <michael.bridak@gmail.com>
|
6
6
|
License: GPL-3.0-or-later
|
@@ -245,6 +245,8 @@ generated, 'cause I'm lazy, list of those who've submitted PR's.
|
|
245
245
|
|
246
246
|
## Recent Changes
|
247
247
|
|
248
|
+
- [25-6-8] Revmoved SQLite WAL mode.
|
249
|
+
- Rewrote DXCC tracker.
|
248
250
|
- [25-6-7] Fix focus issue when dxcc widget is active.
|
249
251
|
- [25-6-4] Add a DXCC/Band widget.
|
250
252
|
- [25-6-3] Fix crash caused by SSL cert expiration from supercheckpartial.com.
|
@@ -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()
|
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
|
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
|
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
|
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
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|