Handling file expiration

* Generate a catalog of the expiration dates for files,
* Detect when a file has expired and raise a ``UserWarning``
This commit is contained in:
Bruno Bord 2019-09-22 19:00:44 +02:00
parent 94225ce126
commit b681451b59
No known key found for this signature in database
GPG Key ID: 9499EA6788BF80A1
8 changed files with 97 additions and 6 deletions

View File

@ -7,6 +7,8 @@
* Dropped compatibility with Python 3.3 and 3.4, as skyfield did.
* Added basic tests for the ``get_skyfield_data_path`` function using `tox`.
* Added automated tests through Travis CI.
* Generate a catalog of the expiration dates for files,
* Detect when a file has expired and raise a ``UserWarning``
## 0.0.2 (2019-08-23)

View File

@ -55,6 +55,18 @@ If you want to make sure that the data files would **never** be downloaded, you
load = Loader(get_skyfield_data_path(), expire=False)
```
Whenever a file contained in the catalog has expired, you're going to receive a warning when loading the `skyfield-data` path:
```python
>>> from skyfield_data import get_skyfield_data_path
>>> from skyfield.api import Loader
>>> load = Loader(get_skyfield_data_path())
/home/[redacted]/skyfield_data/expirations.py:25: RuntimeWarning: The file de421.bsp has expired. Please upgrade your version of `skyfield-data` or expect computation errors
RuntimeWarning
```
By default, the loading isn't blocked, but it's strongly recommended to upgrade to a more recent version, to make sure you're not going to make wrong astronomical computations.
## Developers
We're providing a ``Makefile`` with basic targets to play around with the toolkit. use ``make help`` to get more details.

View File

@ -2,17 +2,17 @@
import argparse
from datetime import date
from datetime import datetime, timedelta
from os.path import join, exists
from os.path import join, exists, abspath, dirname
import shutil
from urllib.request import urlopen
from jplephem.spk import DAF, SPK
from skyfield_data import get_skyfield_data_path
JPL = "ftp://ssd.jpl.nasa.gov/pub/eph/planets/bsp"
USNO = "http://maia.usno.navy.mil/ser7"
IERS = "https://hpiers.obspm.fr/iers/bul/bulc"
__DATA_PATH = abspath(join(dirname(__file__), "skyfield_data", "data"))
def calendar_date(jd_integer):
"""Convert Julian Day `jd_integer` into a Gregorian (year, month, day)."""
@ -188,14 +188,21 @@ def main(args):
"expiration_func": leap_seconds_expiration
},
}
# For expiration date content
target_expiration = abspath(
join(__DATA_PATH, '..', 'expiration_data.py')
)
expiration_dates = {}
for filename, params in items.items():
server = params["server"]
url = "{}/{}".format(server, filename)
target = join(get_skyfield_data_path(), filename)
target = join(__DATA_PATH, filename)
expiration_date = get_expiration_date(target, params)
expiration_dates[filename] = expiration_date
if args.check_only:
expiration_date = get_expiration_date(target, params)
print(
"File: {} => expiration: {}".format(
filename, expiration_date or "`unknown`"
@ -214,6 +221,13 @@ def main(args):
download(url, target)
else:
print("Skipping {} ({})".format(filename, reason))
# Generating the expiration date file.
expiration_template = """import datetime
EXPIRATIONS = {}
"""
with open(target_expiration, 'w') as fd:
fd.write(expiration_template.format(expiration_dates))
print("\nDone\n")

View File

@ -1,4 +1,5 @@
from os.path import dirname, join, abspath
from .expirations import check_expirations
__DATA_PATH = abspath(join(dirname(__file__), "data"))
@ -14,6 +15,7 @@ def get_skyfield_data_path():
load = Loader(get_skyfield_data_path())
planets = load('de421.bsp')
"""
check_expirations()
return __DATA_PATH

View File

@ -0,0 +1,3 @@
import datetime
EXPIRATIONS = {'de421.bsp': datetime.date(2053, 10, 8), 'deltat.data': datetime.date(2020, 6, 1), 'deltat.preds': datetime.date(2021, 1, 1), 'Leap_Second.dat': datetime.date(2020, 7, 28)}

View File

@ -0,0 +1,26 @@
import warnings
from datetime import date
from os.path import dirname, join, abspath
from os import listdir
from .expiration_data import EXPIRATIONS
__DATA_PATH = abspath(join(dirname(__file__), "data"))
def get_all():
return EXPIRATIONS
def check_expirations():
expirations = get_all()
files = listdir(__DATA_PATH)
for filename in files:
expiration_date = expirations.get(filename)
if expiration_date and date.today() >= expiration_date:
warnings.warn(
("The file {} has expired."
" Please upgrade your version of `skyfield-data` or expect"
" computation errors").format(filename),
RuntimeWarning
)

View File

@ -0,0 +1,32 @@
import mock
from datetime import date
from datetime import timedelta
from skyfield_data import get_skyfield_data_path
@mock.patch('skyfield_data.expirations.get_all')
def test_no_expiration(mocked_exp):
mocked_exp.return_value = {}
with mock.patch('warnings.warn') as mocked_warn:
get_skyfield_data_path()
assert mocked_warn.call_count == 0
@mock.patch('skyfield_data.expirations.get_all')
def test_expiration_deltat_distant_future(mocked_exp):
mocked_exp.return_value = {
'deltat.data': date.today() + timedelta(days=10000)
}
with mock.patch('warnings.warn') as mocked_warn:
get_skyfield_data_path()
assert mocked_warn.call_count == 0
@mock.patch('skyfield_data.expirations.get_all')
def test_expiration_deltat_yesterday(mocked_exp):
mocked_exp.return_value = {
'deltat.data': date.today() - timedelta(days=1)
}
with mock.patch('warnings.warn') as mocked_warn:
get_skyfield_data_path()
assert mocked_warn.call_count == 1

View File

@ -4,7 +4,7 @@ envlist = py27,py35,py36,py37
[testenv]
commands =
pytest -s
pytest -s {posargs}
deps =
.[tests]