diff --git a/apps/cli/executables/null/README.md b/apps/cli/executables/null/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b2cc894843867d2fa2ab8c1a76de9c55036411ac --- /dev/null +++ b/apps/cli/executables/null/README.md @@ -0,0 +1,41 @@ + +# datafetcher: data-fetcher for the AAT/PPI + +This is an implementation of the NRAO archive's Java-based data-fetcher in Python, as a research experiment on how it could be modularized and re-structured. + +Use cases datafetcher is intended to handle: + * works for both science products and ancillary products + * download a product from the NRAO archive by specifying its product locator + * download a product from the NRAO archive by providing a path to a locator report + * streaming or direct copy downloads based on file location and execution site + +This is intended to be a library wrapped in a command line interface. + +``` +usage: datafetcher [-h] + (--product-locator PRODUCT_LOCATOR | --location-file LOCATION_FILE) + [--dry-run] [--output-dir OUTPUT_DIR] [--verbose] + [--profile PROFILE] + +Retrieve a product (a science product or an ancillary product) from the NRAO archive, +either by specifying the product's locator or by providing the path to a product +locator report. + +Optional Arguments: + --dry-run dry run, do not fetch product + --output-dir OUTPUT_DIR + output directory, default current directory + --verbose make a lot of noise + --profile PROFILE CAPO profile to use + +Return Codes: + 1: no CAPO profile provided + 2: missing required setting + 3: request to locator service timed out + 4: too many redirects on locator service + 5: catastrophic error on request service + 6: product locator not found + 7: not able to open specified location file + 8: error fetching file from NGAS server + 9: retrieved file not expected size +``` diff --git a/apps/cli/executables/null/__init__.py b/apps/cli/executables/null/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apps/cli/executables/null/setup.py b/apps/cli/executables/null/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..84415da77099fcd47dcf8120dd31be7b8a1f0b1c --- /dev/null +++ b/apps/cli/executables/null/setup.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from pathlib import Path + +from setuptools import setup + +VERSION = open('_version.py').readlines()[-1].split()[-1].strip("\"'") +README = Path('README.md').read_text() + +requires = [ + 'pika>=1.1,<2', + 'pycapo>=0.3.0,<1.0', + 'beautifulsoup4>=4.9.1,<5.0', + 'lxml>=4.3.2,<5.0', + 'psycopg2>=2.8.5,<3.0', + 'pyopenssl>=19.1.0,<20.0', + 'requests>=2.23,<3.0' +] + +tests_require = [ + 'pytest>=5.4,<6.0' +] +setup( + name=Path().absolute().name, + version=VERSION, + description='NRAO Archive Data Fetcher Script', + long_description=README, + author='NRAO SSA Team', + author_email='dms-ssa@nrao.edu', + url='TBD', + license="GPL", + install_requires=requires, + tests_require=tests_require, + keywords=[], + packages=['datafetcher'], + package_dir={'':'src'}, + classifiers=[ + 'Programming Language :: Python :: 3.8' + ], + entry_points={ + 'console_scripts': ['datafetcher = datafetcher.commands:main'] + }, +) diff --git a/apps/cli/executables/null/src/null/__init__.py b/apps/cli/executables/null/src/null/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/apps/cli/executables/null/src/null/_version.py b/apps/cli/executables/null/src/null/_version.py new file mode 100644 index 0000000000000000000000000000000000000000..f27d146a3f39885ce269bacf9ab4510254147c8d --- /dev/null +++ b/apps/cli/executables/null/src/null/_version.py @@ -0,0 +1,2 @@ +""" Version information for this package, don't put anything else here. """ +___version___ = '4.0.0a1.dev1' diff --git a/apps/cli/executables/null/src/null/null.py b/apps/cli/executables/null/src/null/null.py new file mode 100644 index 0000000000000000000000000000000000000000..282c1cc6bbe792ca32ce0757c6c699a41be2c97e --- /dev/null +++ b/apps/cli/executables/null/src/null/null.py @@ -0,0 +1,84 @@ +import os +import sys +import time +import logging +import argparse + +from _version import ___version___ as version + +_DESCRIPTION = """Workspaces null executable, a status capture test of the system. Version {}""" + +logger = logging.getLogger("null") +logger.setLevel(logging.DEBUG) + +class Null: + def __init__(self, args, verbose): + self.args = args + self.verbose = verbose + self.args_to_funcs = { + 'greeting': self.print_greeting, + 'exit': self.exit_with_failure, + 'nap': self.take_nap, + 'dump': self.dump_core + } + + def print_greeting(self): + logger.debug("Hello, world!") + if self.verbose: + logger.debug("And goodbye, world...") + + def exit_with_failure(self): + if self.verbose: + logger.error("Error purposefully induced.") + sys.exit('Exiting with status code -1') + + def take_nap(self): + print(self.verbose) + if self.verbose: + print("wtf??") + logger.debug("Going to sleep...") + time.sleep(5) + if self.verbose: + logger.debug("Waking up.") + + def dump_core(self): + if self.verbose: + logger.debug("Aborting and dumping core...", stack_info=True) + os.abort() + + def execute(self): + for arg, val in vars(self.args).items(): + if val and arg in self.args_to_funcs: + self.args_to_funcs[arg]() + +def make_arg_parser(): + parser = argparse.ArgumentParser(description=_DESCRIPTION.format(version), + formatter_class=argparse.RawTextHelpFormatter) + options = parser.add_argument_group('options', 'settings for altered program behavior') + options.add_argument('-v', '--verbose', action='store_true', + required=False, dest='verbose', default=False, + help='allow the program the gift of speech') + functions = parser.add_mutually_exclusive_group(required=False) + functions.add_argument('-g', '--greeting', action='store_true', + required=False, dest='greeting', default=False, + help='print out a friendly greeting') + functions.add_argument('-e', '--exit', action='store_true', + required=False, dest='exit', default=False, + help='print error message and exit with status code -1') + functions.add_argument('-n', '--nap', action='store_true', + required=False, dest='nap', default=False, + help='take a short nap') + functions.add_argument('-d', '--dump', action='store_true', + required=False, dest='dump', default=False, + help='abort program and dump core') + return parser + + +def main(): + arg_parser = make_arg_parser() + args = arg_parser.parse_args() + null = Null(args, args.verbose) + null.execute() + +if __name__ == '__main__': + main() \ No newline at end of file