wwvb 3.0.7__py3-none-any.whl → 4.0.0a0__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.
wwvb/updateiers.py CHANGED
@@ -6,32 +6,34 @@
6
6
 
7
7
  """Update the DUT1 and LS data based on online sources"""
8
8
 
9
+ from __future__ import annotations
10
+
9
11
  import csv
10
12
  import datetime
11
13
  import io
12
14
  import itertools
13
- import os
14
15
  import pathlib
15
- from typing import Callable, List, Optional
16
+ from typing import Callable
16
17
 
17
18
  import bs4
18
19
  import click
19
20
  import platformdirs
20
21
  import requests
21
22
 
22
- DIST_PATH = str(pathlib.Path(__file__).parent / "iersdata_dist.py")
23
+ DIST_PATH = pathlib.Path(__file__).parent / "iersdata_dist.py"
23
24
 
24
- OLD_TABLE_START: Optional[datetime.date] = None
25
- OLD_TABLE_END: Optional[datetime.date] = None
26
- if os.path.exists(DIST_PATH):
25
+ OLD_TABLE_START: datetime.date | None = None
26
+ OLD_TABLE_END: datetime.date | None = None
27
+ if DIST_PATH.exists():
27
28
  import wwvb.iersdata_dist
28
29
 
29
30
  OLD_TABLE_START = wwvb.iersdata_dist.DUT1_DATA_START
30
31
  OLD_TABLE_END = OLD_TABLE_START + datetime.timedelta(days=len(wwvb.iersdata_dist.DUT1_OFFSETS) - 1)
31
32
 
32
33
  IERS_URL = "https://datacenter.iers.org/data/csv/finals2000A.all.csv"
33
- if os.path.exists("finals2000A.all.csv"):
34
- IERS_URL = "finals2000A.all.csv"
34
+ IERS_PATH = pathlib.Path("finals2000A.all.csv")
35
+ if IERS_PATH.exists():
36
+ IERS_URL = str(IERS_PATH)
35
37
  print("using local", IERS_URL)
36
38
  NIST_URL = "https://www.nist.gov/pml/time-and-frequency-division/atomic-standards/leap-second-and-ut1-utc-information"
37
39
 
@@ -42,15 +44,14 @@ def _get_text(url: str) -> str:
42
44
  with requests.get(url, timeout=30) as response:
43
45
  return response.text
44
46
  else:
45
- return open(url, encoding="utf-8").read()
47
+ return pathlib.Path(url).read_text(encoding="utf-8")
46
48
 
47
49
 
