From 5dec0dcc4cb3483ee4962a4ae7e86135e4bded06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Deuchnord?= Date: Tue, 24 Mar 2020 13:29:07 +0100 Subject: [PATCH] feat: add support for environment variables The observer's position and timezone can now be set using the following environment variables: - `KOSMORRO_LATITUDE`: the observer's latitude - `KOSMORRO_LONGITUDE`: the observer's longitude - `KOSMORRO_TIMEZONE`: the observer's timezone --- .editorconfig | 3 ++ .scripts/tests-e2e.sh | 5 +++ kosmorrolib/core.py | 29 +++++++++++++++++ kosmorrolib/locales/messages.pot | 54 ++++++++++++++++++-------------- kosmorrolib/main.py | 29 ++++++++++++----- manpage/kosmorro.1.md | 19 ++++++++++- test/core.py | 20 ++++++++++++ 7 files changed, 126 insertions(+), 33 deletions(-) diff --git a/.editorconfig b/.editorconfig index 13a634c..b7c833b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,3 +8,6 @@ indent_style = space insert_final_newline = true max_line_length = 120 trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.scripts/tests-e2e.sh b/.scripts/tests-e2e.sh index 3c59ef2..a4c83a6 100644 --- a/.scripts/tests-e2e.sh +++ b/.scripts/tests-e2e.sh @@ -87,6 +87,11 @@ assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --ti assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --timezone=-1" assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=json" assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf" + +# Environment variables +assertSuccess "LATITUDE=50.5876 LONGITUDE=3.0624 TIMEZONE=1 kosmorro -d 2020-01-27" +assertSuccess "LATITUDE=50.5876 LONGITUDE=3.0624 TIMEZONE=-1 kosmorro -d 2020-01-27" + # Missing dependencies, should fail assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf" diff --git a/kosmorrolib/core.py b/kosmorrolib/core.py index 81cec74..f727ca4 100644 --- a/kosmorrolib/core.py +++ b/kosmorrolib/core.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import os +import re from shutil import rmtree from pathlib import Path @@ -25,6 +27,33 @@ from skyfield.nutationlib import iau2000b CACHE_FOLDER = str(Path.home()) + '/.kosmorro-cache' +class Environment: + def __init__(self): + self._vars = {} + + def __set__(self, key, value): + self._vars[key] = value + + def __getattr__(self, key): + return self._vars[key] if key in self._vars else None + + def __str__(self): + return self._vars.__str__() + + def __len__(self): + return len(self._vars) + +def get_env() -> Environment: + environment = Environment() + + for var in os.environ: + if not re.search('^KOSMORRO_', var): + continue + + [_, env] = var.split('_', 1) + environment.__set__(env.lower(), os.getenv(var)) + + return environment def get_loader(): return Loader(CACHE_FOLDER) diff --git a/kosmorrolib/locales/messages.pot b/kosmorrolib/locales/messages.pot index 37ee33a..ebd3403 100644 --- a/kosmorrolib/locales/messages.pot +++ b/kosmorrolib/locales/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: kosmorro 0.6.2\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2020-03-19 20:13+0100\n" +"POT-Creation-Date: 2020-03-24 13:44+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -185,95 +185,101 @@ msgid "" "information." msgstr "" -#: kosmorrolib/main.py:55 +#: kosmorrolib/main.py:58 msgid "" "Save the planet and paper!\n" "Consider printing you PDF document only if really necessary, and use the " "other side of the sheet." msgstr "" -#: kosmorrolib/main.py:59 +#: kosmorrolib/main.py:62 msgid "" "PDF output will not contain the ephemerides, because you didn't provide " "the observation coordinate." msgstr "" -#: kosmorrolib/main.py:81 +#: kosmorrolib/main.py:91 msgid "Could not save the output in \"{path}\": {error}" msgstr "" -#: kosmorrolib/main.py:86 +#: kosmorrolib/main.py:96 msgid "Selected output format needs an output file (--output)." msgstr "" -#: kosmorrolib/main.py:94 +#: kosmorrolib/main.py:104 msgid "The date {date} does not match the required YYYY-MM-DD format." msgstr "" -#: kosmorrolib/main.py:99 +#: kosmorrolib/main.py:109 msgid "The date {date} is not valid: {error}" msgstr "" -#: kosmorrolib/main.py:113 +#: kosmorrolib/main.py:123 msgid "Running on Python {python_version}" msgstr "" -#: kosmorrolib/main.py:119 +#: kosmorrolib/main.py:129 msgid "Do you really want to clear Kosmorro's cache? [yN] " msgstr "" -#: kosmorrolib/main.py:126 +#: kosmorrolib/main.py:136 msgid "Answer did not match expected options, cache not cleared." msgstr "" -#: kosmorrolib/main.py:135 +#: kosmorrolib/main.py:145 msgid "" "Compute the ephemerides and the events for a given date, at a given " "position on Earth." msgstr "" -#: kosmorrolib/main.py:137 +#: kosmorrolib/main.py:147 msgid "" "By default, only the events will be computed for today ({date}).\n" "To compute also the ephemerides, latitude and longitude arguments are " "needed." msgstr "" -#: kosmorrolib/main.py:142 +#: kosmorrolib/main.py:152 msgid "Show the program version" msgstr "" -#: kosmorrolib/main.py:144 +#: kosmorrolib/main.py:154 msgid "Delete all the files Kosmorro stored in the cache." msgstr "" -#: kosmorrolib/main.py:146 +#: kosmorrolib/main.py:156 msgid "The format under which the information have to be output" msgstr "" -#: kosmorrolib/main.py:148 -msgid "The observer's latitude on Earth" +#: kosmorrolib/main.py:158 +msgid "" +"The observer's latitude on Earth. Can also be set in the " +"KOSMORRO_LATITUDE environment variable." msgstr "" -#: kosmorrolib/main.py:150 -msgid "The observer's longitude on Earth" +#: kosmorrolib/main.py:161 +msgid "" +"The observer's longitude on Earth. Can also be set in the " +"KOSMORRO_LONGITUDE environment variable." msgstr "" -#: kosmorrolib/main.py:152 +#: kosmorrolib/main.py:164 msgid "" "The date for which the ephemerides must be computed (in the YYYY-MM-DD " "format). Defaults to the current date ({default_date})" msgstr "" -#: kosmorrolib/main.py:156 -msgid "The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3)." +#: kosmorrolib/main.py:168 +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." msgstr "" -#: kosmorrolib/main.py:158 +#: kosmorrolib/main.py:171 msgid "Disable the colors in the console." msgstr "" -#: kosmorrolib/main.py:160 +#: kosmorrolib/main.py:173 msgid "" "A file to export the output to. If not given, the standard output is " "used. This argument is needed for PDF format." diff --git a/kosmorrolib/main.py b/kosmorrolib/main.py index 0b2fb1b..e03dd89 100644 --- a/kosmorrolib/main.py +++ b/kosmorrolib/main.py @@ -34,6 +34,7 @@ from .exceptions import UnavailableFeatureError def main(): + environment = core.get_env() output_formats = get_dumpers() args = get_args(list(output_formats.keys())) @@ -46,10 +47,12 @@ def main(): print(colored(error.args[0], color='red', attrs=['bold'])) return -1 - if args.latitude is None or args.longitude is None: - position = None - else: + position = None + + if args.latitude is not None or args.longitude is not None: position = Position(args.latitude, args.longitude) + elif environment.latitude is not None and environment.longitude is not None: + position = Position(float(environment.latitude), float(environment.longitude)) if args.format == 'pdf': print(_('Save the planet and paper!\n' @@ -65,8 +68,15 @@ def main(): events_list = events.search_events(compute_date) + timezone = args.timezone + + if timezone is None and environment.timezone is not None: + timezone = int(environment.timezone) + elif timezone is None: + timezone = 0 + selected_dumper = output_formats[args.format](ephemerides, events_list, - date=compute_date, timezone=args.timezone, + date=compute_date, timezone=timezone, with_colors=args.colors) output = selected_dumper.to_string() except UnavailableFeatureError as error: @@ -145,15 +155,18 @@ def get_args(output_formats: [str]): parser.add_argument('--format', '-f', type=str, default=output_formats[0], choices=output_formats, help=_('The format under which the information have to be output')) parser.add_argument('--latitude', '-lat', type=float, default=None, - help=_("The observer's latitude on Earth")) + help=_("The observer's latitude on Earth. Can also be set in the KOSMORRO_LATITUDE environment " + "variable.")) parser.add_argument('--longitude', '-lon', type=float, default=None, - help=_("The observer's longitude on Earth")) + help=_("The observer's longitude on Earth. Can also be set in the KOSMORRO_LONGITUDE " + "environment variable.")) parser.add_argument('--date', '-d', type=str, default=today.strftime('%Y-%m-%d'), help=_('The date for which the ephemerides must be computed (in the YYYY-MM-DD format). ' 'Defaults to the current date ({default_date})').format( default_date=today.strftime('%Y-%m-%d'))) - parser.add_argument('--timezone', '-t', type=int, default=0, - help=_('The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3).')) + parser.add_argument('--timezone', '-t', type=int, 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.')) parser.add_argument('--no-colors', dest='colors', action='store_false', help=_('Disable the colors in the console.')) parser.add_argument('--output', '-o', type=str, default=None, diff --git a/manpage/kosmorro.1.md b/manpage/kosmorro.1.md index 3d7a11d..08f4170 100644 --- a/manpage/kosmorro.1.md +++ b/manpage/kosmorro.1.md @@ -31,12 +31,29 @@ `--no-colors` disable the colors in the console -`--output=`_OUTPUT_, `-o` _OUTPUT_ +`--output=`_OUTPUT_, `-o` _OUTPUT_ a file to export the output to; if not given, the standard output is used `--format=`_FORMAT_, `-f` _FORMAT_ the format under which the information have to be output; one of the following: text, json, pdf +## ENVIRONMENT VARIABLES + +The environment variable listed below may be used instead of the options. +The options have a higher priority than the environment variable. +As a consequence, any option that would be given to `kosmorro` will override its corresponding environment variable. + +Available environment variables are: + +`KOSMORRO_LATITUDE` + the observer's latitude on Earth (alternative to `--latitude`) + +`KOSMORRO_LONGITUDE` + the observer's longitude on Earth (alternative to `--longitude`) + +`KOSMORRO_TIMEZONE` + the observer's timezone (alternative to `--timezone`) + ## EXAMPLES Compute the events only for the current date: diff --git a/test/core.py b/test/core.py index aea32f3..2e4c0cf 100644 --- a/test/core.py +++ b/test/core.py @@ -1,5 +1,6 @@ import unittest +import os import kosmorrolib.core as core @@ -7,6 +8,25 @@ class CoreTestCase(unittest.TestCase): def test_flatten_list(self): self.assertEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], core.flatten_list([0, 1, 2, [3, 4, [5, 6], 7], 8, [9]])) + def test_get_env(self): + self.assertEqual(0, len(core.get_env())) + + os.environ['SOME_RANDOM_VAR'] = 'an awesome value' + self.assertEqual(0, len(core.get_env())) + + os.environ['KOSMORRO_GREAT_VARIABLE'] = 'value' + env = core.get_env() + self.assertEqual(1, len(env)) + self.assertEqual('value', env.great_variable) + + os.environ['KOSMORRO_ANOTHER_VARIABLE'] = 'another value' + env = core.get_env() + self.assertEqual(2, len(env)) + self.assertEqual('value', env.great_variable) + self.assertEqual('another value', env.another_variable) + + self.assertEqual("{'great_variable': 'value', 'another_variable': 'another value'}", str(env)) + if __name__ == '__main__': unittest.main()