Source code for planetary_coverage.cli.kernel
"""CLI kernel module."""
import sys
from argparse import ArgumentParser
from pathlib import Path
from urllib.error import HTTPError
from ..misc import wget
REMOTES = {
'generic': 'https://naif.jpl.nasa.gov/pub/naif/generic_kernels/',
'nasa': 'https://naif.jpl.nasa.gov/pub/naif',
'esa': 'https://spiftp.esac.esa.int/data/SPICE',
'jaxa': 'https://data.darts.isas.jaxa.jp/pub/spice',
}
[docs]def cli_kernel_download(argv=None):
"""CLI to download kernel(s) from a kernel registry.
The user can provide an agency + mission argument
(eg. `--esa JUICE`) to point to the known kernel registry
or provide directly the URL (`-r/--remote`). If none is
provided, the cli will attempt to download it from NAIF
generic kernels.
Note: only one remote is accepted. Otherwise an ERROR is raised.
The user can also specify where to store the kernels (with
`-o/--kernels-dir`).
If the requested kernel is already present locally, the cli
will raise an ERROR, unless the user provide a `-f/--force` flag
(to overwrite it) or `-s/--skip` flag (to continue).
Hint: the user can provide a list a kernels to download them
in a batch.
Tip: if no kernels is provided, the cli will return the remote
location url.
"""
parser = ArgumentParser(description='Planetary-coverage kernel downloader.')
parser.add_argument('kernel', nargs='*', help='One or multiple kernel file(s).')
parser.add_argument('-r', '--remote',
help='Kernel remote location (HTTPS/FTP). '
'Some shortcuts are available.')
parser.add_argument('--nasa', metavar='MISSION',
help='NASA mission (hosted on NAIF website).')
parser.add_argument('--esa', metavar='MISSION',
help='ESA mission (hosted on ESAC website).')
parser.add_argument('--jaxa', metavar='MISSION',
help='JAXA mission (hosted on ISAS website).')
parser.add_argument('-o', '--kernels-dir', default='.',
help='Output kernel directory.')
parser.add_argument('-f', '--force', action='store_true',
help='Overwrite the file if they are already present locally.')
parser.add_argument('-s', '--skip', action='store_true',
help='Skip existing files.')
args, _ = parser.parse_known_args(argv)
# Check remotes duplicates
remotes = {
agency: mission for agency, mission in {
'url': args.remote, 'nasa': args.nasa, 'esa': args.esa, 'jaxa': args.jaxa
}.items() if mission is not None
}
n_remotes = len(remotes)
if n_remotes > 1:
sys.stderr.write(
f'>>> ERROR: {n_remotes} remotes provided ({", ".join(remotes.keys())}). '
'Only one is accepted.\n'
)
sys.exit(1)
# Extract the selected remote
if not remotes:
remote = REMOTES['generic']
elif 'url' in remotes:
remote = remotes['url']
remote += '' if remote.endswith('/') else '/'
else:
for agency, mission in remotes.items():
remote = f'{REMOTES[agency]}/{mission}/kernels/'
# Kernel output folder
kernel_dir = Path(args.kernels_dir)
# Download the kernels
for kernel in args.kernel:
fname = kernel_dir / kernel
try:
wget(remote + kernel, fname, skip=args.skip, force=args.force)
except FileExistsError:
sys.stderr.write(
f'>>> ERROR: {fname} is already present locally. '
'Use `--force` to overwrite it or `--skip` to continue.\n'
)
sys.exit(1)
except HTTPError:
sys.stderr.write('>>> ERROR: kernel not found.\n')
sys.exit(1)
# Display remote location if no kernel is provided
if not args.kernel:
_ = sys.stdout.write(remote + '\n') if remotes else parser.print_help()