| @@ -17,14 +17,18 @@ | |||
| # along with this program. If not, see <https://www.gnu.org/licenses/>. | |||
| import argparse | |||
| import datetime | |||
| import sys | |||
| import os.path | |||
| import pytz | |||
| from babel.dates import format_date | |||
| from kosmorrolib import Position, get_ephemerides, get_events, get_moon_phase | |||
| from kosmorrolib.exceptions import OutOfRangeDateError | |||
| from datetime import date | |||
| from pytz import timezone | |||
| from . import dumper, environment, debug | |||
| from .date import parse_date | |||
| from .geolocation import get_position | |||
| @@ -34,6 +38,7 @@ from .utils import ( | |||
| colored, | |||
| set_colors_activated, | |||
| print_stderr, | |||
| get_timezone, | |||
| ) | |||
| from .exceptions import ( | |||
| InvalidOutputFormatError, | |||
| @@ -88,12 +93,31 @@ def run(): | |||
| ) | |||
| ) | |||
| timezone = args.timezone | |||
| timezone = 0 | |||
| if timezone is None and env_vars.timezone is not None: | |||
| timezone = int(env_vars.timezone) | |||
| elif timezone is None: | |||
| timezone = 0 | |||
| try: | |||
| if args.timezone is not None: | |||
| timezone = get_timezone(args.timezone) | |||
| elif env_vars.tz is not None: | |||
| timezone = get_timezone(env_vars.tz) | |||
| elif env_vars.timezone is not None: | |||
| print_stderr( | |||
| colored( | |||
| _( | |||
| "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard." | |||
| ), | |||
| "yellow", | |||
| ) | |||
| ) | |||
| timezone = get_timezone(env_vars.timezone) | |||
| except pytz.UnknownTimeZoneError as error: | |||
| print_stderr( | |||
| colored( | |||
| _("Unknown timezone: {timezone}").format(timezone=error.args[0]), | |||
| color="red", | |||
| ) | |||
| ) | |||
| return -1 | |||
| try: | |||
| use_colors = not environment.NO_COLOR and args.colors | |||
| @@ -290,11 +314,12 @@ def get_args(output_formats: [str]): | |||
| parser.add_argument( | |||
| "--timezone", | |||
| "-t", | |||
| type=int, | |||
| type=str, | |||
| default=None, | |||
| help=_( | |||
| "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." | |||
| "The timezone to use to display the hours. It can be either a number (e.g. 1 for UTC+1) or a timezone name (e.g. Europe/Paris). " | |||
| "See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones to find your timezone. " | |||
| "Can also be set in the TZ environment variable." | |||
| ), | |||
| ) | |||
| parser.add_argument( | |||
| @@ -44,6 +44,8 @@ class Environment: | |||
| def get_env_vars() -> Environment: | |||
| environment = Environment() | |||
| environment.tz = os.getenv("TZ") | |||
| for var in os.environ: | |||
| if not re.search("^KOSMORRO_", var): | |||
| continue | |||
| @@ -8,7 +8,7 @@ msgid "" | |||
| msgstr "" | |||
| "Project-Id-Version: PROJECT VERSION\n" | |||
| "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" | |||
| "POT-Creation-Date: 2025-04-21 15:35+0200\n" | |||
| "POT-Creation-Date: 2025-09-22 17:24+0200\n" | |||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |||
| "Language-Team: LANGUAGE <LL@li.org>\n" | |||
| @@ -17,89 +17,102 @@ msgstr "" | |||
| "Content-Transfer-Encoding: 8bit\n" | |||
| "Generated-By: Babel 2.17.0\n" | |||
| #: kosmorro/__main__.py:84 | |||
| #: kosmorro/__main__.py:89 | |||
| msgid "" | |||
| "Output file will not contain the ephemerides, because you didn't provide " | |||
| "the observation coordinates." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:135 | |||
| #: kosmorro/__main__.py:107 | |||
| msgid "" | |||
| "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, " | |||
| "which is more standard." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:116 | |||
| #, python-brace-format | |||
| msgid "Unknown timezone: {timezone}" | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:159 | |||
| #, python-brace-format | |||
| msgid "The file could not be saved in \"{path}\": {error}" | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:149 | |||
| #: kosmorro/__main__.py:173 | |||
| msgid "Please provide a file path to export in this format (--output)." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:181 | |||
| #: kosmorro/__main__.py:205 | |||
| #, python-brace-format | |||
| msgid "Moon phase can only be computed between {min_date} and {max_date}" | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:228 | |||
| #: kosmorro/__main__.py:252 | |||
| #, python-brace-format | |||
| msgid "Running on Python {python_version} with Kosmorrolib v{kosmorrolib_version}" | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:241 | |||
| #: kosmorro/__main__.py:265 | |||
| msgid "" | |||
| "Compute the ephemerides and the events for a given date and a given " | |||
| "position on Earth." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:244 | |||
| #: kosmorro/__main__.py:268 | |||
| msgid "" | |||
| "By default, only the events will be computed for today.\n" | |||
| "To compute also the ephemerides, latitude and longitude arguments are " | |||
| "needed." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:256 | |||
| #: kosmorro/__main__.py:280 | |||
| msgid "Show the program version" | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:265 | |||
| #: kosmorro/__main__.py:289 | |||
| msgid "" | |||
| "The format to output the information to. If not provided, the output " | |||
| "format will be inferred from the file extension of the output file." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:275 | |||
| #: kosmorro/__main__.py:299 | |||
| #, python-brace-format | |||
| msgid "" | |||
| "The observer's position on Earth, in the \"{latitude},{longitude}\" " | |||
| "format. Can also be set in the KOSMORRO_POSITION environment variable." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:285 | |||
| #: kosmorro/__main__.py:309 | |||
| msgid "" | |||
| "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," | |||
| " and D numbers). Defaults to current date." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:296 | |||
| #: kosmorro/__main__.py:320 | |||
| msgid "" | |||
| "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." | |||
| "The timezone to use to display the hours. It can be either a number (e.g." | |||
| " 1 for UTC+1) or a timezone name (e.g. Europe/Paris). See " | |||
| "https://en.wikipedia.org/wiki/List_of_tz_database_time_zones to find your" | |||
| " timezone. Can also be set in the TZ environment variable." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:304 | |||
| #: kosmorro/__main__.py:329 | |||
| msgid "Disable the colors in the console." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:312 | |||
| #: kosmorro/__main__.py:337 | |||
| msgid "A file to export the output to. If not given, the standard output is used." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:320 | |||
| #: kosmorro/__main__.py:345 | |||
| msgid "" | |||
| "Do not generate a graph to represent the rise and set times in the LaTeX " | |||
| "file." | |||
| msgstr "" | |||
| #: kosmorro/__main__.py:327 | |||
| #: kosmorro/__main__.py:352 | |||
| msgid "Show debugging messages" | |||
| msgstr "" | |||
| @@ -1,5 +1,7 @@ | |||
| #!/usr/bin/env python3 | |||
| from datetime import datetime | |||
| import pytz | |||
| from termcolor import colored as do_color | |||
| from sys import stderr | |||
| @@ -27,3 +29,12 @@ def colored(text, color=None, on_color=None, attrs=None): | |||
| def print_stderr(*values: object): | |||
| print(*values, file=stderr) | |||
| def get_timezone(value: int | str) -> float: | |||
| try: | |||
| timezone = float(value) | |||
| except ValueError: | |||
| timezone = pytz.timezone(value).utcoffset(datetime.now()).total_seconds() / 3600 | |||
| return timezone | |||
| @@ -23,7 +23,7 @@ | |||
| The date for which the ephemerides must be computed, either in the YYYY-MM-DD format or as an interval in the "[+-]YyMmDd" format (with Y, M, and D numbers); defaults to the current date | |||
| `--timezone=`_TIMEZONE_, `-t` _TIMEZONE_ | |||
| the timezone to display the hours in; e.g. 2 for UTC+2 or -3 for UTC-3 | |||
| the timezone to use to display the hours; it can be either a number (e.g. 1 for UTC+1) or a timezone name (e.g. Europe/Paris) | |||
| `--no-colors` | |||
| disable the colors in the console | |||
| @@ -391,6 +391,18 @@ files = [ | |||
| [package.dependencies] | |||
| six = ">=1.5" | |||
| [[package]] | |||
| name = "pytz" | |||
| version = "2025.2" | |||
| description = "World timezone definitions, modern and historical" | |||
| optional = false | |||
| python-versions = "*" | |||
| groups = ["main"] | |||
| files = [ | |||
| {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, | |||
| {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, | |||
| ] | |||
| [[package]] | |||
| name = "sgp4" | |||
| version = "2.25" | |||
| @@ -529,4 +541,4 @@ tests = ["pytest", "pytest-cov"] | |||
| [metadata] | |||
| lock-version = "2.1" | |||
| python-versions = "^3.12" | |||
| content-hash = "edfb347df82f9895ce51f3af9005b1d924129c24aa7e38b5e2f7bd858e33ec25" | |||
| content-hash = "12bf9cdda9cfaf9616bf3d899450e105991f788267601a41a79fed1b5cbd73a9" | |||
| @@ -22,6 +22,7 @@ kosmorrolib = "^1.0" | |||
| python-dateutil = "^2.8" | |||
| Babel = "^2.9" | |||
| openlocationcode = "^1.0" | |||
| pytz = "^2025.2" | |||
| [tool.poetry.group.dev.dependencies] | |||
| black = "^24.4" | |||
| @@ -62,9 +62,11 @@ options: | |||
| "[+-]YyMmDd" format (with Y, M, and D numbers). | |||
| Defaults to current date. | |||
| --timezone TIMEZONE, -t TIMEZONE | |||
| 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. | |||
| The timezone to use to display the hours. It can be | |||
| either a number (e.g. 1 for UTC+1) or a timezone name | |||
| (e.g. Europe/Paris). See https://en.wikipedia.org/wiki | |||
| /List_of_tz_database_time_zones to find your timezone. | |||
| Can also be set in the TZ environment variable. | |||
| --no-colors Disable the colors in the console. | |||
| --output OUTPUT, -o OUTPUT | |||
| A file to export the output to. If not given, the | |||
| @@ -103,9 +105,11 @@ options: | |||
| "[+-]YyMmDd" format (with Y, M, and D numbers). | |||
| Defaults to current date. | |||
| --timezone, -t TIMEZONE | |||
| 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. | |||
| The timezone to use to display the hours. It can be | |||
| either a number (e.g. 1 for UTC+1) or a timezone name | |||
| (e.g. Europe/Paris). See https://en.wikipedia.org/wiki | |||
| /List_of_tz_database_time_zones to find your timezone. | |||
| Can also be set in the TZ environment variable. | |||
| --no-colors Disable the colors in the console. | |||
| --output, -o OUTPUT A file to export the output to. If not given, the | |||
| standard output is used. | |||
| @@ -6,68 +6,88 @@ from .utils import ( | |||
| ) | |||
| def check_command_return_t_plus_one(result): | |||
| def test_timezone_with_command_line_arg(): | |||
| result = execute(KOSMORRO + ["--timezone=1", "-d2020-01-27"]) | |||
| assert result.successful | |||
| assert ( | |||
| result.stdout | |||
| == """Monday, January 27, 2020 | |||
| assert "Note: All the hours are given in the UTC+1.0 timezone." in result.stdout | |||
| New Moon | |||
| First Quarter on Sunday, February 2, 2020 at 2:41 AM | |||
| result = execute(KOSMORRO + ["--timezone=Europe/Paris", "-d2020-01-27"]) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC+1.0 timezone." not in result.stdout | |||
| Expected events: | |||
| 9:00 PM Venus and Neptune are in conjunction | |||
| result = execute(KOSMORRO + ["--timezone=-5", "-d2020-01-27"]) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout | |||
| Note: All the hours are given in the UTC+1 timezone. | |||
| """ | |||
| ) | |||
| result = execute(KOSMORRO + ["--timezone=America/Chicago", "-d2020-01-27"]) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout | |||
| def check_command_return_t_minus_one(result): | |||
| def test_timezone_with_env_var(): | |||
| result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "1"}) | |||
| assert result.successful | |||
| assert ( | |||
| result.stdout | |||
| == """Monday, January 27, 2020 | |||
| assert "Note: All the hours are given in the UTC+1.0 timezone." in result.stdout | |||
| New Moon | |||
| First Quarter on Sunday, February 2, 2020 at 12:41 AM | |||
| result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "Europe/Paris"}) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC+1.0 timezone." not in result.stdout | |||
| result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "-5"}) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout | |||
| result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "America/Chicago"}) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout | |||
| Expected events: | |||
| 7:00 PM Venus and Neptune are in conjunction | |||
| Note: All the hours are given in the UTC-1 timezone. | |||
| """ | |||
| def test_timezone_with_env_var_and_command_line_arg(): | |||
| result = execute( | |||
| KOSMORRO + ["--timezone=3", "-d2020-01-27"], environment={"TZ": "Europe/Paris"} | |||
| ) | |||
| assert result.successful | |||
| assert "Note: All the hours are given in the UTC+3.0 timezone." in result.stdout | |||
| def test_timezone(): | |||
| check_command_return_t_plus_one( | |||
| execute(KOSMORRO + ["--timezone=1", "-d2020-01-27"]) | |||
| def test_timezone_with_deprecated_env_var(): | |||
| result = execute( | |||
| KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "1"} | |||
| ) | |||
| check_command_return_t_minus_one( | |||
| execute(KOSMORRO + ["--timezone=-1", "-d2020-01-27"]) | |||
| assert result.successful | |||
| assert ( | |||
| "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard." | |||
| in result.stderr | |||
| ) | |||
| assert "Note: All the hours are given in the UTC+1.0 timezone." in result.stdout | |||
| def test_timezone_with_env_var(): | |||
| check_command_return_t_plus_one( | |||
| execute(KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "1"}) | |||
| result = execute( | |||
| KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "Europe/Paris"} | |||
| ) | |||
| check_command_return_t_minus_one( | |||
| execute(KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "-1"}) | |||
| assert result.successful | |||
| assert ( | |||
| "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard." | |||
| in result.stderr | |||
| ) | |||
| assert "Note: All the hours are given in the UTC+1.0 timezone." not in result.stdout | |||
| # If both environment variable and argument are set, use argument: | |||
| result = execute( | |||
| KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "-5"} | |||
| ) | |||
| assert result.successful | |||
| assert ( | |||
| "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard." | |||
| in result.stderr | |||
| ) | |||
| assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout | |||
| check_command_return_t_plus_one( | |||
| execute( | |||
| KOSMORRO + ["--timezone=1", "-d2020-01-27"], | |||
| environment={"KOSMORRO_TIMEZONE": "-1"}, | |||
| ) | |||
| result = execute( | |||
| KOSMORRO + ["-d2020-01-27"], | |||
| environment={"KOSMORRO_TIMEZONE": "America/Chicago"}, | |||
| ) | |||
| check_command_return_t_minus_one( | |||
| execute( | |||
| KOSMORRO + ["--timezone=-1", "-d2020-01-27"], | |||
| environment={"KOSMORRO_TIMEZONE": "1"}, | |||
| ) | |||
| assert result.successful | |||
| assert ( | |||
| "Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard." | |||
| in result.stderr | |||
| ) | |||
| assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout | |||