wwvb 4.0.0a0__tar.gz → 5.0.0__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 (83) hide show
  1. wwvb-5.0.0/.coveragerc +15 -0
  2. {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/codeql.yml +1 -1
  3. {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/cron.yml +2 -2
  4. {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/release.yml +1 -1
  5. {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/test.yml +7 -10
  6. {wwvb-4.0.0a0 → wwvb-5.0.0}/.gitignore +1 -1
  7. {wwvb-4.0.0a0 → wwvb-5.0.0}/.pre-commit-config.yaml +4 -3
  8. {wwvb-4.0.0a0 → wwvb-5.0.0}/Makefile +15 -8
  9. {wwvb-4.0.0a0/src/wwvb.egg-info → wwvb-5.0.0}/PKG-INFO +6 -5
  10. {wwvb-4.0.0a0 → wwvb-5.0.0}/README.md +1 -1
  11. {wwvb-4.0.0a0 → wwvb-5.0.0}/adafruit_datetime.pyi +1 -0
  12. {wwvb-4.0.0a0 → wwvb-5.0.0/doc}/conf.py +4 -2
  13. {wwvb-4.0.0a0 → wwvb-5.0.0/doc}/index.rst +1 -1
  14. wwvb-5.0.0/pyproject.toml +50 -0
  15. {wwvb-4.0.0a0 → wwvb-5.0.0}/requirements-dev.txt +5 -5
  16. wwvb-5.0.0/requirements.txt +11 -0
  17. wwvb-5.0.0/setup.cfg +4 -0
  18. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/uwwvb.py +1 -1
  19. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/__init__.py +7 -5
  20. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/__version__.py +2 -2
  21. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/decode.py +5 -2
  22. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/dut1table.py +2 -2
  23. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/gen.py +2 -3
  24. wwvb-5.0.0/src/wwvb/iersdata.json +1 -0
  25. wwvb-5.0.0/src/wwvb/iersdata.json.license +2 -0
  26. wwvb-5.0.0/src/wwvb/iersdata.py +37 -0
  27. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/tz.py +1 -2
  28. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/updateiers.py +19 -57
  29. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/wwvbtk.py +5 -3
  30. {wwvb-4.0.0a0 → wwvb-5.0.0/src/wwvb.egg-info}/PKG-INFO +6 -5
  31. wwvb-5.0.0/src/wwvb.egg-info/SOURCES.txt +74 -0
  32. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/requires.txt +1 -0
  33. {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testcli.py +3 -3
  34. {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testdaylight.py +1 -1
  35. {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testls.py +4 -5
  36. {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testpm.py +2 -2
  37. {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testuwwvb.py +4 -4
  38. {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testwwvb.py +5 -8
  39. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/both +0 -1
  40. wwvb-4.0.0a0/.coveragerc +0 -7
  41. wwvb-4.0.0a0/.pylintrc +0 -20
  42. wwvb-4.0.0a0/pyproject.toml +0 -25
  43. wwvb-4.0.0a0/setup.cfg +0 -49
  44. wwvb-4.0.0a0/src/wwvb/iersdata.py +0 -28
  45. wwvb-4.0.0a0/src/wwvb/iersdata_dist.py +0 -38
  46. wwvb-4.0.0a0/src/wwvb.egg-info/SOURCES.txt +0 -74
  47. {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/Apache-2.0.txt +0 -0
  48. {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/CC0-1.0.txt +0 -0
  49. {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/GPL-3.0-only.txt +0 -0
  50. {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/Unlicense.txt +0 -0
  51. {wwvb-4.0.0a0 → wwvb-5.0.0}/codecov.yml +0 -0
  52. {wwvb-4.0.0a0 → wwvb-5.0.0/doc}/_static/.empty +0 -0
  53. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/py.typed +0 -0
  54. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/dependency_links.txt +0 -0
  55. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/entry_points.txt +0 -0
  56. {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/top_level.txt +0 -0
  57. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/1998leapsecond +0 -0
  58. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/2012leapsecond +0 -0
  59. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/all-headers +0 -0
  60. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/bar +0 -0
  61. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/cradek +0 -0
  62. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/duration +0 -0
  63. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/enddst-phase +0 -0
  64. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/enddst-phase-2 +0 -0
  65. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/endleapyear +0 -0
  66. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/leapday1 +0 -0
  67. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/leapday28 +0 -0
  68. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/leapday29 +0 -0
  69. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/negleapsecond +0 -0
  70. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nextdst +0 -0
  71. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nextst +0 -0
  72. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nonleapday1 +0 -0
  73. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nonleapday28 +0 -0
  74. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/phase +0 -0
  75. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startdst +0 -0
  76. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startdst-phase +0 -0
  77. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startdst-phase-2 +0 -0
  78. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startleapyear +0 -0
  79. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startst +0 -0
  80. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k +0 -0
  81. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k-1 +0 -0
  82. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k1 +0 -0
  83. {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k1-1 +0 -0
wwvb-5.0.0/.coveragerc ADDED
@@ -0,0 +1,15 @@
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-only
4
+ [report]
5
+ exclude_also =
6
+ def __repr__
7
+ if self.debug:
8
+ if settings.DEBUG
9
+ raise AssertionError
10
+ raise NotImplementedError
11
+ if 0:
12
+ if __name__ == .__main__.:
13
+ if TYPE_CHECKING:
14
+ class .*\bProtocol\):
15
+ @(abc\.)?abstractmethod
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2022 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2022-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: CC0-1.0
4
4
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: CC0-1.0
4
4
 
@@ -41,4 +41,4 @@ jobs:
41
41
  git config user.name "${GITHUB_ACTOR} (github actions cron)"
42
42
  git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
43
43
  git remote set-url --push origin https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
44
- if git commit -m"update iersdata" src/wwvb/iersdata_dist.py; then git push origin HEAD:main; fi
44
+ if git commit -m"update iersdata" src/wwvb/iersdata.json; then git push origin HEAD:main; fi
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: CC0-1.0
4
4
 
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: CC0-1.0
4
4
 
@@ -41,19 +41,13 @@ jobs:
41
41
  - '3.13.0-alpha.0 - 3.13'
42
42
  os-version:
43
43
  - 'ubuntu-latest'
44
- coverage-core:
45
- - 'ctrace'
46
44
  include:
47
45
  - os-version: 'macos-latest'
48
46
  python-version: '3.x'
49
47
  - os-version: 'windows-latest'
50
48
  python-version: '3.x'
51
- - os-version: 'ubuntu-latest'
52
- python-version: '3.12'
53
- coverage-core: 'sysmon'
54
49
  - os-version: 'ubuntu-latest'
55
50
  python-version: 'pypy-3.10'
56
- coverage-core: 'pytrace'
57
51
 
58
52
  runs-on: ${{ matrix.os-version }}
59
53
  steps:
@@ -73,14 +67,17 @@ jobs:
73
67
  if: (! startsWith(matrix.python-version, 'pypy-'))
74
68
  run: make mypy PYTHON=python
75
69
 
76
- - name: Test
77
- run: make coverage PYTHON=python COVERAGE_CORE=${{ matrix.coverage-core }}
70
+ - name: Coverage
71
+ run: make coverage PYTHON=python
72
+
73
+ - name: Test installed version
74
+ run: make test_venv PYTHON=python
78
75
 
79
76
  - name: Upload Coverage as artifact
80
77
  if: always()
81
78
  uses: actions/upload-artifact@v4
82
79
  with:
83
- name: coverage for ${{ matrix.python-version }} on ${{ matrix.os-version }} ${{ matrix.coverage-core }}
80
+ name: coverage for ${{ matrix.python-version }} on ${{ matrix.os-version }}
84
81
  path: coverage.xml
85
82
 
86
83
  pre-commit:
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: CC0-1.0
4
4
 
@@ -1,4 +1,5 @@
1
1
  # SPDX-FileCopyrightText: 2020 Diego Elio Pettenò
2
+ # SPDX-FileCopyrightText: 2020-2024 Jeff Epler
2
3
  #
3
4
  # SPDX-License-Identifier: Unlicense
4
5
 
@@ -7,20 +8,20 @@ default_language_version:
7
8
 
8
9
  repos:
9
10
  - repo: https://github.com/pre-commit/pre-commit-hooks
10
- rev: v4.6.0
11
+ rev: v5.0.0
11
12
  hooks:
12
13
  - id: check-yaml
13
14
  - id: end-of-file-fixer
14
15
  exclude: tests
15
16
  - id: trailing-whitespace
16
- exclude: tests
17
+ exclude: test/wwvbgen_testcases
17
18
  - repo: https://github.com/fsfe/reuse-tool
18
19
  rev: v4.0.3
19
20
  hooks:
20
21
  - id: reuse
21
22
  - repo: https://github.com/astral-sh/ruff-pre-commit
22
23
  # Ruff version.
23
- rev: v0.5.1
24
+ rev: v0.6.9
24
25
  hooks:
25
26
  # Run the linter.
26
27
  - id: ruff
@@ -17,6 +17,11 @@ STEPECHO = @echo
17
17
  endif
18
18
 
19
19
  PYTHON ?= python3
20
+ ifeq ($(OS),Windows_NT)
21
+ ENVPYTHON ?= _env/Scripts/python.exe
22
+ else
23
+ ENVPYTHON ?= _env/bin/python3
24
+ endif
20
25
 
21
26
  .PHONY: default
22
27
  default: coverage mypy
@@ -25,12 +30,18 @@ COVERAGE_INCLUDE=--include "src/**/*.py"
25
30
  .PHONY: coverage
26
31
  coverage:
27
32
  $(Q)$(PYTHON) -mcoverage erase
28
- $(Q)env PYTHONPATH=src $(PYTHON) -mcoverage run --branch -p -m unittest discover -s src
33
+ $(Q)env PYTHONPATH=src $(PYTHON) -mcoverage run --branch -p -m unittest discover -s test
29
34
  $(Q)$(PYTHON) -mcoverage combine -q
30
35
  $(Q)$(PYTHON) -mcoverage html $(COVERAGE_INCLUDE)
31
36
  $(Q)$(PYTHON) -mcoverage xml $(COVERAGE_INCLUDE)
32
37
  $(Q)$(PYTHON) -mcoverage report --fail-under=100 $(COVERAGE_INCLUDE)
33
38
 
39
+ .PHONY: test_venv
40
+ test_venv:
41
+ $(Q)$(PYTHON) -mvenv --clear _env
42
+ $(Q)$(ENVPYTHON) -mpip install .
43
+ $(Q)$(ENVPYTHON) -m unittest discover -s test
44
+
34
45
  .PHONY: mypy
35
46
  mypy:
36
47
  $(Q)mypy --strict --no-warn-unused-ignores src
@@ -46,19 +57,15 @@ update:
46
57
  # from the environment for the first two.
47
58
  SPHINXOPTS ?= -a -E -j auto
48
59
  SPHINXBUILD ?= sphinx-build
49
- SOURCEDIR = .
60
+ SOURCEDIR = doc
50
61
  BUILDDIR = _build
51
62
 
52
63
  # Route particular targets to Sphinx using the new
53
64
  # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
54
65
  .PHONY: html
55
66
  html:
56
- @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
57
-
58
- # Pass the desired coverage tracer name to subprocesses
59
- export COVERAGE_CORE
67
+ $(Q)$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
60
68
 
61
- # Copyright (C) 2021 Jeff Epler <jepler@gmail.com>
62
- # SPDX-FileCopyrightText: 2021 Jeff Epler
69
+ # SPDX-FileCopyrightText: 2024 Jeff Epler
63
70
  #
64
71
  # SPDX-License-Identifier: GPL-3.0-only
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wwvb
3
- Version: 4.0.0a0
3
+ Version: 5.0.0
4
4
  Summary: Generate WWVB timecodes for any desired time
5
- Home-page: https://github.com/jepler/wwvbpy
6
- Author: Jeff Epler
7
- Author-email: jepler@gmail.com
5
+ Author-email: Jeff Epler <jepler@gmail.com>
6
+ Project-URL: Source, https://github.com/jepler/wwvbpy
7
+ Project-URL: Documentation, https://github.com/jepler/wwvbpy
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
@@ -22,9 +22,10 @@ Requires-Dist: leapseconddata
22
22
  Requires-Dist: platformdirs
23
23
  Requires-Dist: python-dateutil
24
24
  Requires-Dist: requests
25
+ Requires-Dist: tzdata
25
26
 
26
27
  <!--
27
- SPDX-FileCopyrightText: 2021 Jeff Epler
28
+ SPDX-FileCopyrightText: 2021-2024 Jeff Epler
28
29
 
29
30
  SPDX-License-Identifier: GPL-3.0-only
30
31
  -->
@@ -1,5 +1,5 @@
1
1
  <!--
2
- SPDX-FileCopyrightText: 2021 Jeff Epler
2
+ SPDX-FileCopyrightText: 2021-2024 Jeff Epler
3
3
 
4
4
  SPDX-License-Identifier: GPL-3.0-only
5
5
  -->
@@ -1,4 +1,5 @@
1
1
  # SPDX-FileCopyrightText: 2015-2021 Jukka Lehtosalo and contributors
2
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
3
  #
3
4
  # SPDX-License-Identifier: Apache-2.0
4
5
 
@@ -16,8 +16,10 @@ import os
16
16
  import re
17
17
  import subprocess
18
18
  import sys
19
+ import pathlib
19
20
 
20
- sys.path.insert(0, os.path.abspath("."))
21
+ ROOT = pathlib.Path(__file__).absolute().parent.parent
22
+ sys.path.insert(0, str(ROOT / "src"))
21
23
 
22
24
 
23
25
  # -- Project information -----------------------------------------------------
@@ -80,6 +82,6 @@ html_static_path = ["_static"]
80
82
  autodoc_typehints = "description"
81
83
  autodoc_class_signature = "separated"
82
84
 
83
- # SPDX-FileCopyrightText: 2021 Jeff Epler
85
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
84
86
  #
85
87
  # SPDX-License-Identifier: GPL-3.0-only
@@ -1,4 +1,4 @@
1
- .. SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ .. SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  ..
3
3
  .. SPDX-License-Identifier: GPL-3.0-only
4
4
 
@@ -0,0 +1,50 @@
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-only
4
+
5
+ [build-system]
6
+ requires = [
7
+ "setuptools>=68",
8
+ "setuptools_scm[toml]>=6.0",
9
+ ]
10
+ build-backend = "setuptools.build_meta"
11
+ [tool.setuptool]
12
+ package_dir = {"" = "src"}
13
+ include-package-data = true
14
+
15
+ [tool.setuptools.dynamic]
16
+ readme = {file = ["README.md"], content-type="text/markdown"}
17
+ dependencies = {file = "requirements.txt"}
18
+ [tool.setuptools_scm]
19
+ write_to = "src/wwvb/__version__.py"
20
+ [tool.ruff.lint]
21
+ select = ["E", "F", "D", "I", "N", "UP", "YTT", "BLE", "B", "FBT", "A", "COM", "C4", "DTZ", "FA", "ISC", "ICN", "PIE", "PYI", "Q", "RET", "SIM", "TID", "TCH", "ARG", "PTH", "C", "R", "W", "FLY", "RUF", "PL"]
22
+ ignore = ["D203", "D213", "D400", "D415", "ISC001", "E741", "C901", "PLR0911", "PLR2004", "PLR0913"]
23
+ [tool.ruff]
24
+ line-length = 120
25
+ [project]
26
+ name = "wwvb"
27
+ authors = [{name = "Jeff Epler", email = "jepler@gmail.com"}]
28
+ description = "Generate WWVB timecodes for any desired time"
29
+ dynamic = ["readme","version","dependencies"]
30
+ classifiers = [
31
+ "Programming Language :: Python :: 3",
32
+ "Programming Language :: Python :: 3.9",
33
+ "Programming Language :: Python :: 3.10",
34
+ "Programming Language :: Python :: 3.11",
35
+ "Programming Language :: Python :: Implementation :: PyPy",
36
+ "Programming Language :: Python :: Implementation :: CPython",
37
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
38
+ "Operating System :: OS Independent",
39
+ ]
40
+ requires-python = ">=3.9"
41
+ [project.urls]
42
+ Source = "https://github.com/jepler/wwvbpy"
43
+ Documentation = "https://github.com/jepler/wwvbpy"
44
+ [project.scripts]
45
+ wwvbgen = "wwvb.gen:main"
46
+ wwvbdecode = "wwvb.decode:main"
47
+ dut1table = "wwvb.dut1table:main"
48
+ updateiers = "wwvb.updateiers:main"
49
+ [project.gui-scripts]
50
+ wwvbtk = "wwvb.wwvbtk:main"
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: GPL-3.0-only
4
4
  adafruit-circuitpython-datetime
@@ -14,12 +14,12 @@ pre-commit
14
14
  python-dateutil
15
15
  requests; implementation_name=="cpython"
16
16
  setuptools>=68; implementation_name=="cpython"
17
- sphinx
17
+ sphinx>=7,<8
18
18
  sphinx-autodoc-typehints
19
19
  sphinx-rtd-theme
20
20
  twine; implementation_name=="cpython"
21
- types-beautifulsoup4
22
- types-python-dateutil
23
- types-requests
21
+ types-beautifulsoup4; implementation_name=="cpython"
22
+ types-python-dateutil; implementation_name=="cpython"
23
+ types-requests; implementation_name=="cpython"
24
24
  tzdata
25
25
  wheel
@@ -0,0 +1,11 @@
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
+ #
3
+ # SPDX-License-Identifier: GPL-3.0-only
4
+ adafruit-circuitpython-datetime
5
+ beautifulsoup4
6
+ click
7
+ leapseconddata
8
+ platformdirs
9
+ python-dateutil
10
+ requests
11
+ tzdata
wwvb-5.0.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2021 Jeff Epler
1
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
2
2
  #
3
3
  # SPDX-License-Identifier: GPL-3.0-only
4
4
 
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/python3
2
2
  """A library for WWVB timecodes"""
3
3
 
4
- # Copyright (C) 2011-2020 Jeff Epler <jepler@gmail.com>
5
- # SPDX-FileCopyrightText: 2021 Jeff Epler
4
+ # SPDX-FileCopyrightText: 2011-2024 Jeff Epler
6
5
  #
7
6
  # SPDX-License-Identifier: GPL-3.0-only
8
7
 
@@ -12,11 +11,14 @@ import datetime
12
11
  import enum
13
12
  import json
14
13
  import warnings
15
- from typing import Any, Generator, NamedTuple, TextIO, TypeVar
14
+ from typing import TYPE_CHECKING, Any, NamedTuple, TextIO, TypeVar
16
15
 
17
16
  from . import iersdata
18
17
  from .tz import Mountain
19
18
 
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Generator
21
+
20
22
  HOUR = datetime.timedelta(seconds=3600)
21
23
  SECOND = datetime.timedelta(seconds=1)
22
24
  T = TypeVar("T")
@@ -871,6 +873,8 @@ def print_timecodes(
871
873
  style_chars = styles.get(style, ["0", "1", "2"])
872
874
  first = True
873
875
  for _ in range(minutes):
876
+ if not first and channel == "both":
877
+ print(file=file)
874
878
  if first or all_timecodes:
875
879
  if not first:
876
880
  print(file=file)
@@ -888,8 +892,6 @@ def print_timecodes(
888
892
  pfx = " " * len(pfx)
889
893
  if channel in ("phase", "both"):
890
894
  print(f"{pfx} {tc.to_pm_string(style_chars)}", file=file)
891
- if channel == "both":
892
- print(file=file)
893
895
  w = w.next_minute()
894
896
 
895
897
 
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '4.0.0a0'
16
- __version_tuple__ = version_tuple = (4, 0, 0)
15
+ __version__ = version = '5.0.0'
16
+ __version_tuple__ = version_tuple = (5, 0, 0)
@@ -6,10 +6,13 @@
6
6
  from __future__ import annotations
7
7
 
8
8
  import sys
9
- from typing import Generator
9
+ from typing import TYPE_CHECKING
10
10
 
11
11
  import wwvb
12
12
 
13
+ if TYPE_CHECKING:
14
+ from collections.abc import Generator
15
+
13
16
  # State 1: Unsync'd
14
17
  # Marker: State 2
15
18
  # Other: State 1
@@ -86,5 +89,5 @@ def main() -> None:
86
89
  print(w)
87
90
 
88
91
 
89
- if __name__ == "__main__": # pragma no cover
92
+ if __name__ == "__main__":
90
93
  main()
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
- # SPDX-FileCopyrightText: 2021 Jeff Epler
3
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
4
4
  #
5
5
  # SPDX-License-Identifier: GPL-3.0-only
6
6
 
@@ -28,5 +28,5 @@ def main() -> None:
28
28
  print(date)
29
29
 
30
30
 
31
- if __name__ == "__main__": # pragma no branch
31
+ if __name__ == "__main__":
32
32
  main()
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/python3
2
2
  """A command-line program for generating wwvb timecodes"""
3
3
 
4
- # Copyright (C) 2011-2020 Jeff Epler <jepler@gmail.com>
5
- # SPDX-FileCopyrightText: 2021 Jeff Epler
4
+ # SPDX-FileCopyrightText: 2011-2024 Jeff Epler
6
5
  #
7
6
  # SPDX-License-Identifier: GPL-3.0-only
8
7
 
@@ -124,5 +123,5 @@ def main(
124
123
  print_timecodes(w, minutes, channel, style, all_timecodes=all_timecodes, file=sys.stdout)
125
124
 
126
125
 
127
- if __name__ == "__main__": # pragma no branch
126
+ if __name__ == "__main__":
128
127
  main()
@@ -0,0 +1 @@
1
+ {"START": "1972-01-01", "OFFSETS_GZ": "H4sIAFEb/WYC/+2aa3LDMAiEL5uHLDuxnN5/pn/aTmfSSiAWhGR9J8gsywJylqVHPtqxZuH/7leeI0fKsGd5EngQ2WisJWKegrThDa6aJFnL0u4wYZkCE2UmSF0U+13vCveStC6JTfQyW3O86HLJf0SvDgy5u4FCI+WVKRuy0KMjJeXoULIvMDmEWgeRxAJtwXquPCIBqbLh/gbfv0mcxk3mHV9tYiATZP8W/zgw2wd5LpJnY+WErI8abJ3opaIW6592+YMbjSsNWQFlNVVtuhjhtQzSUh4MEpOdDrSW6qsUv+O+Dt+XkIONSrUwvWmTsmq5LO9xsZ+EgcDK+MIESDaYmxSxGlgbGOFjBXMjbV7lc6zlmQ0i48oH5P4+vK7i/AHc7tfTXDtffqFi3m6WhApPSTyDvArU5vUDhm7YaNQYGASVbbwLUBtI2PrhSiZNbvCRrtGUGu0GbjDhJ3aLCx5dQFjt0LFovmWB96e6tktqMenoULXajVS3asBibP3kYXrpmZxnsS2Yf2xRPrHbvQ2D9wjfL4C6b4PWV4otW0vWUYkeWE5M8M594oLbxP77xcl4NuBkG0dfM3xOUf/T0GF+ur+J5pljcODEUZkXg6vIdLYy7g3oZU3bPNDnc8qwGdJZMmAurUsRj6tOo95zP6fb9YPWp5OuZ5X7q2DrmsG/VCyTyaREnDRhnUxOjcmKM9b/R7R0+gQ5cs/LtEwAAA=="}
@@ -0,0 +1,2 @@
1
+ SPDX-FileCopyrightText: Public domain
2
+ SPDX-License-Identifier: CC0-1.0
@@ -0,0 +1,37 @@
1
+ # -*- python3 -*-
2
+ """Retrieve iers data, possibly from user or site data or from the wwvbpy distribution"""
3
+
4
+ # SPDX-FileCopyrightText: 2011-2024 Jeff Epler
5
+ #
6
+ # SPDX-License-Identifier: GPL-3.0-only
7
+
8
+ import binascii
9
+ import datetime
10
+ import gzip
11
+ import importlib.resources
12
+ import json
13
+
14
+ import platformdirs
15
+
16
+ __all__ = ["DUT1_DATA_START", "DUT1_OFFSETS", "start", "span", "end"]
17
+
18
+ content: dict[str, str] = {"START": "1970-01-01", "OFFSETS_GZ": "H4sIAFNx1mYC/wMAAAAAAAAAAAA="}
19
+
20
+ path = importlib.resources.files("wwvb") / "iersdata.json"
21
+ content = json.loads(path.read_text(encoding="utf-8"))
22
+
23
+ for location in [ # pragma no cover
24
+ platformdirs.user_data_path("wwvbpy", "unpythonic.net"),
25
+ platformdirs.site_data_path("wwvbpy", "unpythonic.net"),
26
+ ]:
27
+ path = location / "iersdata.json"
28
+ if path.exists():
29
+ content = json.loads(path.read_text(encoding="utf-8"))
30
+ break
31
+
32
+ DUT1_DATA_START = datetime.date.fromisoformat(content["START"])
33
+ DUT1_OFFSETS = gzip.decompress(binascii.a2b_base64(content["OFFSETS_GZ"])).decode("ascii")
34
+
35
+ start = datetime.datetime.combine(DUT1_DATA_START, datetime.time(), tzinfo=datetime.timezone.utc)
36
+ span = datetime.timedelta(days=len(DUT1_OFFSETS))
37
+ end = start + span
@@ -1,8 +1,7 @@
1
1
  # -*- python -*-
2
2
  """A library for WWVB timecodes"""
3
3
 
4
- # Copyright (C) 2011-2020 Jeff Epler <jepler@gmail.com>
5
- # SPDX-FileCopyrightText: 2021 Jeff Epler
4
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
6
5
  #
7
6
  # SPDX-License-Identifier: GPL-3.0-only
8
7
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/python3
2
2
 
3
- # SPDX-FileCopyrightText: 2021 Jeff Epler
3
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
4
4
  #
5
5
  # SPDX-License-Identifier: GPL-3.0-only
6
6
 
@@ -8,10 +8,12 @@
8
8
 
9
9
  from __future__ import annotations
10
10
 
11
+ import binascii
11
12
  import csv
12
13
  import datetime
14
+ import gzip
13
15
  import io
14
- import itertools
16
+ import json
15
17
  import pathlib
16
18
  from typing import Callable
17
19
 
@@ -20,15 +22,7 @@ import click
20
22
  import platformdirs
21
23
  import requests
22
24
 
23
- DIST_PATH = pathlib.Path(__file__).parent / "iersdata_dist.py"
24
-
25
- OLD_TABLE_START: datetime.date | None = None
26
- OLD_TABLE_END: datetime.date | None = None
27
- if DIST_PATH.exists():
28
- import wwvb.iersdata_dist
29
-
30
- OLD_TABLE_START = wwvb.iersdata_dist.DUT1_DATA_START
31
- OLD_TABLE_END = OLD_TABLE_START + datetime.timedelta(days=len(wwvb.iersdata_dist.DUT1_OFFSETS) - 1)
25
+ DIST_PATH = pathlib.Path(__file__).parent / "iersdata.json"
32
26
 
33
27
  IERS_URL = "https://datacenter.iers.org/data/csv/finals2000A.all.csv"
34
28
  IERS_PATH = pathlib.Path("finals2000A.all.csv")
@@ -47,7 +41,7 @@ def _get_text(url: str) -> str:
47
41
  return pathlib.Path(url).read_text(encoding="utf-8")
48
42
 
49
43
 
50
- def update_iersdata( # noqa: PLR0915, PLR0912
44
+ def update_iersdata( # noqa: PLR0915
51
45
  target_path: pathlib.Path,
52
46
  ) -> None:
53
47
  """Update iersdata.py"""
@@ -124,57 +118,25 @@ def update_iersdata( # noqa: PLR0915, PLR0912
124
118
  assert wwvb_start is not None
125
119
  patch(wwvb_start, wwvb_data_stamp + datetime.timedelta(days=1), wwvb_dut1)
126
120
 
127
- with target_path.open("w", encoding="utf-8") as output:
128
-
129
- def code(*args: str) -> None:
130
- """Print to the output file"""
131
- print(*args, file=output)
132
-
133
- code("# -*- python3 -*-")
134
- code("# fmt: off")
135
- code('"""File generated from public data - not subject to copyright"""')
136
- code("# SPDX" + "-FileCopyrightText: Public domain")
137
- code("# SPDX" + "-License-Identifier: CC0-1.0")
138
- code("# isort: skip_file")
139
- code("import datetime")
140
-
141
- code("__all__ = ['DUT1_DATA_START', 'DUT1_OFFSETS']")
142
- code(f"DUT1_DATA_START = {table_start!r}")
143
- c = sorted(chr(ord("a") + ch + 10) for ch in set(offsets))
144
- code(f"{','.join(c)} = tuple({''.join(c)!r})")
145
- code(f"DUT1_OFFSETS = str( # {table_start.year:04d}{table_start.month:02d}{table_start.day:02d}")
146
- line = ""
147
- j = 0
148
-
149
- for val, it in itertools.groupby(offsets):
150
- part = ""
151
- ch = chr(ord("a") + val + 10)
152
- sz = len(list(it))
153
- if j:
154
- part = part + "+"
155
- part = part + ch if sz < 2 else part + f"{ch}*{sz}"
156
- j += sz
157
- if len(line + part) > 60:
158
- d = table_start + datetime.timedelta(j - 1)
159
- code(f" {line:<60s} # {d.year:04d}{d.month:02d}{d.day:02d}")
160
- line = part
161
- else:
162
- line = line + part
163
- d = table_start + datetime.timedelta(j - 1)
164
- code(f" {line:<60s} # {d.year:04d}{d.month:02d}{d.day:02d}")
165
- code(")")
166
121
  table_end = table_start + datetime.timedelta(len(offsets) - 1)
167
- if OLD_TABLE_START:
168
- print(f"old iersdata covered {OLD_TABLE_START} .. {OLD_TABLE_END}")
122
+ base = ord("a") + 10
123
+ offsets_bin = bytes(base + ch for ch in offsets)
124
+
125
+ target_path.write_text(
126
+ json.dumps(
127
+ {
128
+ "START": table_start.isoformat(),
129
+ "OFFSETS_GZ": binascii.b2a_base64(gzip.compress(offsets_bin)).decode("ascii").strip(),
130
+ },
131
+ ),
132
+ )
133
+
169
134
  print(f"iersdata covers {table_start} .. {table_end}")
170
135
 
171
136
 
172
137
  def iersdata_path(callback: Callable[[str, str], pathlib.Path]) -> pathlib.Path:
173
138
  """Find out the path for this directory"""
174
- print("iersdata_path", callback)
175
- r = callback("wwvbpy", "unpythonic.net") / "wwvb_iersdata.py"
176
- print(f"iersdata_path {r=!r}")
177
- return r
139
+ return callback("wwvbpy", "unpythonic.net") / "iersdata.json"
178
140
 
179
141
 
180
142
  @click.command()
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/python3
2
2
  """Visualize the WWVB signal in realtime"""
3
3
 
4
- # Copyright (C) 2011-2020 Jeff Epler <jepler@gmail.com>
5
- # SPDX-FileCopyrightText: 2021 Jeff Epler
4
+ # SPDX-FileCopyrightText: 2021-2024 Jeff Epler
6
5
  #
7
6
  # SPDX-License-Identifier: GPL-3.0-only
8
7
  from __future__ import annotations
@@ -11,12 +10,15 @@ import functools
11
10
  import threading
12
11
  import time
13
12
  from tkinter import Canvas, TclError, Tk
14
- from typing import Any, Generator
13
+ from typing import TYPE_CHECKING, Any
15
14
 
16
15
  import click
17
16
 
18
17
  import wwvb
19
18
 
19
+ if TYPE_CHECKING:
20
+ from collections.abc import Generator
21
+
20
22
 
21
23
  @functools.cache
22
24
  def _app() -> Tk: