Просмотр исходного кода

Merge pull request #77 from Brainface1/relative-dates

feat: add support for relative dates on --date argument
tags/v0.8.0
Jérôme Deuchnord 4 лет назад
committed by GitHub
Родитель
Сommit
048a2cdbf8
Не найден GPG ключ соответствующий данной подписи Идентификатор GPG ключа: 4AEE18F83AFDEB23
10 измененных файлов: 116 добавлений и 71 удалений
  1. +4
    -0
      .scripts/tests-e2e.sh
  2. +1
    -0
      Pipfile
  3. +45
    -37
      Pipfile.lock
  4. +0
    -0
      kosmorro
  5. +31
    -0
      kosmorrolib/core.py
  6. +25
    -23
      kosmorrolib/locales/messages.pot
  7. +1
    -9
      kosmorrolib/main.py
  8. +1
    -1
      manpage/kosmorro.1.md
  9. +1
    -1
      setup.py
  10. +7
    -0
      test/core.py

+ 4
- 0
.scripts/tests-e2e.sh Просмотреть файл

@@ -81,6 +81,10 @@ assertSuccess "kosmorro -h"
assertSuccess "kosmorro -d 2020-01-27" assertSuccess "kosmorro -d 2020-01-27"
assertFailure "kosmorro -d yolo-yo-lo" assertFailure "kosmorro -d yolo-yo-lo"
assertFailure "kosmorro -d 2020-13-32" assertFailure "kosmorro -d 2020-13-32"
assertSuccess "kosmorro --date='+3y 5m3d'"
assertSuccess "kosmorro --date='-1y3d'"
assertFailure "kosmorro --date='+3d4m"
assertFailure "kosmorro -date='3y'"
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624" assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624"
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27" 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"


+ 1
- 0
Pipfile Просмотреть файл

@@ -16,6 +16,7 @@ tabulate = "*"
numpy = ">=1.17.0,<2.0.0" numpy = ">=1.17.0,<2.0.0"
termcolor = "*" termcolor = "*"
latex = "*" latex = "*"
python-dateutil = "*"


[requires] [requires]
python_version = "3" python_version = "3"

+ 45
- 37
Pipfile.lock Просмотреть файл

