not1mm 25.5.26.1__py3-none-any.whl → 25.6.1__py3-none-any.whl

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 (50) hide show
  1. not1mm/__main__.py +66 -43
  2. not1mm/data/MASTER.SCP +2636 -2654
  3. not1mm/data/cty.json +1 -1
  4. not1mm/data/new_contest.ui +5 -0
  5. not1mm/lib/database.py +14 -45
  6. not1mm/lib/edit_station.py +5 -5
  7. not1mm/lib/plugin_common.py +21 -0
  8. not1mm/lib/super_check_partial.py +28 -12
  9. not1mm/lib/version.py +1 -1
  10. not1mm/logwindow.py +4 -0
  11. not1mm/plugins/ari_dx.py +11 -11
  12. not1mm/plugins/arrl_160m.py +13 -13
  13. not1mm/plugins/arrl_dx_cw.py +47 -47
  14. not1mm/plugins/arrl_dx_ssb.py +48 -48
  15. not1mm/plugins/canada_day.py +6 -6
  16. not1mm/plugins/cq_160_cw.py +16 -16
  17. not1mm/plugins/cq_160_ssb.py +16 -16
  18. not1mm/plugins/cq_wpx_cw.py +28 -28
  19. not1mm/plugins/cq_wpx_rtty.py +20 -20
  20. not1mm/plugins/cq_wpx_ssb.py +28 -28
  21. not1mm/plugins/cq_ww_cw.py +19 -19
  22. not1mm/plugins/cq_ww_rtty.py +14 -14
  23. not1mm/plugins/cq_ww_ssb.py +18 -18
  24. not1mm/plugins/ea_majistad_cw.py +6 -6
  25. not1mm/plugins/ea_majistad_ssb.py +6 -6
  26. not1mm/plugins/ea_rtty.py +6 -6
  27. not1mm/plugins/es_field_day.py +604 -0
  28. not1mm/plugins/es_open.py +37 -26
  29. not1mm/plugins/helvetia.py +12 -12
  30. not1mm/plugins/iaru_hf.py +3 -3
  31. not1mm/plugins/jidx_cw.py +4 -4
  32. not1mm/plugins/jidx_ph.py +4 -4
  33. not1mm/plugins/lz-dx.py +12 -12
  34. not1mm/plugins/naqp_cw.py +6 -6
  35. not1mm/plugins/naqp_rtty.py +6 -6
  36. not1mm/plugins/naqp_ssb.py +6 -6
  37. not1mm/plugins/phone_weekly_test.py +6 -6
  38. not1mm/plugins/ref_cw.py +8 -8
  39. not1mm/plugins/ref_ssb.py +8 -8
  40. not1mm/plugins/sac_cw.py +9 -9
  41. not1mm/plugins/sac_ssb.py +11 -11
  42. not1mm/plugins/spdx.py +7 -7
  43. not1mm/plugins/ukeidx.py +10 -10
  44. not1mm/statistics.py +1 -0
  45. {not1mm-25.5.26.1.dist-info → not1mm-25.6.1.dist-info}/METADATA +7 -277
  46. {not1mm-25.5.26.1.dist-info → not1mm-25.6.1.dist-info}/RECORD +50 -49
  47. {not1mm-25.5.26.1.dist-info → not1mm-25.6.1.dist-info}/WHEEL +1 -1
  48. {not1mm-25.5.26.1.dist-info → not1mm-25.6.1.dist-info}/entry_points.txt +0 -0
  49. {not1mm-25.5.26.1.dist-info → not1mm-25.6.1.dist-info}/licenses/LICENSE +0 -0
  50. {not1mm-25.5.26.1.dist-info → not1mm-25.6.1.dist-info}/top_level.txt +0 -0
not1mm/__main__.py CHANGED
@@ -958,6 +958,8 @@ class MainWindow(QtWidgets.QMainWindow):
958
958
  self.remove_confirmed_commands(json_data)
959
959
  if json_data.get("subject") == "CONTACTCHANGED":
960
960
  self.remove_confirmed_commands(json_data)
961
+ if json_data.get("subject") == "NEWDB":
962
+ self.remove_confirmed_commands(json_data)
961
963
 
962
964
  continue
