| @@ -28,7 +28,13 @@ from datetime import date | |||||
| from . import dumper, environment, debug | from . import dumper, environment, debug | ||||
| from .date import parse_date | from .date import parse_date | ||||
| from .geolocation import get_position | from .geolocation import get_position | ||||
| from .utils import KOSMORRO_VERSION, KOSMORROLIB_VERSION, colored, set_colors_activated | |||||
| from .utils import ( | |||||
| KOSMORRO_VERSION, | |||||
| KOSMORROLIB_VERSION, | |||||
| colored, | |||||
| set_colors_activated, | |||||
| print_stderr, | |||||
| ) | |||||
| from .exceptions import ( | from .exceptions import ( | ||||
| InvalidOutputFormatError, | InvalidOutputFormatError, | ||||
| UnavailableFeatureError, | UnavailableFeatureError, | ||||
| @@ -52,7 +58,7 @@ def run(): | |||||
| try: | try: | ||||
| compute_date = parse_date(args.date) | compute_date = parse_date(args.date) | ||||
| except ValueError as error: | except ValueError as error: | ||||
| print(colored(error.args[0], color="red", attrs=["bold"])) | |||||
| print_stderr(colored(error.args[0], color="red", attrs=["bold"])) | |||||
| return -1 | return -1 | ||||
| position = None | position = None | ||||
| @@ -79,8 +85,7 @@ def run(): | |||||
| ) | ) | ||||
| ) | ) | ||||
| if position is None: | if position is None: | ||||
| print() | |||||
| print( | |||||
| print_stderr( | |||||
| colored( | colored( | ||||
| _( | _( | ||||
| "PDF output will not contain the ephemerides, because you didn't provide the observation " | "PDF output will not contain the ephemerides, because you didn't provide the observation " | ||||
| @@ -109,15 +114,15 @@ def run(): | |||||
| args.show_graph, | args.show_graph, | ||||
| ) | ) | ||||
| except InvalidOutputFormatError as error: | except InvalidOutputFormatError as error: | ||||
| print(colored(error.msg, "red")) | |||||
| print_stderr(colored(error.msg, "red")) | |||||
| debug.debug_print(error) | debug.debug_print(error) | ||||
| return 3 | return 3 | ||||
| except UnavailableFeatureError as error: | except UnavailableFeatureError as error: | ||||
| print(colored(error.msg, "red")) | |||||
| print_stderr(colored(error.msg, "red")) | |||||
| debug.debug_print(error) | debug.debug_print(error) | ||||
| return 2 | return 2 | ||||
| except DateRangeError as error: | except DateRangeError as error: | ||||
| print(colored(error.msg, "red")) | |||||
| print_stderr(colored(error.msg, "red")) | |||||
| debug.debug_print(error) | debug.debug_print(error) | ||||
| return 1 | return 1 | ||||
| @@ -128,11 +133,11 @@ def run(): | |||||
| with open(args.output, opening_mode) as output_file: | with open(args.output, opening_mode) as output_file: | ||||
| output_file.write(file_content) | output_file.write(file_content) | ||||
| except UnavailableFeatureError as error: | except UnavailableFeatureError as error: | ||||
| print(colored(error.msg, "red")) | |||||
| print_stderr(colored(error.msg, "red")) | |||||
| debug.debug_print(error) | debug.debug_print(error) | ||||
| return 2 | return 2 | ||||
| except OSError as error: | except OSError as error: | ||||
| print( | |||||
| print_stderr( | |||||
| colored( | colored( | ||||
| _('The file could not be saved in "{path}": {error}').format( | _('The file could not be saved in "{path}": {error}').format( | ||||
| path=args.output, error=error.strerror | path=args.output, error=error.strerror | ||||
| @@ -146,7 +151,7 @@ def run(): | |||||
| elif not output.is_file_output_needed(): | elif not output.is_file_output_needed(): | ||||
| print(output) | print(output) | ||||
| else: | else: | ||||
| print( | |||||
| print_stderr( | |||||
| colored( | colored( | ||||
| _("Please provide a file path to export in this format (--output)."), | _("Please provide a file path to export in this format (--output)."), | ||||
| color="red", | color="red", | ||||
| @@ -165,35 +170,32 @@ def get_information( | |||||
| colors: bool, | colors: bool, | ||||
| show_graph: bool, | show_graph: bool, | ||||
| ) -> dumper.Dumper: | ) -> dumper.Dumper: | ||||
| if position is not None: | |||||
| try: | |||||
| try: | |||||
| if position is not None: | |||||
| eph = get_ephemerides( | eph = get_ephemerides( | ||||
| for_date=compute_date, position=position, timezone=timezone | for_date=compute_date, position=position, timezone=timezone | ||||
| ) | ) | ||||
| except OutOfRangeDateError as error: | |||||
| raise DateRangeError(error.min_date, error.max_date) | |||||
| else: | |||||
| eph = [] | |||||
| else: | |||||
| eph = [] | |||||
| try: | |||||
| moon_phase = get_moon_phase(for_date=compute_date, timezone=timezone) | |||||
| except OutOfRangeDateError as error: | |||||
| moon_phase = None | |||||
| print( | |||||
| colored( | |||||
| _( | |||||
| "Moon phase can only be computed between {min_date} and {max_date}" | |||||
| ).format( | |||||
| min_date=format_date(error.min_date, "long"), | |||||
| max_date=format_date(error.max_date, "long"), | |||||
| ), | |||||
| "yellow", | |||||
| try: | |||||
| moon_phase = get_moon_phase(for_date=compute_date, timezone=timezone) | |||||
| except OutOfRangeDateError as error: | |||||
| moon_phase = None | |||||
| print_stderr( | |||||
| colored( | |||||
| _( | |||||
| "Moon phase can only be computed between {min_date} and {max_date}" | |||||
| ).format( | |||||
| min_date=format_date(error.min_date, "long"), | |||||
| max_date=format_date(error.max_date, "long"), | |||||
| ), | |||||
| "yellow", | |||||
| ) | |||||
| ) | ) | ||||
| ) | |||||
| events_list = get_events(compute_date, timezone) | |||||
| events_list = get_events(compute_date, timezone) | |||||
| try: | |||||
| return get_dumpers()[output_format]( | return get_dumpers()[output_format]( | ||||
| ephemerides=eph, | ephemerides=eph, | ||||
| moon_phase=moon_phase, | moon_phase=moon_phase, | ||||
| @@ -205,6 +207,8 @@ def get_information( | |||||
| ) | ) | ||||
| except KeyError as error: | except KeyError as error: | ||||
| raise InvalidOutputFormatError(output_format, list(get_dumpers().keys())) | raise InvalidOutputFormatError(output_format, list(get_dumpers().keys())) | ||||
| except OutOfRangeDateError as error: | |||||
| raise DateRangeError(error.min_date, error.max_date) | |||||
| def get_dumpers() -> {str: dumper.Dumper}: | def get_dumpers() -> {str: dumper.Dumper}: | ||||
| @@ -8,7 +8,7 @@ msgid "" | |||||
| msgstr "" | msgstr "" | ||||
| "Project-Id-Version: PROJECT VERSION\n" | "Project-Id-Version: PROJECT VERSION\n" | ||||
| "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" | "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" | ||||
| "POT-Creation-Date: 2022-04-27 11:36+0000\n" | |||||
| "POT-Creation-Date: 2022-04-29 12:01+0000\n" | |||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
| @@ -17,94 +17,94 @@ msgstr "" | |||||
| "Content-Transfer-Encoding: 8bit\n" | "Content-Transfer-Encoding: 8bit\n" | ||||
| "Generated-By: Babel 2.10.1\n" | "Generated-By: Babel 2.10.1\n" | ||||
| #: kosmorro/__main__.py:76 | |||||
| #: kosmorro/__main__.py:82 | |||||
| msgid "" | msgid "" | ||||
| "Save the planet and paper!\n" | "Save the planet and paper!\n" | ||||
| "Consider printing your PDF document only if really necessary, and use the" | "Consider printing your PDF document only if really necessary, and use the" | ||||
| " other side of the sheet." | " other side of the sheet." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:85 | |||||
| #: kosmorro/__main__.py:90 | |||||
| msgid "" | msgid "" | ||||
| "PDF output will not contain the ephemerides, because you didn't provide " | "PDF output will not contain the ephemerides, because you didn't provide " | ||||
| "the observation coordinates." | "the observation coordinates." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:137 | |||||
| #: kosmorro/__main__.py:142 | |||||
| msgid "The file could not be saved in \"{path}\": {error}" | msgid "The file could not be saved in \"{path}\": {error}" | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:151 | |||||
| #: kosmorro/__main__.py:156 | |||||
| msgid "Please provide a file path to export in this format (--output)." | msgid "Please provide a file path to export in this format (--output)." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:184 | |||||
| #: kosmorro/__main__.py:187 | |||||
| msgid "Moon phase can only be computed between {min_date} and {max_date}" | msgid "Moon phase can only be computed between {min_date} and {max_date}" | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:234 | |||||
| #: kosmorro/__main__.py:238 | |||||
| msgid "Running on Python {python_version} with Kosmorrolib v{kosmorrolib_version}" | msgid "Running on Python {python_version} with Kosmorrolib v{kosmorrolib_version}" | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:247 | |||||
| #: kosmorro/__main__.py:251 | |||||
| msgid "" | msgid "" | ||||
| "Compute the ephemerides and the events for a given date and a given " | "Compute the ephemerides and the events for a given date and a given " | ||||
| "position on Earth." | "position on Earth." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:250 | |||||
| #: kosmorro/__main__.py:254 | |||||
| msgid "" | msgid "" | ||||
| "By default, only the events will be computed for today.\n" | "By default, only the events will be computed for today.\n" | ||||
| "To compute also the ephemerides, latitude and longitude arguments are " | "To compute also the ephemerides, latitude and longitude arguments are " | ||||
| "needed." | "needed." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:263 | |||||
| #: kosmorro/__main__.py:267 | |||||
| msgid "Show the program version" | msgid "Show the program version" | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:271 | |||||
| #: kosmorro/__main__.py:275 | |||||
| msgid "" | msgid "" | ||||
| "The format to output the information to. If not provided, the output " | "The format to output the information to. If not provided, the output " | ||||
| "format will be inferred from the file extension of the output file." | "format will be inferred from the file extension of the output file." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:281 | |||||
| #: kosmorro/__main__.py:285 | |||||
| msgid "" | msgid "" | ||||
| "The observer's position on Earth, in the \"{latitude},{longitude}\" " | "The observer's position on Earth, in the \"{latitude},{longitude}\" " | ||||
| "format. Can also be set in the KOSMORRO_POSITION environment variable." | "format. Can also be set in the KOSMORRO_POSITION environment variable." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:291 | |||||
| #: kosmorro/__main__.py:295 | |||||
| msgid "" | msgid "" | ||||
| "The date for which the ephemerides must be calculated. Can be in the " | "The date for which the ephemerides must be calculated. Can be in the " | ||||
| "YYYY-MM-DD format or an interval in the \"[+-]YyMmDd\" format (with Y, M," | "YYYY-MM-DD format or an interval in the \"[+-]YyMmDd\" format (with Y, M," | ||||
| " and D numbers). Defaults to current date." | " and D numbers). Defaults to current date." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:302 | |||||
| #: kosmorro/__main__.py:306 | |||||
| msgid "" | msgid "" | ||||
| "The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3). " | "The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3). " | ||||
| "Can also be set in the KOSMORRO_TIMEZONE environment variable." | "Can also be set in the KOSMORRO_TIMEZONE environment variable." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:311 | |||||
| #: kosmorro/__main__.py:315 | |||||
| msgid "Disable the colors in the console." | msgid "Disable the colors in the console." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:318 | |||||
| #: kosmorro/__main__.py:322 | |||||
| msgid "" | msgid "" | ||||
| "A file to export the output to. If not given, the standard output is " | "A file to export the output to. If not given, the standard output is " | ||||
| "used. This argument is needed for PDF format." | "used. This argument is needed for PDF format." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:327 | |||||
| #: kosmorro/__main__.py:331 | |||||
| msgid "" | msgid "" | ||||
| "Do not generate a graph to represent the rise and set times in the PDF " | "Do not generate a graph to represent the rise and set times in the PDF " | ||||
| "format." | "format." | ||||
| msgstr "" | msgstr "" | ||||
| #: kosmorro/__main__.py:335 | |||||
| #: kosmorro/__main__.py:339 | |||||
| msgid "Show debugging messages" | msgid "Show debugging messages" | ||||
| msgstr "" | msgstr "" | ||||
| @@ -1,6 +1,7 @@ | |||||
| #!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
| from termcolor import colored as do_color | from termcolor import colored as do_color | ||||
| from sys import stderr | |||||
| try: | try: | ||||
| from importlib.metadata import version | from importlib.metadata import version | ||||
| @@ -25,3 +26,7 @@ def colored(text, color=None, on_color=None, attrs=None): | |||||
| return text | return text | ||||
| return do_color(text, color, on_color, attrs) | return do_color(text, color, on_color, attrs) | ||||
| def print_stderr(*values: object): | |||||
| print(*values, file=stderr) | |||||
| @@ -29,7 +29,7 @@ def test_with_incorrect_date_values(): | |||||
| result = execute(KOSMORRO + arg) | result = execute(KOSMORRO + arg) | ||||
| assert not result.is_successful() | assert not result.is_successful() | ||||
| assert ( | assert ( | ||||
| result.stdout | |||||
| result.stderr | |||||
| == f"The date {value} does not match the required YYYY-MM-DD format or the offset format.\n" | == f"The date {value} does not match the required YYYY-MM-DD format or the offset format.\n" | ||||
| ) | ) | ||||
| @@ -38,7 +38,7 @@ def test_with_incorrect_date_values(): | |||||
| result = execute(KOSMORRO + arg) | result = execute(KOSMORRO + arg) | ||||
| assert not result.is_successful() | assert not result.is_successful() | ||||
| assert ( | assert ( | ||||
| result.stdout == f"The date {value} is not valid: month must be in 1..12\n" | |||||
| result.stderr == f"The date {value} is not valid: month must be in 1..12\n" | |||||
| ) | ) | ||||
| @@ -47,6 +47,16 @@ def test_with_out_of_range_dates(): | |||||
| result = execute(KOSMORRO + arg) | result = execute(KOSMORRO + arg) | ||||
| assert not result.is_successful() | assert not result.is_successful() | ||||
| assert ( | assert ( | ||||
| result.stdout | |||||
| result.stderr | |||||
| == "Moon phase can only be computed between August 9, 1899 and September 26, 2053\nThe date must be between July 28, 1899 and October 8, 2053\n" | |||||
| ) | |||||
| def test_with_out_of_range_dates_for_moon_phase_only(): | |||||
| for arg in [["-d", "1899-07-30"], ["-d", "2053-10-06"]]: | |||||
| result = execute(KOSMORRO + arg) | |||||
| assert result.is_successful() | |||||
| assert ( | |||||
| result.stderr | |||||
| == "Moon phase can only be computed between August 9, 1899 and September 26, 2053\n" | == "Moon phase can only be computed between August 9, 1899 and September 26, 2053\n" | ||||
| ) | ) | ||||
| @@ -171,35 +171,37 @@ def test_tex_output(): | |||||
| i += 1 | i += 1 | ||||
| # disabled for now, waiting for the new pdf generator | |||||
| # def test_pdf_output(): | |||||
| # if platform != "linux": | |||||
| # # Consider it works everywhere if it does at least on Linux | |||||
| # return | |||||
| # | |||||
| # tmp_dir = tempfile.mkdtemp() | |||||
| # result = execute( | |||||
| # KOSMORRO | |||||
| # + [ | |||||
| # "--position=50.5876,3.0624", | |||||
| # "-d2020-01-27", | |||||
| # "--format=pdf", | |||||
| # f"--output={tmp_dir}/document.pdf", | |||||
| # ] | |||||
| # ) | |||||
| # | |||||
| # if environ.get("TEXLIVE_INSTALLED") is None: | |||||
| # assert not result.is_successful() | |||||
| # assert ( | |||||
| # result.stdout | |||||
| # == """Save the planet and paper! | |||||
| # Consider printing your PDF document only if really necessary, and use the other side of the sheet. | |||||
| # Building PDF was not possible, because some dependencies are not installed. | |||||
| # Please look at the documentation at https://kosmorro.space/cli/generate-pdf/ for more information. | |||||
| # """ | |||||
| # ) | |||||
| def test_pdf_output(): | |||||
| if platform != "linux": | |||||
| # Consider it works everywhere if it does at least on Linux | |||||
| return | |||||
| tmp_dir = tempfile.mkdtemp() | |||||
| result = execute( | |||||
| KOSMORRO | |||||
| + [ | |||||
| "--position=50.5876,3.0624", | |||||
| "-d2020-01-27", | |||||
| "--format=pdf", | |||||
| f"--output={tmp_dir}/document.pdf", | |||||
| ] | |||||
| ) | |||||
| if environ.get("TEXLIVE_INSTALLED") is None: | |||||
| assert not result.is_successful() | |||||
| assert ( | |||||
| result.stdout | |||||
| == "Save the planet and paper!\nConsider printing your PDF document only if really necessary, and use the other side of the sheet.\n" | |||||
| ) | |||||
| assert ( | |||||
| result.stderr | |||||
| == "Building PDF was not possible, because some dependencies are not installed.\nPlease look at the documentation at https://kosmorro.space/cli/generate-pdf/ for more information.\n" | |||||
| ) | |||||
| # return | |||||
| # | # | ||||
| # return | |||||
| # disabled for now, waiting for the new pdf generator | |||||
| # | # | ||||
| # assert result.is_successful() | # assert result.is_successful() | ||||
| # assert ( | # assert ( | ||||