@@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "67748949d467fbdca22ccc963430b21be215566f8a49b56ac734b44023ce5ff2"
"sha256": "4bcfaa3140b0b5c03886cf6877b37a1eb9df4e175f43d3ce0c1312496cde8515"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@@ -82,6 +82,14 @@
"index": "pypi", "index": "pypi",
"version": "==1.18.2" "version": "==1.18.2"
}, },
"python-dateutil": {
"hashes": [
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
],
"index": "pypi",
"version": "==2.8.1"
},
"sgp4": { "sgp4": {
"hashes": [ "hashes": [
"sha256:0e37751cf68d0b9d3417e4bcb1973e52f032b5dc29d57dd264f2e5c330ef9ce4", "sha256:0e37751cf68d0b9d3417e4bcb1973e52f032b5dc29d57dd264f2e5c330ef9ce4",
@@ -177,10 +185,10 @@
}, },
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3",
"sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"
"sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304",
"sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519"
], ],
"version": "==2019.11.28"
"version": "==2020.4.5.1"
}, },
"chardet": { "chardet": {
"hashes": [ "hashes": [
@@ -199,39 +207,39 @@
}, },
"coverage": { "coverage": {
"hashes": [ "hashes": [
"sha256:03f630aba2b9b0d69871c2e8d23a69b7fe94a1e2f5f10df5049c0df99db639a0",
"sha256:046a1a742e66d065d16fb564a26c2a15867f17695e7f3d358d7b1ad8a61bca30",
"sha256:0a907199566269e1cfa304325cc3b45c72ae341fbb3253ddde19fa820ded7a8b",
"sha256:165a48268bfb5a77e2d9dbb80de7ea917332a79c7adb747bd005b3a07ff8caf0",
"sha256:1b60a95fc995649464e0cd48cecc8288bac5f4198f21d04b8229dc4097d76823",
"sha256:1f66cf263ec77af5b8fe14ef14c5e46e2eb4a795ac495ad7c03adc72ae43fafe",
"sha256:2e08c32cbede4a29e2a701822291ae2bc9b5220a971bba9d1e7615312efd3037",
"sha256:3844c3dab800ca8536f75ae89f3cf566848a3eb2af4d9f7b1103b4f4f7a5dad6",
"sha256:408ce64078398b2ee2ec08199ea3fcf382828d2f8a19c5a5ba2946fe5ddc6c31",
"sha256:443be7602c790960b9514567917af538cac7807a7c0c0727c4d2bbd4014920fd",
"sha256:4482f69e0701139d0f2c44f3c395d1d1d37abd81bfafbf9b6efbe2542679d892",
"sha256:4a8a259bf990044351baf69d3b23e575699dd60b18460c71e81dc565f5819ac1",
"sha256:513e6526e0082c59a984448f4104c9bf346c2da9961779ede1fc458e8e8a1f78",
"sha256:5f587dfd83cb669933186661a351ad6fc7166273bc3e3a1531ec5c783d997aac",
"sha256:62061e87071497951155cbccee487980524d7abea647a1b2a6eb6b9647df9006",
"sha256:641e329e7f2c01531c45c687efcec8aeca2a78a4ff26d49184dce3d53fc35014",
"sha256:65a7e00c00472cd0f59ae09d2fb8a8aaae7f4a0cf54b2b74f3138d9f9ceb9cb2",
"sha256:6ad6ca45e9e92c05295f638e78cd42bfaaf8ee07878c9ed73e93190b26c125f7",
"sha256:73aa6e86034dad9f00f4bbf5a666a889d17d79db73bc5af04abd6c20a014d9c8",
"sha256:7c9762f80a25d8d0e4ab3cb1af5d9dffbddb3ee5d21c43e3474c84bf5ff941f7",
"sha256:85596aa5d9aac1bf39fe39d9fa1051b0f00823982a1de5766e35d495b4a36ca9",
"sha256:86a0ea78fd851b313b2e712266f663e13b6bc78c2fb260b079e8b67d970474b1",
"sha256:8a620767b8209f3446197c0e29ba895d75a1e272a36af0786ec70fe7834e4307",
"sha256:922fb9ef2c67c3ab20e22948dcfd783397e4c043a5c5fa5ff5e9df5529074b0a",
"sha256:9fad78c13e71546a76c2f8789623eec8e499f8d2d799f4b4547162ce0a4df435",
"sha256:a37c6233b28e5bc340054cf6170e7090a4e85069513320275a4dc929144dccf0",
"sha256:c3fc325ce4cbf902d05a80daa47b645d07e796a80682c1c5800d6ac5045193e5",
"sha256:cda33311cb9fb9323958a69499a667bd728a39a7aa4718d7622597a44c4f1441",
"sha256:db1d4e38c9b15be1521722e946ee24f6db95b189d1447fa9ff18dd16ba89f732",
"sha256:eda55e6e9ea258f5e4add23bcf33dc53b2c319e70806e180aecbff8d90ea24de",
"sha256:f372cdbb240e09ee855735b9d85e7f50730dcfb6296b74b95a3e5dea0615c4c1"
],
"version": "==5.0.4"
"sha256:00f1d23f4336efc3b311ed0d807feb45098fc86dee1ca13b3d6768cdab187c8a",
"sha256:01333e1bd22c59713ba8a79f088b3955946e293114479bbfc2e37d522be03355",
"sha256:0cb4be7e784dcdc050fc58ef05b71aa8e89b7e6636b99967fadbdba694cf2b65",
"sha256:0e61d9803d5851849c24f78227939c701ced6704f337cad0a91e0972c51c1ee7",
"sha256:1601e480b9b99697a570cea7ef749e88123c04b92d84cedaa01e117436b4a0a9",
"sha256:2742c7515b9eb368718cd091bad1a1b44135cc72468c731302b3d641895b83d1",
"sha256:2d27a3f742c98e5c6b461ee6ef7287400a1956c11421eb574d843d9ec1f772f0",
"sha256:402e1744733df483b93abbf209283898e9f0d67470707e3c7516d84f48524f55",
"sha256:5c542d1e62eece33c306d66fe0a5c4f7f7b3c08fecc46ead86d7916684b36d6c",
"sha256:5f2294dbf7875b991c381e3d5af2bcc3494d836affa52b809c91697449d0eda6",
"sha256:6402bd2fdedabbdb63a316308142597534ea8e1895f4e7d8bf7476c5e8751fef",
"sha256:66460ab1599d3cf894bb6baee8c684788819b71a5dc1e8fa2ecc152e5d752019",
"sha256:782caea581a6e9ff75eccda79287daefd1d2631cc09d642b6ee2d6da21fc0a4e",
"sha256:79a3cfd6346ce6c13145731d39db47b7a7b859c0272f02cdb89a3bdcbae233a0",
"sha256:7a5bdad4edec57b5fb8dae7d3ee58622d626fd3a0be0dfceda162a7035885ecf",
"sha256:8fa0cbc7ecad630e5b0f4f35b0f6ad419246b02bc750de7ac66db92667996d24",
"sha256:a027ef0492ede1e03a8054e3c37b8def89a1e3c471482e9f046906ba4f2aafd2",
"sha256:a3f3654d5734a3ece152636aad89f58afc9213c6520062db3978239db122f03c",
"sha256:a82b92b04a23d3c8a581fc049228bafde988abacba397d57ce95fe95e0338ab4",
"sha256:acf3763ed01af8410fc36afea23707d4ea58ba7e86a8ee915dfb9ceff9ef69d0",
"sha256:adeb4c5b608574a3d647011af36f7586811a2c1197c861aedb548dd2453b41cd",
"sha256:b83835506dfc185a319031cf853fa4bb1b3974b1f913f5bb1a0f3d98bdcded04",
"sha256:bb28a7245de68bf29f6fb199545d072d1036a1917dca17a1e75bbb919e14ee8e",
"sha256:bf9cb9a9fd8891e7efd2d44deb24b86d647394b9705b744ff6f8261e6f29a730",
"sha256:c317eaf5ff46a34305b202e73404f55f7389ef834b8dbf4da09b9b9b37f76dd2",
"sha256:dbe8c6ae7534b5b024296464f387d57c13caa942f6d8e6e0346f27e509f0f768",
"sha256:de807ae933cfb7f0c7d9d981a053772452217df2bf38e7e6267c9cbf9545a796",
"sha256:dead2ddede4c7ba6cb3a721870f5141c97dc7d85a079edb4bd8d88c3ad5b20c7",
"sha256:dec5202bfe6f672d4511086e125db035a52b00f1648d6407cc8e526912c0353a",
"sha256:e1ea316102ea1e1770724db01998d1603ed921c54a86a2efcb03428d5417e489",
"sha256:f90bfc4ad18450c80b024036eaf91e4a246ae287701aaa88eaebebf150868052"
],
"version": "==5.1"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [



+ 31
- 0
kosmorrolib/core.py Просмотреть файл

@@ -21,10 +21,15 @@ import re
from shutil import rmtree from shutil import rmtree
from pathlib import Path from pathlib import Path


from datetime import date
from dateutil.relativedelta import relativedelta

from skyfield.api import Loader from skyfield.api import Loader
from skyfield.timelib import Time from skyfield.timelib import Time
from skyfield.nutationlib import iau2000b from skyfield.nutationlib import iau2000b


from kosmorrolib.i18n import _

CACHE_FOLDER = str(Path.home()) + '/.kosmorro-cache' CACHE_FOLDER = str(Path.home()) + '/.kosmorro-cache'


class Environment: class Environment:
@@ -86,3 +91,29 @@ def flatten_list(the_list: list):
new_list.append(item) new_list.append(item)


return new_list return new_list


def get_date(date_arg: str) -> date:
if re.match(r'^\d{4}-\d{2}-\d{2}$', date_arg):
try:
return date.fromisoformat(date_arg)
except ValueError as error:
raise ValueError(_('The date {date} is not valid: {error}').format(date=date_arg, error=error.args[0]))
elif re.match(r'^([+-])(([0-9]+)y)?[ ]?(([0-9]+)m)?[ ]?(([0-9]+)d)?$', date_arg):
def get_offset(date_arg: str, signifier: str):
if re.search(r'([0-9]+)' + signifier, date_arg):
return abs(int(re.search(r'[+-]?([0-9]+)' + signifier, date_arg).group(0)[:-1]))
return 0

days = get_offset(date_arg, 'd')
months = get_offset(date_arg, 'm')
years = get_offset(date_arg, 'y')


if date_arg[0] == '+':
return date.today() + relativedelta(days=days, months=months, years=years)
return date.today() - relativedelta(days=days, months=months, years=years)

else:
error_msg = _('The date {date} does not match the required YYYY-MM-DD format or the offset format.')
raise ValueError(error_msg.format(date=date_arg))

+ 25
- 23
kosmorrolib/locales/messages.pot Просмотреть файл

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: kosmorro 0.7.0\n" "Project-Id-Version: kosmorro 0.7.0\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2020-04-05 10:47+0200\n"
"POT-Creation-Date: 2020-04-16 17:57+0200\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,6 +17,16 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.8.0\n" "Generated-By: Babel 2.8.0\n"


#: kosmorrolib/core.py:101
msgid "The date {date} is not valid: {error}"
msgstr ""

#: kosmorrolib/core.py:118
msgid ""
"The date {date} does not match the required YYYY-MM-DD format or the "
"offset format."
msgstr ""

#: kosmorrolib/data.py:32 #: kosmorrolib/data.py:32
msgid "New Moon" msgid "New Moon"
msgstr "" msgstr ""
@@ -211,80 +221,72 @@ msgstr ""
msgid "Selected output format needs an output file (--output)." msgid "Selected output format needs an output file (--output)."
msgstr "" msgstr ""


#: kosmorrolib/main.py:104
msgid "The date {date} does not match the required YYYY-MM-DD format."
msgstr ""

#: kosmorrolib/main.py:109
msgid "The date {date} is not valid: {error}"
msgstr ""

#: kosmorrolib/main.py:123
#: kosmorrolib/main.py:115
msgid "Running on Python {python_version}" msgid "Running on Python {python_version}"
msgstr "" msgstr ""


#: kosmorrolib/main.py:129
#: kosmorrolib/main.py:121
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:136
#: kosmorrolib/main.py:128
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:145
#: kosmorrolib/main.py:137
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:147
#: kosmorrolib/main.py:139
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:152
#: kosmorrolib/main.py:144
msgid "Show the program version" msgid "Show the program version"
msgstr "" msgstr ""


#: kosmorrolib/main.py:154
#: kosmorrolib/main.py:146
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:156
#: kosmorrolib/main.py:148
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:158
#: kosmorrolib/main.py:150
msgid "" msgid ""
"The observer's latitude on Earth. Can also be set in the " "The observer's latitude on Earth. Can also be set in the "
"KOSMORRO_LATITUDE environment variable." "KOSMORRO_LATITUDE environment variable."
msgstr "" msgstr ""


#: kosmorrolib/main.py:161
#: kosmorrolib/main.py:153
msgid "" msgid ""
"The observer's longitude on Earth. Can also be set in the " "The observer's longitude on Earth. Can also be set in the "
"KOSMORRO_LONGITUDE environment variable." "KOSMORRO_LONGITUDE environment variable."
msgstr "" msgstr ""


#: kosmorrolib/main.py:164
#: kosmorrolib/main.py:156
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:168
#: kosmorrolib/main.py:160
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 ""


#: kosmorrolib/main.py:171
#: kosmorrolib/main.py:163
msgid "Disable the colors in the console." msgid "Disable the colors in the console."
msgstr "" msgstr ""


#: kosmorrolib/main.py:173
#: kosmorrolib/main.py:165
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."


+ 1
- 9
kosmorrolib/main.py Просмотреть файл

@@ -42,7 +42,7 @@ def main():
return 0 if args.special_action() else 1 return 0 if args.special_action() else 1


try: try:
compute_date = get_date(args.date)
compute_date = core.get_date(args.date)
except ValueError as error: except ValueError as error:
print(colored(error.args[0], color='red', attrs=['bold'])) print(colored(error.args[0], color='red', attrs=['bold']))
return -1 return -1
@@ -99,14 +99,6 @@ def main():
return 0 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}: def get_dumpers() -> {str: dumper.Dumper}:


+ 1
- 1
manpage/kosmorro.1.md Просмотреть файл

@@ -23,7 +23,7 @@
the observer's longitude on Earth the observer's longitude on Earth


`--date=`_DATE_, `-d` _DATE_ `--date=`_DATE_, `-d` _DATE_
The date for which the ephemerides must be computed (in the YYYY-MM-DD format); defaults to the current date
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_ `--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 display the hours in; e.g. 2 for UTC+2 or -3 for UTC-3


+ 1
- 1
setup.py Просмотреть файл

@@ -41,7 +41,7 @@ setup(
data_files=[ data_files=[
('man/man1', ['manpage/kosmorro.1']) ('man/man1', ['manpage/kosmorro.1'])
], ],
install_requires=['skyfield>=1.17.0,<2.0.0', 'tabulate', 'numpy>=1.17.0,<2.0.0', 'termcolor'],
install_requires=['skyfield>=1.17.0,<2.0.0', 'tabulate', 'numpy>=1.17.0,<2.0.0', 'termcolor', 'python-dateutil'],
classifiers=[ classifiers=[
'Development Status :: 3 - Alpha', 'Development Status :: 3 - Alpha',
'Operating System :: POSIX :: Linux', 'Operating System :: POSIX :: Linux',


+ 7
- 0
test/core.py Просмотреть файл

@@ -3,6 +3,9 @@ import unittest
import os import os
import kosmorrolib.core as core import kosmorrolib.core as core


from datetime import date
from dateutil.relativedelta import relativedelta



class CoreTestCase(unittest.TestCase): class CoreTestCase(unittest.TestCase):
def test_flatten_list(self): def test_flatten_list(self):
@@ -27,6 +30,10 @@ class CoreTestCase(unittest.TestCase):


self.assertEqual("{'great_variable': 'value', 'another_variable': 'another value'}", str(env)) self.assertEqual("{'great_variable': 'value', 'another_variable': 'another value'}", str(env))


def test_date_arg_parsing(self):
self.assertEqual(core.get_date("+1y 2m3d"), date.today() + relativedelta(years=1, months=2, days=3))
self.assertEqual(core.get_date("-1y2d"), date.today() - relativedelta(years=1, days=2))
self.assertEqual(core.get_date("1111-11-13"), date(1111, 11, 13))


if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Загрузка…
Отмена
Сохранить