Add support for environment variables for the observer's position and timezonetags/v0.7.0
@@ -8,3 +8,6 @@ indent_style = space | |||||
insert_final_newline = true | insert_final_newline = true | ||||
max_line_length = 120 | max_line_length = 120 | ||||
trim_trailing_whitespace = true | trim_trailing_whitespace = true | ||||
[*.md] | |||||
trim_trailing_whitespace = false |
@@ -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 --timezone=-1" | ||||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=json" | 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" | 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 | # Missing dependencies, should fail | ||||
assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf" | assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf" | ||||
@@ -16,6 +16,8 @@ | |||||
# You should have received a copy of the GNU Affero General Public License | # You should have received a copy of the GNU Affero General Public License | ||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. | # along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||
import os | |||||
import re | |||||
from shutil import rmtree | from shutil import rmtree | ||||
from pathlib import Path | from pathlib import Path | ||||
@@ -25,6 +27,33 @@ from skyfield.nutationlib import iau2000b | |||||
CACHE_FOLDER = str(Path.home()) + '/.kosmorro-cache' | 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(): | def get_loader(): | ||||
return Loader(CACHE_FOLDER) | return Loader(CACHE_FOLDER) | ||||
@@ -8,7 +8,7 @@ msgid "" | |||||
msgstr "" | msgstr "" | ||||
"Project-Id-Version: kosmorro 0.6.2\n" | "Project-Id-Version: kosmorro 0.6.2\n" | ||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\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" | "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" | ||||
@@ -185,95 +185,101 @@ msgid "" | |||||
"information." | "information." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:55 | |||||
#: kosmorrolib/main.py:58 | |||||
msgid "" | msgid "" | ||||
"Save the planet and paper!\n" | "Save the planet and paper!\n" | ||||
"Consider printing you PDF document only if really necessary, and use the " | "Consider printing you PDF document only if really necessary, and use the " | ||||
"other side of the sheet." | "other side of the sheet." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:59 | |||||
#: kosmorrolib/main.py:62 | |||||
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 coordinate." | "the observation coordinate." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:81 | |||||
#: kosmorrolib/main.py:91 | |||||
msgid "Could not save the output in \"{path}\": {error}" | msgid "Could not save the output in \"{path}\": {error}" | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:86 | |||||
#: kosmorrolib/main.py:96 | |||||
msgid "Selected output format needs an output file (--output)." | msgid "Selected output format needs an output file (--output)." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:94 | |||||
#: kosmorrolib/main.py:104 | |||||
msgid "The date {date} does not match the required YYYY-MM-DD format." | msgid "The date {date} does not match the required YYYY-MM-DD format." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:99 | |||||
#: kosmorrolib/main.py:109 | |||||
msgid "The date {date} is not valid: {error}" | msgid "The date {date} is not valid: {error}" | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:113 | |||||
#: kosmorrolib/main.py:123 | |||||
msgid "Running on Python {python_version}" | msgid "Running on Python {python_version}" | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:119 | |||||
#: kosmorrolib/main.py:129 | |||||
msgid "Do you really want to clear Kosmorro's cache? [yN] " | msgid "Do you really want to clear Kosmorro's cache? [yN] " | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:126 | |||||
#: kosmorrolib/main.py:136 | |||||
msgid "Answer did not match expected options, cache not cleared." | msgid "Answer did not match expected options, cache not cleared." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:135 | |||||
#: kosmorrolib/main.py:145 | |||||
msgid "" | msgid "" | ||||
"Compute the ephemerides and the events for a given date, at a given " | "Compute the ephemerides and the events for a given date, at a given " | ||||
"position on Earth." | "position on Earth." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:137 | |||||
#: kosmorrolib/main.py:147 | |||||
msgid "" | msgid "" | ||||
"By default, only the events will be computed for today ({date}).\n" | "By default, only the events will be computed for today ({date}).\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 "" | ||||
#: kosmorrolib/main.py:142 | |||||
#: kosmorrolib/main.py:152 | |||||
msgid "Show the program version" | msgid "Show the program version" | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:144 | |||||
#: kosmorrolib/main.py:154 | |||||
msgid "Delete all the files Kosmorro stored in the cache." | msgid "Delete all the files Kosmorro stored in the cache." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:146 | |||||
#: kosmorrolib/main.py:156 | |||||
msgid "The format under which the information have to be output" | msgid "The format under which the information have to be output" | ||||
msgstr "" | 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 "" | 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 "" | msgstr "" | ||||
#: kosmorrolib/main.py:152 | |||||
#: kosmorrolib/main.py:164 | |||||
msgid "" | msgid "" | ||||
"The date for which the ephemerides must be computed (in the YYYY-MM-DD " | "The date for which the ephemerides must be computed (in the YYYY-MM-DD " | ||||
"format). Defaults to the current date ({default_date})" | "format). Defaults to the current date ({default_date})" | ||||
msgstr "" | 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 "" | msgstr "" | ||||
#: kosmorrolib/main.py:158 | |||||
#: kosmorrolib/main.py:171 | |||||
msgid "Disable the colors in the console." | msgid "Disable the colors in the console." | ||||
msgstr "" | msgstr "" | ||||
#: kosmorrolib/main.py:160 | |||||
#: kosmorrolib/main.py:173 | |||||
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." | ||||
@@ -34,6 +34,7 @@ from .exceptions import UnavailableFeatureError | |||||
def main(): | def main(): | ||||
environment = core.get_env() | |||||
output_formats = get_dumpers() | output_formats = get_dumpers() | ||||
args = get_args(list(output_formats.keys())) | args = get_args(list(output_formats.keys())) | ||||
@@ -46,10 +47,12 @@ def main(): | |||||
print(colored(error.args[0], color='red', attrs=['bold'])) | print(colored(error.args[0], color='red', attrs=['bold'])) | ||||
return -1 | 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) | 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': | if args.format == 'pdf': | ||||
print(_('Save the planet and paper!\n' | print(_('Save the planet and paper!\n' | ||||
@@ -65,8 +68,15 @@ def main(): | |||||
events_list = events.search_events(compute_date) | 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, | selected_dumper = output_formats[args.format](ephemerides, events_list, | ||||
date=compute_date, timezone=args.timezone, | |||||
date=compute_date, timezone=timezone, | |||||
with_colors=args.colors) | with_colors=args.colors) | ||||
output = selected_dumper.to_string() | output = selected_dumper.to_string() | ||||
except UnavailableFeatureError as error: | 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, | 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')) | help=_('The format under which the information have to be output')) | ||||
parser.add_argument('--latitude', '-lat', type=float, default=None, | 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, | 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'), | 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). ' | help=_('The date for which the ephemerides must be computed (in the YYYY-MM-DD format). ' | ||||
'Defaults to the current date ({default_date})').format( | 'Defaults to the current date ({default_date})').format( | ||||
default_date=today.strftime('%Y-%m-%d'))) | 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', | parser.add_argument('--no-colors', dest='colors', action='store_false', | ||||
help=_('Disable the colors in the console.')) | help=_('Disable the colors in the console.')) | ||||
parser.add_argument('--output', '-o', type=str, default=None, | parser.add_argument('--output', '-o', type=str, default=None, | ||||
@@ -31,12 +31,29 @@ | |||||
`--no-colors` | `--no-colors` | ||||
disable the colors in the console | 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 | a file to export the output to; if not given, the standard output is used | ||||
`--format=`_FORMAT_, `-f` _FORMAT_ | `--format=`_FORMAT_, `-f` _FORMAT_ | ||||
the format under which the information have to be output; one of the following: text, json, pdf | 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 | ## EXAMPLES | ||||
Compute the events only for the current date: | Compute the events only for the current date: | ||||
@@ -1,5 +1,6 @@ | |||||
import unittest | import unittest | ||||
import os | |||||
import kosmorrolib.core as core | import kosmorrolib.core as core | ||||
@@ -7,6 +8,25 @@ class CoreTestCase(unittest.TestCase): | |||||
def test_flatten_list(self): | 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]])) | 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__': | if __name__ == '__main__': | ||||
unittest.main() | unittest.main() |