963
965
 
@@ -1953,6 +1955,23 @@ class MainWindow(QtWidgets.QMainWindow):
1953
1955
  self.rate_window.msg_from_main(cmd)
1954
1956
  if self.statistics_window:
1955
1957
  self.statistics_window.msg_from_main(cmd)
1958
+ # server
1959
+ if self.pref.get("useserver", False) is True:
1960
+ cmd = self.contest_settings.copy()
1961
+ cmd["cmd"] = "NEWDB"
1962
+ stale = datetime.datetime.now() + datetime.timedelta(seconds=30)
1963
+ cmd["expire"] = stale.isoformat()
1964
+ cmd["NetBiosName"] = socket.gethostname()
1965
+ cmd["Operator"] = self.current_op
1966
+ cmd["ID"] = uuid.uuid4().hex
1967
+ cmd["Station"] = self.station
1968
+ self.server_commands.append(cmd)
1969
+ # bytesToSend = bytes(dumps(self.contact), encoding="ascii")
1970
+ try:
1971
+ self.server_channel.send_as_json(cmd)
1972
+ # server_udp.sendto(bytesToSend, (multicast_group, int(multicast_port)))
1973
+ except OSError as err:
1974
+ logging.warning("%s", err)
1956
1975
 
1957
1976
  if hasattr(self.contest, "columns"):
1958
1977
  cmd = {}
@@ -2281,7 +2300,7 @@ class MainWindow(QtWidgets.QMainWindow):
2281
2300
  self.lookup_service.msg_from_main(cmd)
2282
2301
  self.write_preference()
2283
2302
 
2284
- def cty_lookup(self, callsign: str) -> list:
2303
+ def cty_lookup(self, callsign: str) -> dict:
2285
2304
  """Lookup callsign in cty.dat file.
2286
2305
 
2287
2306
  Parameters
@@ -2291,8 +2310,8 @@ class MainWindow(QtWidgets.QMainWindow):
2291
2310
 
2292
2311
  Returns
2293
2312
  -------
2294
- return : list
2295
- list of dicts containing the callsign and the station.
2313
+ return : dict
2314
+ {'entity': 'European Russia', 'cq': 16, 'itu': 29, 'continent': 'EU', 'lat': 53.65, 'long': -41.37, 'tz': 4.0, 'len': 2, 'primary_pfx': 'UA', 'exact_match': False}
2296
2315
  """
2297
2316
  callsign = callsign.upper()
2298
2317
  for count in reversed(range(len(callsign))):
@@ -2847,6 +2866,7 @@ class MainWindow(QtWidgets.QMainWindow):
2847
2866
  self.n1mm.send_contact_info()
2848
2867
 
2849
2868
  self.database.log_contact(self.contact)
2869
+ # server
2850
2870
  if self.pref.get("useserver", False) is True:
2851
2871
  stale = datetime.datetime.now() + datetime.timedelta(seconds=30)
2852
2872
  self.contact["cmd"] = "POST"
@@ -3817,11 +3837,13 @@ class MainWindow(QtWidgets.QMainWindow):
3817
3837
  self.log_window.msg_from_main(cmd)
3818
3838
  if self.check_window:
3819
3839
  self.check_window.msg_from_main(cmd)
3820
- self.check_callsign(stripped_text)
3821
- if self.check_dupe(stripped_text):
3822
- self.dupe_indicator.show()
3823
- else:
3824
- self.dupe_indicator.hide()
3840
+ if len(stripped_text) >= 3:
3841
+ self.check_callsign(stripped_text)
3842
+ # self.check_callsign(stripped_text)
3843
+ if self.check_dupe(stripped_text):
3844
+ self.dupe_indicator.show()
3845
+ else:
3846
+ self.dupe_indicator.hide()
3825
3847
  if self.contest:
