diff --git a/.github/workflows/check_style.yml b/.github/workflows/check_style.yml index bd043c1..1dcc5a4 100644 --- a/.github/workflows/check_style.yml +++ b/.github/workflows/check_style.yml @@ -11,6 +11,6 @@ jobs: env: SKIP: no-commit-to-branch steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - uses: pre-commit/action@v2.0.0 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - uses: pre-commit/action@v3.0.1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a68f68e..38bc830 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.6.0 hooks: - id: check-merge-conflict - id: check-yaml @@ -12,22 +12,21 @@ repos: - id: trailing-whitespace args: [--markdown-linebreak-ext=md] - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.13.2 hooks: - id: isort args: [--profile, black] - repo: https://github.com/asottile/pyupgrade - rev: v2.31.1 + rev: v3.15.2 hooks: - id: pyupgrade args: [--py37-plus] - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 7.0.0 hooks: - id: flake8 - additional_dependencies: [flake8-typing-imports==1.7.0] args: ['--ignore=E501,E203,E731,W503'] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 24.3.0 hooks: - id: black diff --git a/README.md b/README.md index 776f72e..789acc6 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,15 @@ galcheat ### Options - **`-s `**: print information for a given survey - **`--refs`**: print the source for each parameter +- **`--rich`**: use pretty printing for the terminal (needs the `rich` library installed) - **`-h, --help`**: get help ### Examples ```sh -galcheat -s LSST # LSST info -galcheat --refs # all surveys info with refs -galcheat --refs -s HSC # HSC info with refs +galcheat -s LSST # LSST info +galcheat --refs # all surveys info with refs +galcheat --refs -s HSC # HSC info with refs +galcheat -s LSST --rich # pretty print rich terminal output for LSST info ``` API diff --git a/docs/index.md b/docs/index.md index d2e3dab..8bccb04 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,14 +16,16 @@ galcheat - **`-s `**: print information for a given survey - **`--refs`**: print the source for each parameter +- **`--rich`**: use pretty printing for the terminal (needs the `rich` library installed) - **`-h, --help`**: get help ### Examples ```sh -galcheat -s LSST # LSST info -galcheat --refs # all surveys info with refs -galcheat --refs -s HSC # HSC info with refs +galcheat -s LSST # LSST info +galcheat --refs # all surveys info with refs +galcheat --refs -s HSC # HSC info with refs +galcheat -s LSST --rich # pretty print rich terminal output for LSST survey info ``` ## Installation @@ -49,3 +51,11 @@ The developer tools needed to perform tests and linting and compile the docs loc ```sh python -m pip install -U galcheat[dev] ``` + +### Rich display (new in v1.1) + +For a better terminal experience, install the `rich` library and use it together with the `--rich` option from `galcheat` + +```sh +python -m pip install rich +``` diff --git a/galcheat/__init__.py b/galcheat/__init__.py index 2c7f72f..48062cd 100644 --- a/galcheat/__init__.py +++ b/galcheat/__init__.py @@ -49,4 +49,5 @@ interest or reporting inconsistent values. """ + from galcheat.helpers import available_surveys, get_survey # noqa diff --git a/galcheat/__main__.py b/galcheat/__main__.py index bc30775..5772dca 100644 --- a/galcheat/__main__.py +++ b/galcheat/__main__.py @@ -24,22 +24,53 @@ def _survey_parser(): dest="show_refs", help="Print the references for each parameter.", ) + parser.add_argument( + "--rich", + action="store_true", + dest="use_rich", + help="Use rich console for printing.", + ) return parser.parse_args() def main(): args = _survey_parser() + use_rich = False + if args.use_rich: + try: + from rich.console import Console + + console = Console() + use_rich = True + except ImportError: + print( + "The rich library is not installed by default with galcheat.", + "In order to use rich printing, please consider installing it using pip.", + "`python -m pip install rich`", + "\nDefaulting to classic display...\n", + ) + if args.survey_name is None: - for survey in available_surveys: - print_survey(survey, show_refs=args.show_refs) - print(_LINEBREAK) + surveys = available_surveys else: - try: - print_survey(args.survey_name, show_refs=args.show_refs) - except ValueError as e: - print(e) - print(_FOOTER) + surveys = [args.survey_name] + + if use_rich: + from galcheat.rich import display_references, display_survey + + for survey in surveys: + console.print("") + console.print(display_survey(survey)) + if args.show_refs: + console.print(display_references(survey)) + console.print(_FOOTER) + else: + for survey in surveys: + print_survey(survey, show_refs=args.show_refs) + if survey != surveys[-1]: + print(_LINEBREAK) + print(_FOOTER) if __name__ == "__main__": diff --git a/galcheat/rich.py b/galcheat/rich.py new file mode 100644 index 0000000..64ab453 --- /dev/null +++ b/galcheat/rich.py @@ -0,0 +1,115 @@ +import textwrap + +from galcheat.helpers import Survey, get_survey + +_SATELLITE = "🛰️️ " +_TELESCOPE = "🔭️ " + + +def _rich_survey_name(survey): + if survey.name in ["Euclid_VIS", "COSMOS"]: + icon = _SATELLITE + else: + icon = _TELESCOPE + + return f"{icon} [b]{survey.name}[/b]" + + +def display_survey(survey): + from rich.console import Group + from rich.panel import Panel + from rich.text import Text + + if not isinstance(survey, Survey): + survey = get_survey(survey) + + survey_desc = Text( + textwrap.fill(survey.description, 40), no_wrap=False, justify="left" + ) + + survey_info = _survey_table(survey) + + filters_info = [ + _filter_panel(survey.get_filter(filter)) for filter in survey.available_filters + ] + + display_info = [ + survey_desc, + "\n", + survey_info, + "\n", + "[b]Filter info:", + ] + filters_info + + return Panel( + Group(*display_info), + padding=1, + expand=False, + title=_rich_survey_name(survey), + title_align="center", + ) + + +def _survey_table(survey): + from rich.table import Table + + survey_info = Table.grid() + survey_info.add_column(justify="left") + survey_info.add_column(justify="left") + + survey_info.add_row("Pixel scale: ", f"{survey.pixel_scale}") + survey_info.add_row("Mirror diameter: ", f"{survey.mirror_diameter}") + survey_info.add_row("Effective area: ", f"{survey.effective_area:.2f}") + survey_info.add_row("Obscuration: ", f"{survey.obscuration:.2f}") + survey_info.add_row("Gain: ", f"{survey.gain}") + survey_info.add_row("Zeropoint airmass: ", f"{survey.zeropoint_airmass}") + survey_info.add_row("Available filters: ", ", ".join(survey.available_filters)) + + return survey_info + + +def _filter_panel(filter): + from rich.panel import Panel + from rich.table import Table + + filter_info = Table.grid() + filter_info.add_column(justify="left") + filter_info.add_column(justify="left") + + filter_info.add_row("PSF FWHM: ", f"{filter.psf_fwhm}") + filter_info.add_row("Zeropoint: ", f"{filter.zeropoint}") + filter_info.add_row("Sky brightness: ", f"{filter.sky_brightness:.2f}") + filter_info.add_row("Full exposure time: ", f"{filter.full_exposure_time}") + filter_info.add_row("Effective wavelength: ", f"{filter.effective_wavelength}") + + return Panel( + filter_info, + padding=0, + expand=False, + title=f"[b]{filter.name}[/]", + title_align="left", + ) + + +def display_references(survey): + from rich.box import HEAVY_HEAD + from rich.table import Table + + if not isinstance(survey, Survey): + survey = get_survey(survey) + + ref_table = Table( + "Parameter", + "Source", + "Comments", + title=f"[b]{survey.name} references[/]", + # show_lines=True, + box=HEAVY_HEAD, + ) + for name, param in survey.references.items(): + link = param["link"] + source = f"[u cyan link={link}]{link}" + comment = textwrap.fill(param["comment"], 60) + ref_table.add_row(name, source, comment) + + return ref_table diff --git a/setup.cfg b/setup.cfg index 62041bc..045ea3e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,6 +47,7 @@ dev = mkdocs-material>=8.2 mkdocstrings>=0.18 pytkdocs[numpy-style]>=0.16 + rich>=13.7 scripts = speclite>=0.15