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.
- wwvb-5.0.0/.coveragerc +15 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/codeql.yml +1 -1
- {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/cron.yml +2 -2
- {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/release.yml +1 -1
- {wwvb-4.0.0a0 → wwvb-5.0.0}/.github/workflows/test.yml +7 -10
- {wwvb-4.0.0a0 → wwvb-5.0.0}/.gitignore +1 -1
- {wwvb-4.0.0a0 → wwvb-5.0.0}/.pre-commit-config.yaml +4 -3
- {wwvb-4.0.0a0 → wwvb-5.0.0}/Makefile +15 -8
- {wwvb-4.0.0a0/src/wwvb.egg-info → wwvb-5.0.0}/PKG-INFO +6 -5
- {wwvb-4.0.0a0 → wwvb-5.0.0}/README.md +1 -1
- {wwvb-4.0.0a0 → wwvb-5.0.0}/adafruit_datetime.pyi +1 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0/doc}/conf.py +4 -2
- {wwvb-4.0.0a0 → wwvb-5.0.0/doc}/index.rst +1 -1
- wwvb-5.0.0/pyproject.toml +50 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/requirements-dev.txt +5 -5
- wwvb-5.0.0/requirements.txt +11 -0
- wwvb-5.0.0/setup.cfg +4 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/uwwvb.py +1 -1
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/__init__.py +7 -5
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/__version__.py +2 -2
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/decode.py +5 -2
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/dut1table.py +2 -2
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/gen.py +2 -3
- wwvb-5.0.0/src/wwvb/iersdata.json +1 -0
- wwvb-5.0.0/src/wwvb/iersdata.json.license +2 -0
- wwvb-5.0.0/src/wwvb/iersdata.py +37 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/tz.py +1 -2
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/updateiers.py +19 -57
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/wwvbtk.py +5 -3
- {wwvb-4.0.0a0 → wwvb-5.0.0/src/wwvb.egg-info}/PKG-INFO +6 -5
- wwvb-5.0.0/src/wwvb.egg-info/SOURCES.txt +74 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/requires.txt +1 -0
- {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testcli.py +3 -3
- {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testdaylight.py +1 -1
- {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testls.py +4 -5
- {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testpm.py +2 -2
- {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testuwwvb.py +4 -4
- {wwvb-4.0.0a0/src/wwvb → wwvb-5.0.0/test}/testwwvb.py +5 -8
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/both +0 -1
- wwvb-4.0.0a0/.coveragerc +0 -7
- wwvb-4.0.0a0/.pylintrc +0 -20
- wwvb-4.0.0a0/pyproject.toml +0 -25
- wwvb-4.0.0a0/setup.cfg +0 -49
- wwvb-4.0.0a0/src/wwvb/iersdata.py +0 -28
- wwvb-4.0.0a0/src/wwvb/iersdata_dist.py +0 -38
- wwvb-4.0.0a0/src/wwvb.egg-info/SOURCES.txt +0 -74
- {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/Apache-2.0.txt +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/CC0-1.0.txt +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/GPL-3.0-only.txt +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/LICENSES/Unlicense.txt +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/codecov.yml +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0/doc}/_static/.empty +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb/py.typed +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/dependency_links.txt +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/entry_points.txt +0 -0
- {wwvb-4.0.0a0 → wwvb-5.0.0}/src/wwvb.egg-info/top_level.txt +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/1998leapsecond +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/2012leapsecond +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/all-headers +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/bar +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/cradek +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/duration +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/enddst-phase +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/enddst-phase-2 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/endleapyear +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/leapday1 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/leapday28 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/leapday29 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/negleapsecond +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nextdst +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nextst +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nonleapday1 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/nonleapday28 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/phase +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startdst +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startdst-phase +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startdst-phase-2 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startleapyear +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/startst +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k-1 +0 -0
- {wwvb-4.0.0a0/tests → wwvb-5.0.0/test/wwvbgen_testcases}/y2k1 +0 -0
- {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: 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/
|
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
|
|
@@ -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:
|
77
|
-
run: make coverage PYTHON=python
|
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 }}
|
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,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:
|
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:
|
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.
|
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
|
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
|
-
|
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
|
-
#
|
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:
|
3
|
+
Version: 5.0.0
|
4
4
|
Summary: Generate WWVB timecodes for any desired time
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-->
|
@@ -16,8 +16,10 @@ import os
|
|
16
16
|
import re
|
17
17
|
import subprocess
|
18
18
|
import sys
|
19
|
+
import pathlib
|
19
20
|
|
20
|
-
|
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
|
@@ -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
|
wwvb-5.0.0/setup.cfg
ADDED
@@ -1,8 +1,7 @@
|
|
1
1
|
#!/usr/bin/python3
|
2
2
|
"""A library for WWVB timecodes"""
|
3
3
|
|
4
|
-
#
|
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
|
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
|
|
@@ -6,10 +6,13 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import sys
|
9
|
-
from typing import
|
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__":
|
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__":
|
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
|
-
#
|
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__":
|
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,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,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
|
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 / "
|
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
|
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
|
-
|
168
|
-
|
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
|
-
|
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
|
-
#
|
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
|
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:
|