3826
3848
  if self.use_call_history and hasattr(
3827
3849
  self.contest, "populate_history_info_line"
@@ -3973,42 +3995,43 @@ class MainWindow(QtWidgets.QMainWindow):
3973
3995
  """
3974
3996
 
3975
3997
  result = self.cty_lookup(callsign)
3976
- debug_result = f"{result}"
3998
+ debug_result = f"{result=}"
3977
3999
  logger.debug("%s", debug_result)
3978
- if result:
3979
- for a in result.items():
3980
- entity = a[1].get("entity", "")
3981
- cq = a[1].get("cq", "")
3982
- itu = a[1].get("itu", "")
3983
- continent = a[1].get("continent")
3984
- lat = float(a[1].get("lat", "0.0"))
3985
- lon = float(a[1].get("long", "0.0"))
3986
- lon = lon * -1 # cty.dat file inverts longitudes
3987
- primary_pfx = a[1].get("primary_pfx", "")
3988
- heading = bearing_with_latlon(self.station.get("GridSquare"), lat, lon)
3989
- kilometers = distance_with_latlon(
3990
- self.station.get("GridSquare"), lat, lon
3991
- )
3992
- self.heading_distance.setText(
3993
- f"Regional Hdg {heading}° LP {reciprocol(heading)}° / "
3994
- f"distance {int(kilometers*0.621371)}mi {kilometers}km"
3995
- )
3996
- self.contact["CountryPrefix"] = primary_pfx
3997
- self.contact["ZN"] = int(cq)
4000
+ if result is not None:
4001
+ try:
4002
+ a = result.get(next(iter(result)))
4003
+ except (StopIteration, AttributeError):
4004
+ return
4005
+ entity = a.get("entity", "")
4006
+ cq = a.get("cq", "")
4007
+ itu = a.get("itu", "")
4008
+ continent = a.get("continent")
4009
+ lat = float(a.get("lat", "0.0"))
4010
+ lon = float(a.get("long", "0.0"))
4011
+ lon = lon * -1 # cty.dat file inverts longitudes
4012
+ primary_pfx = a.get("primary_pfx", "")
4013
+ heading = bearing_with_latlon(self.station.get("GridSquare"), lat, lon)
4014
+ kilometers = distance_with_latlon(self.station.get("GridSquare"), lat, lon)
4015
+ self.heading_distance.setText(
4016
+ f"Regional Hdg {heading}° LP {reciprocol(heading)}° / "
4017
+ f"distance {int(kilometers*0.621371)}mi {kilometers}km"
4018
+ )
4019
+ self.contact["CountryPrefix"] = primary_pfx
4020
+ self.contact["ZN"] = int(cq)
4021
+ if self.contest:
4022
+ if self.contest.name in ("IARU HF", "LZ DX"):
4023
+ self.contact["ZN"] = int(itu)
4024
+ self.contact["Continent"] = continent
4025
+ self.dx_entity.setText(
4026
+ f"{primary_pfx}: {continent}/{entity} cq:{cq} itu:{itu}"
4027
+ )
4028
+ if len(callsign) > 2:
3998
4029
  if self.contest:
3999
- if self.contest.name in ("IARU HF", "LZ DX"):
4000
- self.contact["ZN"] = int(itu)
4001
- self.contact["Continent"] = continent
4002
- self.dx_entity.setText(
4003
- f"{primary_pfx}: {continent}/{entity} cq:{cq} itu:{itu}"
4004
- )
4005
- if len(callsign) > 2:
4006
- if self.contest:
4007
- if (
4008
- "CQ WW" not in self.contest.name
4009
- and "IARU HF" not in self.contest.name
4010
- ):
4011
- self.contest.prefill(self)
4030
+ if (
4031
+ "CQ WW" not in self.contest.name
4032
+ and "IARU HF" not in self.contest.name
4033
+ ):
4034
+ self.contest.prefill(self)
4012
4035
 
4013
4036
  def check_dupe(self, call: str) -> bool:
4014
4037
  """Checks if a callsign is a dupe on current band/mode."""
@@ -4032,7 +4055,7 @@ class MainWindow(QtWidgets.QMainWindow):
4032
4055
  result = {"isdupe": False}
4033
4056
  if self.contest.dupe_type == 5:
4034
4057
  result = {"isdupe": False} # in case contest has no function.
4035
- if hasattr(self.contest, "specific_contest_check_dupe"):
4058
+ if not hasattr(self.contest, "check_dupe"):
4036
4059
  result = self.contest.specific_contest_check_dupe(self, call)
4037
4060
 
4038
4061
  debugline = f"{result}"