BREAKING CHANGE: the --day, --month and --year arguments have been removed in the favor of a single one.tags/v0.7.0
@@ -77,20 +77,24 @@ assertSuccess "$PYTHON_BIN setup.py sdist" | |||
assertSuccess "$PIP_BIN install dist/kosmorro-$VERSION.tar.gz" "CI" | |||
assertSuccess kosmorro | |||
assertSuccess "kosmorro -h" | |||
assertSuccess "kosmorro -d 2020-01-27" | |||
assertFailure "kosmorro -d yolo-yo-lo" | |||
assertFailure "kosmorro -d 2020-13-32" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020 --timezone=1" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020 --timezone=-1" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020 --format=json" | |||
assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020 --format=pdf" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27" | |||
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" | |||
assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf" | |||
# Missing dependencies, should fail | |||
assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020 --format=pdf -o /tmp/document.pdf" | |||
assertFailure "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf" | |||
assertSuccess "sudo apt-get install -y texlive" "CI" | |||
assertSuccess "$PIP_BIN install latex" "CI" | |||
# Dependencies installed, should not fail | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 27 -m 1 -y 2020 --format=pdf -o /tmp/document.pdf" | |||
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf" | |||
# man page | |||
assertSuccess "man --pager=cat kosmorro" | |||
@@ -47,7 +47,7 @@ class EphemeridesComputer: | |||
return {'rise': sunrise, 'set': sunset} | |||
@staticmethod | |||
def get_moon_phase(year, month, day) -> MoonPhase: | |||
def get_moon_phase(compute_date: datetime.date) -> MoonPhase: | |||
earth = get_skf_objects()['earth'] | |||
moon = get_skf_objects()['moon'] | |||
sun = get_skf_objects()['sun'] | |||
@@ -61,9 +61,9 @@ class EphemeridesComputer: | |||
moon_phase_at.rough_period = 7.0 # one lunar phase per week | |||
today = get_timescale().utc(year, month, day) | |||
time1 = get_timescale().utc(year, month, day - 10) | |||
time2 = get_timescale().utc(year, month, day + 10) | |||
today = get_timescale().utc(compute_date.year, compute_date.month, compute_date.day) | |||
time1 = get_timescale().utc(compute_date.year, compute_date.month, compute_date.day - 10) | |||
time2 = get_timescale().utc(compute_date.year, compute_date.month, compute_date.day + 10) | |||
times, phase = find_discrete(time1, time2, moon_phase_at) | |||
@@ -116,9 +116,9 @@ class EphemeridesComputer: | |||
def is_leap_year(year: int) -> bool: | |||
return (year % 4 == 0 and year % 100 > 0) or (year % 400 == 0) | |||
def compute_ephemerides_for_day(self, year: int, month: int, day: int) -> dict: | |||
return {'moon_phase': self.get_moon_phase(year, month, day), | |||
'details': [self.get_asters_ephemerides_for_aster(aster, datetime.date(year, month, day), self.position) | |||
def compute_ephemerides_for_day(self, compute_date: datetime.date) -> dict: | |||
return {'moon_phase': self.get_moon_phase(compute_date), | |||
'details': [self.get_asters_ephemerides_for_aster(aster, compute_date, self.position) | |||
for aster in ASTERS] if self.position is not None else []} | |||
def compute_ephemerides_for_month(self, year: int, month: int) -> [dict]: | |||
@@ -167,11 +167,5 @@ class EphemeridesComputer: | |||
return seasons | |||
def compute_ephemerides(self, year: int, month: int, day: int): | |||
if day is not None: | |||
return self.compute_ephemerides_for_day(year, month, day) | |||
if month is not None: | |||
return self.compute_ephemerides_for_month(year, month) | |||
return self.compute_ephemerides_for_year(year) | |||
def compute_ephemerides(self, compute_date: datetime.date): | |||
return self.compute_ephemerides_for_day(compute_date) |
@@ -8,7 +8,7 @@ msgid "" | |||
msgstr "" | |||
"Project-Id-Version: kosmorro 0.6.0\n" | |||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" | |||
"POT-Creation-Date: 2020-03-01 14:20+0100\n" | |||
"POT-Creation-Date: 2020-03-04 08:05+0100\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" | |||
@@ -185,100 +185,95 @@ msgid "" | |||
"information." | |||
msgstr "" | |||
#: kosmorrolib/main.py:58 | |||
#: kosmorrolib/main.py:55 | |||
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:62 | |||
#: kosmorrolib/main.py:59 | |||
msgid "" | |||
"PDF output will not contain the ephemerides, because you didn't provide " | |||
"the observation coordinate." | |||
msgstr "" | |||
#: kosmorrolib/main.py:84 | |||
#: kosmorrolib/main.py:81 | |||
msgid "Could not save the output in \"{path}\": {error}" | |||
msgstr "" | |||
#: kosmorrolib/main.py:89 | |||
#: kosmorrolib/main.py:86 | |||
msgid "Selected output format needs an output file (--output)." | |||
msgstr "" | |||
#: kosmorrolib/main.py:106 | |||
#: kosmorrolib/main.py:94 | |||
msgid "The date {date} does not match the required YYYY-MM-DD format." | |||
msgstr "" | |||
#: kosmorrolib/main.py:99 | |||
msgid "The date {date} is not valid: {error}" | |||
msgstr "" | |||
#: kosmorrolib/main.py:113 | |||
msgid "Running on Python {python_version}" | |||
msgstr "" | |||
#: kosmorrolib/main.py:112 | |||
#: kosmorrolib/main.py:119 | |||
msgid "Do you really want to clear Kosmorro's cache? [yN] " | |||
msgstr "" | |||
#: kosmorrolib/main.py:119 | |||
#: kosmorrolib/main.py:126 | |||
msgid "Answer did not match expected options, cache not cleared." | |||
msgstr "" | |||
#: kosmorrolib/main.py:128 | |||
#: kosmorrolib/main.py:135 | |||
msgid "" | |||
"Compute the ephemerides and the events for a given date, at a given " | |||
"position on Earth." | |||
msgstr "" | |||
#: kosmorrolib/main.py:130 | |||
#: kosmorrolib/main.py:137 | |||
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:135 | |||
#: kosmorrolib/main.py:142 | |||
msgid "Show the program version" | |||
msgstr "" | |||
#: kosmorrolib/main.py:137 | |||
#: kosmorrolib/main.py:144 | |||
msgid "Delete all the files Kosmorro stored in the cache." | |||
msgstr "" | |||
#: kosmorrolib/main.py:139 | |||
#: kosmorrolib/main.py:146 | |||
msgid "The format under which the information have to be output" | |||
msgstr "" | |||
#: kosmorrolib/main.py:141 | |||
#: kosmorrolib/main.py:148 | |||
msgid "The observer's latitude on Earth" | |||
msgstr "" | |||
#: kosmorrolib/main.py:143 | |||
#: kosmorrolib/main.py:150 | |||
msgid "The observer's longitude on Earth" | |||
msgstr "" | |||
#: kosmorrolib/main.py:145 | |||
msgid "" | |||
"A number between 1 and 28, 29, 30 or 31 (depending on the month). The day" | |||
" you want to compute the ephemerides for. Defaults to {default_day} (the" | |||
" current day)." | |||
msgstr "" | |||
#: kosmorrolib/main.py:149 | |||
msgid "" | |||
"A number between 1 and 12. The month you want to compute the ephemerides " | |||
"for. Defaults to {default_month} (the current month)." | |||
msgstr "" | |||
#: kosmorrolib/main.py:152 | |||
msgid "" | |||
"The year you want to compute the ephemerides for. Defaults to " | |||
"{default_year} (the current year)." | |||
"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:155 | |||
#: kosmorrolib/main.py:156 | |||
msgid "The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3)." | |||
msgstr "" | |||
#: kosmorrolib/main.py:157 | |||
#: kosmorrolib/main.py:158 | |||
msgid "Disable the colors in the console." | |||
msgstr "" | |||
#: kosmorrolib/main.py:159 | |||
#: kosmorrolib/main.py:160 | |||
msgid "" | |||
"A file to export the output to. If not given, the standard output is " | |||
"used. This argument is needed for PDF format." | |||
@@ -40,14 +40,11 @@ def main(): | |||
if args.special_action is not None: | |||
return 0 if args.special_action() else 1 | |||
year = args.year | |||
month = args.month | |||
day = args.day | |||
compute_date = date(year, month, day) | |||
if day is not None and month is None: | |||
month = date.today().month | |||
try: | |||
compute_date = get_date(args.date) | |||
except ValueError as error: | |||
print(colored(error.args[0], color='red', attrs=['bold'])) | |||
return -1 | |||
if args.latitude is None or args.longitude is None: | |||
position = None | |||
@@ -64,7 +61,7 @@ def main(): | |||
try: | |||
ephemeris = EphemeridesComputer(position) | |||
ephemerides = ephemeris.compute_ephemerides(year, month, day) | |||
ephemerides = ephemeris.compute_ephemerides(compute_date) | |||
events_list = events.search_events(compute_date) | |||
@@ -92,6 +89,16 @@ def main(): | |||
return 0 | |||
def get_date(yyyymmdd: str) -> date: | |||
if not re.match(r'^\d{4}-\d{2}-\d{2}$', yyyymmdd): | |||
raise ValueError(_('The date {date} does not match the required YYYY-MM-DD format.').format(date=yyyymmdd)) | |||
try: | |||
return date.fromisoformat(yyyymmdd) | |||
except ValueError as error: | |||
raise ValueError(_('The date {date} is not valid: {error}').format(date=yyyymmdd, error=error.args[0])) | |||
def get_dumpers() -> {str: dumper.Dumper}: | |||
return { | |||
'text': dumper.TextDumper, | |||
@@ -141,16 +148,10 @@ def get_args(output_formats: [str]): | |||
help=_("The observer's latitude on Earth")) | |||
parser.add_argument('--longitude', '-lon', type=float, default=None, | |||
help=_("The observer's longitude on Earth")) | |||
parser.add_argument('--day', '-d', type=int, default=today.day, | |||
help=_('A number between 1 and 28, 29, 30 or 31 (depending on the month). The day you want to ' | |||
' compute the ephemerides for. Defaults to {default_day} (the current day).').format( | |||
default_day=today.day)) | |||
parser.add_argument('--month', '-m', type=int, default=today.month, | |||
help=_('A number between 1 and 12. The month you want to compute the ephemerides for.' | |||
' Defaults to {default_month} (the current month).').format(default_month=today.month)) | |||
parser.add_argument('--year', '-y', type=int, default=today.year, | |||
help=_('The year you want to compute the ephemerides for.' | |||
' Defaults to {default_year} (the current year).').format(default_year=today.year)) | |||
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('--no-colors', dest='colors', action='store_false', | |||
@@ -22,14 +22,8 @@ | |||
`--longitude=`_LONGITUDE_, `-lon` _LONGITUDE_ | |||
the observer's longitude on Earth | |||
`--day=`_DAY_, `-d` _DAY_ | |||
a number between 1 and 28, 29, 30 or 31 (depending on the month); the day you want to compute the ephemerides for, defaults to the current day | |||
`--month=`_MONTH_, `-m` _MONTH_ | |||
a number between 1 and 12; the month you want to compute the ephemerides for, defaults to the current month | |||
`--year=`_YEAR_, `-y` _YEAR_ | |||
the year you want to compute the ephemerides for; defaults to the current year | |||
`--date=`_DATE_, `-d` _DATE_ | |||
The date for which the ephemerides must be computed (in the YYYY-MM-DD format); 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 | |||
@@ -43,18 +37,24 @@ | |||
`--format=`_FORMAT_, `-f` _FORMAT_ | |||
the format under which the information have to be output; one of the following: text, json, pdf | |||
## EXAMPLE | |||
## EXAMPLES | |||
Compute the events only for the current date: | |||
``` | |||
kosmorro | |||
``` | |||
Compute the ephemerides for Lille, France, on April 1st, 2022: | |||
``` | |||
kosmorro --latitude=50.5876 --longitude=3.0624 -d 1 -m 4 -y 2022 | |||
kosmorro --latitude=50.5876 --longitude=3.0624 --date=2022-04-01 | |||
``` | |||
Compute the ephemerides for Lille, France, on April 1st, 2022, and export them in a PDF document: | |||
``` | |||
kosmorro --latitude=50.5876 --longitude=3.0624 -d 1 -m 4 -y 2022 --format=pdf --output=file.pdf | |||
kosmorro --latitude=50.5876 --longitude=3.0624 -date=2022-04-01 --format=pdf --output=file.pdf | |||
``` | |||
## AUTHOR | |||
@@ -22,61 +22,61 @@ class EphemeridesComputerTestCase(unittest.TestCase): | |||
################################################################################################################### | |||
def test_moon_phase_new_moon(self): | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 25) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 25)) | |||
self.assertEqual('WANING_CRESCENT', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-26T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 26) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 26)) | |||
self.assertEqual('NEW_MOON', phase.identifier) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-12-04T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 27) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 27)) | |||
self.assertEqual('WAXING_CRESCENT', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-12-04T') | |||
def test_moon_phase_first_crescent(self): | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 3) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 3)) | |||
self.assertEqual('WAXING_CRESCENT', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-04T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 4) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 4)) | |||
self.assertEqual('FIRST_QUARTER', phase.identifier) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-12T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 5) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 5)) | |||
self.assertEqual('WAXING_GIBBOUS', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-12T') | |||
def test_moon_phase_full_moon(self): | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 11) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 11)) | |||
self.assertEqual('WAXING_GIBBOUS', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-12T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 12) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 12)) | |||
self.assertEqual('FULL_MOON', phase.identifier) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-19T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 13) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 13)) | |||
self.assertEqual('WANING_GIBBOUS', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-19T') | |||
def test_moon_phase_last_quarter(self): | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 18) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 18)) | |||
self.assertEqual('WANING_GIBBOUS', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-19T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 19) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 19)) | |||
self.assertEqual('LAST_QUARTER', phase.identifier) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-26T') | |||
phase = EphemeridesComputer.get_moon_phase(2019, 11, 20) | |||
phase = EphemeridesComputer.get_moon_phase(date(2019, 11, 20)) | |||
self.assertEqual('WANING_CRESCENT', phase.identifier) | |||
self.assertIsNone(phase.time) | |||
self.assertRegexpMatches(phase.next_phase_date.isoformat(), '^2019-11-26T') | |||