48
- def update_iersdata( # pylint: disable=too-many-locals, too-many-branches, too-many-statements
49
- target_file: str,
50
+ def update_iersdata( # noqa: PLR0915, PLR0912
51
+ target_path: pathlib.Path,
50
52
  ) -> None:
51
53
  """Update iersdata.py"""
52
-
53
- offsets: List[int] = []
54
+ offsets: list[int] = []
54
55
  iersdata_text = _get_text(IERS_URL)
55
56
  for r in csv.DictReader(io.StringIO(iersdata_text), delimiter=";"):
56
57
  jd = float(r["MJD"])
@@ -97,11 +98,11 @@ def update_iersdata( # pylint: disable=too-many-locals, too-many-branches, too-
97
98
  off_end = (patch_end - table_start).days
98
99
  offsets[off_start:off_end] = [val] * (off_end - off_start)
99
100
 
100
- wwvb_dut1: Optional[int] = None
101
- wwvb_start: Optional[datetime.date] = None
101
+ wwvb_dut1: int | None = None
102
+ wwvb_start: datetime.date | None = None
102
103
  for row in wwvb_dut1_table.findAll("tr")[1:][::-1]:
103
104
  cells = row.findAll("td")
104
- when = datetime.datetime.strptime(cells[0].text, "%Y-%m-%d").date()
105
+ when = datetime.datetime.strptime(cells[0].text + "+0000", "%Y-%m-%d%z").date()
105
106
  dut1 = cells[2].text.replace("s", "").replace(" ", "")
106
107
  dut1 = int(round(float(dut1) * 10))
107
108
  if wwvb_dut1 is not None:
@@ -123,25 +124,24 @@ def update_iersdata( # pylint: disable=too-many-locals, too-many-branches, too-
123
124
  assert wwvb_start is not None
124
125
  patch(wwvb_start, wwvb_data_stamp + datetime.timedelta(days=1), wwvb_dut1)
125
126
 
126
- with open(target_file, "wt", encoding="utf-8") as output:
127
+ with target_path.open("w", encoding="utf-8") as output:
127
128
 
128
129
  def code(*args: str) -> None:
129
130
  """Print to the output file"""
130
131
  print(*args, file=output)
131
132
 
132
133
  code("# -*- python3 -*-")
134
+ code("# fmt: off")
133
135
  code('"""File generated from public data - not subject to copyright"""')
134
136
  code("# SPDX" + "-FileCopyrightText: Public domain")
135
137
  code("# SPDX" + "-License-Identifier: CC0-1.0")
136
- code("# fmt: off")
137
138
  code("# isort: skip_file")
138
- code("# pylint: disable=invalid-name")
139
139
  code("import datetime")
140
140
 
141
141
  code("__all__ = ['DUT1_DATA_START', 'DUT1_OFFSETS']")
142
- code(f"DUT1_DATA_START = {repr(table_start)}")
142
+ code(f"DUT1_DATA_START = {table_start!r}")
143
143
  c = sorted(chr(ord("a") + ch + 10) for ch in set(offsets))
144
- code(f"{','.join(c)} = tuple({repr(''.join(c))})")
144
+ code(f"{','.join(c)} = tuple({''.join(c)!r})")
145
145
  code(f"DUT1_OFFSETS = str( # {table_start.year:04d}{table_start.month:02d}{table_start.day:02d}")
146
146
  line = ""
147
147
  j = 0
@@ -152,10 +152,7 @@ def update_iersdata( # pylint: disable=too-many-locals, too-many-branches, too-
152
152
  sz = len(list(it))
153
153
  if j:
154
154
  part = part + "+"
155
- if sz < 2:
156
- part = part + ch
157
- else:
158
- part = part + f"{ch}*{sz}"
155
+ part = part + ch if sz < 2 else part + f"{ch}*{sz}"
159
156
  j += sz
160
157
  if len(line + part) > 60:
161
158
  d = table_start + datetime.timedelta(j - 1)
@@ -172,25 +169,30 @@ def update_iersdata( # pylint: disable=too-many-locals, too-many-branches, too-
172
169
  print(f"iersdata covers {table_start} .. {table_end}")
173
170
 
174
171
 
175
- def iersdata_path(callback: Callable[[str, str], str]) -> str:
172
+ def iersdata_path(callback: Callable[[str, str], pathlib.Path]) -> pathlib.Path:
176
173
  """Find out the path for this directory"""
177
- return os.path.join(callback("wwvbpy", "unpythonic.net"), "wwvb_iersdata.py")
174
+ print("iersdata_path", callback)
175
+ r = callback("wwvbpy", "unpythonic.net") / "wwvb_iersdata.py"
176
+ print(f"iersdata_path {r=!r}")
177
+ return r
178
178
 
179
179
 
180
180
  @click.command()
181
181
  @click.option(
182
182
  "--user",
183
183
  "location",
184
- flag_value=iersdata_path(platformdirs.user_data_dir),
185
- default=iersdata_path(platformdirs.user_data_dir),
184
+ flag_value=iersdata_path(platformdirs.user_data_path),
185
+ default=iersdata_path(platformdirs.user_data_path),
186
+ type=pathlib.Path,
186
187
  )
187
188
  @click.option("--dist", "location", flag_value=DIST_PATH)
188
- @click.option("--site", "location", flag_value=iersdata_path(platformdirs.site_data_dir))
189
+ @click.option("--site", "location", flag_value=iersdata_path(platformdirs.site_data_path))
189
190
  def main(location: str) -> None:
190
191
  """Update DUT1 data"""
191
- print("will write to", location)
192
- os.makedirs(os.path.dirname(location), exist_ok=True)
193
- update_iersdata(location)
192
+ path = pathlib.Path(location)
193
+ print(f"will write to {location!r}")
194
+ path.parent.mkdir(parents=True, exist_ok=True)
195
+ update_iersdata(path)
194
196
 
195
197
 
196
198
  if __name__ == "__main__":
wwvb/wwvbtk.py CHANGED
@@ -5,12 +5,13 @@
5
5
  # SPDX-FileCopyrightText: 2021 Jeff Epler
6
6
  #
7
7
  # SPDX-License-Identifier: GPL-3.0-only
8
+ from __future__ import annotations
8
9
 
9
10
  import functools
10
11
  import threading
11
12
  import time
12
- from tkinter import Canvas, TclError, Tk # pylint: disable=import-error
13
- from typing import Any, Generator, Optional, Tuple
13
+ from tkinter import Canvas, TclError, Tk
14
+ from typing import Any, Generator
14
15
 
15
16
  import click
16
17
 
@@ -23,9 +24,7 @@ def _app() -> Tk:
23
24
  return Tk()
24
25
 
25
26
 
26
- def validate_colors( # pylint: disable=unused-argument
27
- ctx: Any, param: Any, value: str
28
- ) -> list[str]:
27
+ def validate_colors(ctx: Any, param: Any, value: str) -> list[str]: # noqa: ARG001
29
28
  """Check that all colors in a string are valid, splitting it to a list"""
30
29
  app = _app()
31
30
  colors = value.split()
@@ -55,9 +54,8 @@ DEFAULT_COLORS = "#3c3c3c #3c3c3c #3c3c3c #cc3c3c #88883c #3ccc3c"
55
54
  @click.option("--colors", callback=validate_colors, default=DEFAULT_COLORS)
56
55
  @click.option("--size", default=48)
57
56
  @click.option("--min-size", default=None)
58
- def main(colors: list[str], size: int, min_size: Optional[int]) -> None:
57
+ def main(colors: list[str], size: int, min_size: int | None) -> None: # noqa: PLR0915
59
58
  """Visualize the WWVB signal in realtime"""
60
-
61
59
  if min_size is None:
62
60
  min_size = size
63
61
 
@@ -67,7 +65,7 @@ def main(colors: list[str], size: int, min_size: Optional[int]) -> None:
67
65
  if deadline > now:
68
66
  time.sleep(deadline - now)
69
67
 
70
- def wwvbtick() -> Generator[Tuple[float, wwvb.AmplitudeModulation], None, None]:
68
+ def wwvbtick() -> Generator[tuple[float, wwvb.AmplitudeModulation], None, None]:
71
69
  """Yield consecutive values of the WWVB amplitude signal, going from minute to minute"""
72
70
  timestamp = time.time() // 60 * 60
73
71
 
@@ -79,13 +77,15 @@ def main(colors: list[str], size: int, min_size: Optional[int]) -> None:
79
77
  yield timestamp + i, code
80
78
  timestamp = timestamp + 60
81
79
 
82
- def wwvbsmarttick() -> Generator[Tuple[float, wwvb.AmplitudeModulation], None, None]:
83
- """Yield consecutive values of the WWVB amplitude signal but deal with time
84
- progressing unexpectedly, such as when the computer is suspended or NTP steps
85
- the clock backwards
80
+ def wwvbsmarttick() -> Generator[tuple[float, wwvb.AmplitudeModulation], None, None]:
81
+ """Yield consecutive values of the WWVB amplitude signal
82
+
83
+ .. but deal with time progressing unexpectedly, such as when the
84
+ computer is suspended or NTP steps the clock backwards
86
85
 
87
86
  When time goes backwards or advances by more than a minute, get a fresh
88
- wwvbtick object; otherwise, discard time signals more than 1s in the past."""
87
+ wwvbtick object; otherwise, discard time signals more than 1s in the past.
88
+ """
89
89
  while True:
90
90
  for stamp, code in wwvbtick():
91
91
  now = time.time()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wwvb
3
- Version: 3.0.7
3
+ Version: 4.0.0a0
4
4
  Summary: Generate WWVB timecodes for any desired time
5
5
  Home-page: https://github.com/jepler/wwvbpy
6
6
  Author: Jeff Epler
@@ -0,0 +1,23 @@
1
+ uwwvb.py,sha256=Ocys0AK10NocugDxNjIjUkL3_uVqD2Q6c2WLfqXmx1s,5732
2
+ wwvb/__init__.py,sha256=gSeXqukkcHnYCJAkbXk4eWBMqBu7n3GJ7CJM32XMiaU,30770
3
+ wwvb/__version__.py,sha256=vsEaiHcm9DvHyRWD600KxOTf-j-TilwuyCMsi2Ba3dE,413
4
+ wwvb/decode.py,sha256=d7bAG2pVsFMX0uxY6pMaz-psdbLXauSHh55JDaUT6W4,2713
5
+ wwvb/dut1table.py,sha256=uqaCnCOWr7ytx-nt3mmyhFb9jJVNP5N-WJX-glunKAk,890
6
+ wwvb/gen.py,sha256=0hgicarLgCtOgBgIpb9sU08yzKgCGuwIYOqblR34H5I,3791
7
+ wwvb/iersdata.py,sha256=NOItawXnXwd3Gq3K_cx85NVQ_iogLw3MDgzOI8q_75Y,924
8
+ wwvb/iersdata_dist.py,sha256=zQVO2AjiBTrhpSs21HUG9fL4S11K3WzTk0kP_eyMXz4,2364
9
+ wwvb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ wwvb/testcli.py,sha256=wa1E9iRaE62OBHshR4K_hxhIzSNxwpWy8rgoEKuhrqs,10168
11
+ wwvb/testdaylight.py,sha256=JW8UJK-FeAg9Kjy5F_aBYbUVj44DKpJOXQ-u9ooyprA,2485
12
+ wwvb/testls.py,sha256=Kz4-MWLaUKABwyql8sWdzvtg8gipxhHv4r-6fn3fptg,1720
13
+ wwvb/testpm.py,sha256=JR3V_EIm0Su3c4m5CcKpMANL3aZnpzEzDL3KhgKX3rM,905
14
+ wwvb/testuwwvb.py,sha256=SMvq85tJgjGMYHKsreCtlM4Wrb3MYOOjf5rKf9wuHYc,9176
15
+ wwvb/testwwvb.py,sha256=t0TUJhHOh-mRFD-GUvePzHs7D3DkNb_paRAI1uYH8l8,16807
16
+ wwvb/tz.py,sha256=XVYh0btrnyP_nUiZUwBjufkYbb26_DTiZVl-R_1BA2A,299
17
+ wwvb/updateiers.py,sha256=3Bg0cpQnTDrGWcHbi0rwZ4rSURJcO64Bds9FDTYLSK8,7382
18
+ wwvb/wwvbtk.py,sha256=WumGtKsAxMw1HMTfm5x4dOKmHikCaDBRZfh_WbF4iu0,4585
19
+ wwvb-4.0.0a0.dist-info/METADATA,sha256=lLqzL4USvZY6Md_rAg-k7OhzY2ySNPHjSWgTKwF8qG4,10292
20
+ wwvb-4.0.0a0.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
21
+ wwvb-4.0.0a0.dist-info/entry_points.txt,sha256=KSevvHWLEKxOxUQ-L-OQidD4Sj2BPEfhZ2TQhOgyys4,179
22
+ wwvb-4.0.0a0.dist-info/top_level.txt,sha256=0IYdkhEAMgurpv_F-76rlyn4GdxepGFzG99tivVdQVU,11
23
+ wwvb-4.0.0a0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,23 +0,0 @@
1
- uwwvb.py,sha256=zX0pkBvo-Nn1QNI2NWvCE0sH6dlSgz8IHoszhgMf8XI,5720
2
- wwvb/__init__.py,sha256=sRUn_0A7FMqbTcq2k3sX_13FS3gB3A1GOvr0vyYWDzo,30100
3
- wwvb/__version__.py,sha256=LJ4HJPpXI_UsV9wSih_sOZxstGnvrh7nUYp4E-ZbpXc,411
4
- wwvb/decode.py,sha256=PdRKvSVzyWwMyaM6BGkwXm7RqDW5EByw7NBcIpkNiqY,2795
5
- wwvb/dut1table.py,sha256=uqaCnCOWr7ytx-nt3mmyhFb9jJVNP5N-WJX-glunKAk,890
6
- wwvb/gen.py,sha256=v5n23peFc4wOuunAmAe0NogTQIttp5F4KOSwJMRqUlc,3792
7
- wwvb/iersdata.py,sha256=bMkIY5IAd0n93EQe16BoCqtDkXjnqkjG5L20F3Egp4o,994
8
- wwvb/iersdata_dist.py,sha256=O4sDlkJPeIcX8pSzrxl_5RptOdC_F8e_KxyV3JIEHjQ,2395
9
- wwvb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- wwvb/testcli.py,sha256=8Mgn6l7qddeudtZmZNCKgPvVJYoWBlQupuIdyvQlNtQ,10118
11
- wwvb/testdaylight.py,sha256=JW8UJK-FeAg9Kjy5F_aBYbUVj44DKpJOXQ-u9ooyprA,2485
12
- wwvb/testls.py,sha256=Kz4-MWLaUKABwyql8sWdzvtg8gipxhHv4r-6fn3fptg,1720
13
- wwvb/testpm.py,sha256=I5ajzZjUypyKszSe4sTnMZbS43nPmee4H1G3uZlHC_w,935
14
- wwvb/testuwwvb.py,sha256=kGINMTDNuA5TxBnFok-eamnlcxFXxjVuhvgELums31k,8444
15
- wwvb/testwwvb.py,sha256=Sl5s01OqDv8mEZsXocII24hj9CinBlphJCUFtAgXvE4,16143
16
- wwvb/tz.py,sha256=XVYh0btrnyP_nUiZUwBjufkYbb26_DTiZVl-R_1BA2A,299
17
- wwvb/updateiers.py,sha256=_yaMeaW4pWSkDl5b8Dur-gdoQVGode6bVjH1kvYvagU,7362
18
- wwvb/wwvbtk.py,sha256=CdzgUp6AbwMvSi62fJBDUlRDyApfVsE3qKL7FucBqno,4598
19
- wwvb-3.0.7.dist-info/METADATA,sha256=y2SJcCnjkd4htfzY7sL7OPCHQCmL2NwJ6fkuBGqnKjY,10290
20
- wwvb-3.0.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
21
- wwvb-3.0.7.dist-info/entry_points.txt,sha256=KSevvHWLEKxOxUQ-L-OQidD4Sj2BPEfhZ2TQhOgyys4,179
22
- wwvb-3.0.7.dist-info/top_level.txt,sha256=0IYdkhEAMgurpv_F-76rlyn4GdxepGFzG99tivVdQVU,11
23
- wwvb-3.0.7.dist-info/RECORD,,