Add colors in the text returntags/v0.5.0
@@ -13,6 +13,7 @@ babel = "*" | |||
skyfield = ">=1.13.0,<2.0.0" | |||
tabulate = "*" | |||
numpy = ">=1.17.0,<2.0.0" | |||
termcolor = "*" | |||
[requires] | |||
python_version = "3" |
@@ -1,7 +1,7 @@ | |||
{ | |||
"_meta": { | |||
"hash": { | |||
"sha256": "d5c2451a4f189a6d10a9205879f066fd9b595723f2e1077416aa3f48cdcbfb9f" | |||
"sha256": "fb530146420b5768bc25165302d947d11615aac375e7a63a9076fdddd0372d53" | |||
}, | |||
"pipfile-spec": 6, | |||
"requires": { | |||
@@ -68,6 +68,13 @@ | |||
], | |||
"index": "pypi", | |||
"version": "==0.8.6" | |||
}, | |||
"termcolor": { | |||
"hashes": [ | |||
"sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" | |||
], | |||
"index": "pypi", | |||
"version": "==1.1.0" | |||
} | |||
}, | |||
"develop": { | |||
@@ -110,39 +117,39 @@ | |||
}, | |||
"coverage": { | |||
"hashes": [ | |||
"sha256:189aac76d6e0d7af15572c51892e7326ee451c076c5a50a9d266406cd6c49708", | |||
"sha256:1bf7ba2af1d373a1750888724f84cffdfc697738f29a353c98195f98fc011509", | |||
"sha256:1f4ee8e2e4243971618bc16fcc4478317405205f135e95226c2496e2a3b8dbbf", | |||
"sha256:225e79a5d485bc1642cb7ba02281419c633c216cdc6b26c26494ba959f09e69f", | |||
"sha256:23688ff75adfa8bfa2a67254d889f9bdf9302c27241d746e17547c42c732d3f4", | |||
"sha256:28f7f73b34a05e23758e860a89a7f649b85c6749e252eff60ebb05532d180e86", | |||
"sha256:2d0cb9b1fe6ad0d915d45ad3d87f03a38e979093a98597e755930db1f897afae", | |||
"sha256:47874b4711c5aeb295c31b228a758ce3d096be83dc37bd56da48ed99efb8813b", | |||
"sha256:511ec0c00840e12fb4e852e4db58fa6a01ca4da72f36a9766fae344c3d502033", | |||
"sha256:53e7438fef0c97bc248f88ba1edd10268cd94d5609970aaf87abbe493691af87", | |||
"sha256:569f9ee3025682afda6e9b0f5bb14897c0db03f1a1dc088b083dd36e743f92bb", | |||
"sha256:593853aa1ac6dcc6405324d877544c596c9d948ef20d2e9512a0f5d2d3202356", | |||
"sha256:5b0a07158360d22492f9abd02a0f2ee7981b33f0646bf796598b7673f6bbab14", | |||
"sha256:7ca3db38a61f3655a2613ee2c190d63639215a7a736d3c64cc7bbdb002ce6310", | |||
"sha256:7d1cc7acc9ce55179616cf72154f9e648136ea55987edf84addbcd9886ffeba2", | |||
"sha256:88b51153657612aea68fa684a5b88037597925260392b7bb4509d4f9b0bdd889", | |||
"sha256:955ec084f549128fa2702f0b2dc696392001d986b71acd8fd47424f28289a9c3", | |||
"sha256:b251c7092cbb6d789d62dc9c9e7c4fb448c9138b51285c36aeb72462cad3600e", | |||
"sha256:bd82b684bb498c60ef47bb1541a50e6d006dde8579934dcbdbc61d67d1ea70d9", | |||
"sha256:bfe102659e2ec13b86c7f3b1db6c9a4e7beea4255058d006351339e6b342d5d2", | |||
"sha256:c1e4e39e43057396a5e9d069bfbb6ffeee892e40c5d2effbd8cd71f34ee66c4d", | |||
"sha256:cb2b74c123f65e8166f7e1265829a6c8ed755c3cd16d7f50e75a83456a5f3fd7", | |||
"sha256:cca38ded59105f7705ef6ffe1e960b8db6c7d8279c1e71654a4775ab4454ca15", | |||
"sha256:cf908840896f7aa62d0ec693beb53264b154f972eb8226fb864ac38975590c4f", | |||
"sha256:d095a7b473f8a95f7efe821f92058c8a2ecfb18f8db6677ae3819e15dc11aaae", | |||
"sha256:d22b4297e7e4225ccf01f1aa55e7a96412ea0796b532dd614c3fcbafa341128e", | |||
"sha256:d4a2b578a7a70e0c71f662705262f87a456f1e6c1e40ada7ea699abaf070a76d", | |||
"sha256:ddeb42a3d5419434742bf4cc71c9eaa22df3b76808e23a82bd0b0bd360f1a9f1", | |||
"sha256:e65a5aa1670db6263f19fdc03daee1d7dbbadb5cb67fd0a1f16033659db13c1d", | |||
"sha256:eaad65bd20955131bcdb3967a4dea66b4e4d4ca488efed7c00d91ee0173387e8", | |||
"sha256:f45fba420b94165c17896861bb0e8b27fb7abdcedfeb154895d8553df90b7b00" | |||
], | |||
"version": "==5.0.2" | |||
"sha256:15cf13a6896048d6d947bf7d222f36e4809ab926894beb748fc9caa14605d9c3", | |||
"sha256:1daa3eceed220f9fdb80d5ff950dd95112cd27f70d004c7918ca6dfc6c47054c", | |||
"sha256:1e44a022500d944d42f94df76727ba3fc0a5c0b672c358b61067abb88caee7a0", | |||
"sha256:25dbf1110d70bab68a74b4b9d74f30e99b177cde3388e07cc7272f2168bd1477", | |||
"sha256:3230d1003eec018ad4a472d254991e34241e0bbd513e97a29727c7c2f637bd2a", | |||
"sha256:3dbb72eaeea5763676a1a1efd9b427a048c97c39ed92e13336e726117d0b72bf", | |||
"sha256:5012d3b8d5a500834783689a5d2292fe06ec75dc86ee1ccdad04b6f5bf231691", | |||
"sha256:51bc7710b13a2ae0c726f69756cf7ffd4362f4ac36546e243136187cfcc8aa73", | |||
"sha256:527b4f316e6bf7755082a783726da20671a0cc388b786a64417780b90565b987", | |||
"sha256:722e4557c8039aad9592c6a4213db75da08c2cd9945320220634f637251c3894", | |||
"sha256:76e2057e8ffba5472fd28a3a010431fd9e928885ff480cb278877c6e9943cc2e", | |||
"sha256:77afca04240c40450c331fa796b3eab6f1e15c5ecf8bf2b8bee9706cd5452fef", | |||
"sha256:7afad9835e7a651d3551eab18cbc0fdb888f0a6136169fbef0662d9cdc9987cf", | |||
"sha256:9bea19ac2f08672636350f203db89382121c9c2ade85d945953ef3c8cf9d2a68", | |||
"sha256:a8b8ac7876bc3598e43e2603f772d2353d9931709345ad6c1149009fd1bc81b8", | |||
"sha256:b0840b45187699affd4c6588286d429cd79a99d509fe3de0f209594669bb0954", | |||
"sha256:b26aaf69713e5674efbde4d728fb7124e429c9466aeaf5f4a7e9e699b12c9fe2", | |||
"sha256:b63dd43f455ba878e5e9f80ba4f748c0a2156dde6e0e6e690310e24d6e8caf40", | |||
"sha256:be18f4ae5a9e46edae3f329de2191747966a34a3d93046dbdf897319923923bc", | |||
"sha256:c312e57847db2526bc92b9bfa78266bfbaabac3fdcd751df4d062cd4c23e46dc", | |||
"sha256:c60097190fe9dc2b329a0eb03393e2e0829156a589bd732e70794c0dd804258e", | |||
"sha256:c62a2143e1313944bf4a5ab34fd3b4be15367a02e9478b0ce800cb510e3bbb9d", | |||
"sha256:cc1109f54a14d940b8512ee9f1c3975c181bbb200306c6d8b87d93376538782f", | |||
"sha256:cd60f507c125ac0ad83f05803063bed27e50fa903b9c2cfee3f8a6867ca600fc", | |||
"sha256:d513cc3db248e566e07a0da99c230aca3556d9b09ed02f420664e2da97eac301", | |||
"sha256:d649dc0bcace6fcdb446ae02b98798a856593b19b637c1b9af8edadf2b150bea", | |||
"sha256:d7008a6796095a79544f4da1ee49418901961c97ca9e9d44904205ff7d6aa8cb", | |||
"sha256:da93027835164b8223e8e5af2cf902a4c80ed93cb0909417234f4a9df3bcd9af", | |||
"sha256:e69215621707119c6baf99bda014a45b999d37602cb7043d943c76a59b05bf52", | |||
"sha256:ea9525e0fef2de9208250d6c5aeeee0138921057cd67fcef90fbed49c4d62d37", | |||
"sha256:fca1669d464f0c9831fd10be2eef6b86f5ebd76c724d1e0706ebdff86bb4adf0" | |||
], | |||
"version": "==5.0.3" | |||
}, | |||
"idna": { | |||
"hashes": [ | |||
@@ -223,10 +230,10 @@ | |||
}, | |||
"six": { | |||
"hashes": [ | |||
"sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", | |||
"sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" | |||
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", | |||
"sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" | |||
], | |||
"version": "==1.13.0" | |||
"version": "==1.14.0" | |||
}, | |||
"urllib3": { | |||
"hashes": [ | |||
@@ -22,6 +22,7 @@ import json | |||
from tabulate import tabulate | |||
from skyfield.timelib import Time | |||
from numpy import int64 | |||
from termcolor import colored | |||
from .data import Object, AsterEphemerides, MoonPhase, Event | |||
from .i18n import _ | |||
@@ -31,10 +32,12 @@ TIME_FORMAT = _('{hours}:{minutes}').format(hours='%H', minutes='%M') | |||
class Dumper(ABC): | |||
def __init__(self, ephemeris: dict, events: [Event], date: datetime.date = datetime.date.today()): | |||
def __init__(self, ephemeris: dict, events: [Event], date: datetime.date = datetime.date.today(), | |||
with_colors: bool = True): | |||
self.ephemeris = ephemeris | |||
self.events = events | |||
self.date = date | |||
self.with_colors = with_colors | |||
@abstractmethod | |||
def to_string(self): | |||
@@ -80,35 +83,45 @@ class JsonDumper(Dumper): | |||
class TextDumper(Dumper): | |||
def to_string(self): | |||
text = self.date.strftime(FULL_DATE_FORMAT) | |||
# Always capitalize the first character | |||
text = ''.join([text[0].upper(), text[1:]]) | |||
text = [self.style(self.get_date(), 'h1')] | |||
if len(self.ephemeris['details']) > 0: | |||
text = '\n\n'.join([text, | |||
self.get_asters(self.ephemeris['details']) | |||
]) | |||
text.append(self.get_asters(self.ephemeris['details'])) | |||
text = '\n\n'.join([text, | |||
self.get_moon(self.ephemeris['moon_phase']) | |||
]) | |||
text.append(self.get_moon(self.ephemeris['moon_phase'])) | |||
if len(self.events) > 0: | |||
text = '\n\n'.join([text, | |||
_('Expected events:'), | |||
self.get_events(self.events) | |||
]) | |||
text.append('\n'.join([self.style(_('Expected events:'), 'h2'), | |||
self.get_events(self.events)])) | |||
text = '\n\n'.join([text, _('Note: All the hours are given in UTC.')]) | |||
text.append(self.style(_('Note: All the hours are given in UTC.'), 'em')) | |||
return text | |||
return '\n\n'.join(text) | |||
@staticmethod | |||
def get_asters(asters: [Object]) -> str: | |||
def style(self, text: str, tag: str) -> str: | |||
if not self.with_colors: | |||
return text | |||
styles = { | |||
'h1': lambda t: colored(t, 'yellow', attrs=['bold']), | |||
'h2': lambda t: colored(t, 'magenta', attrs=['bold']), | |||
'th': lambda t: colored(t, 'white', attrs=['bold']), | |||
'strong': lambda t: colored(t, attrs=['bold']), | |||
'em': lambda t: colored(t, attrs=['dark']) | |||
} | |||
return styles[tag](text) | |||
def get_date(self) -> str: | |||
date = self.date.strftime(FULL_DATE_FORMAT) | |||
return ''.join([date[0].upper(), date[1:]]) | |||
def get_asters(self, asters: [Object]) -> str: | |||
data = [] | |||
for aster in asters: | |||
name = aster.name | |||
name = self.style(aster.name, 'th') | |||
if aster.ephemerides.rise_time is not None: | |||
planet_rise = aster.ephemerides.rise_time.utc_strftime(TIME_FORMAT) | |||
@@ -127,23 +140,23 @@ class TextDumper(Dumper): | |||
data.append([name, planet_rise, planet_culmination, planet_set]) | |||
return tabulate(data, headers=[_('Object'), _('Rise time'), _('Culmination time'), _('Set time')], | |||
return tabulate(data, headers=[self.style(_('Object'), 'th'), | |||
self.style(_('Rise time'), 'th'), | |||
self.style(_('Culmination time'), 'th'), | |||
self.style(_('Set time'), 'th')], | |||
tablefmt='simple', stralign='center', colalign=('left',)) | |||
@staticmethod | |||
def get_events(events: [Event]) -> str: | |||
def get_events(self, events: [Event]) -> str: | |||
data = [] | |||
for event in events: | |||
data.append([event.start_time.utc_strftime(TIME_FORMAT), event.get_description()]) | |||
data.append([self.style(event.start_time.utc_strftime(TIME_FORMAT), 'th'), | |||
event.get_description()]) | |||
return tabulate(data, tablefmt='plain', stralign='left') | |||
@staticmethod | |||
def get_moon(moon_phase: MoonPhase) -> str: | |||
current_moon_phase = _('Moon phase: {current_moon_phase}').format( | |||
current_moon_phase=moon_phase.get_phase() | |||
) | |||
def get_moon(self, moon_phase: MoonPhase) -> str: | |||
current_moon_phase = ' '.join([self.style(_('Moon phase:'), 'strong'), moon_phase.get_phase()]) | |||
new_moon_phase = _('{next_moon_phase} on {next_moon_phase_date} at {next_moon_phase_time}').format( | |||
next_moon_phase=moon_phase.get_next_phase(), | |||
next_moon_phase_date=moon_phase.next_phase_date.utc_strftime(FULL_DATE_FORMAT), | |||
@@ -8,7 +8,7 @@ msgid "" | |||
msgstr "" | |||
"Project-Id-Version: kosmorro 0.4.0\n" | |||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" | |||
"POT-Creation-Date: 2020-01-02 14:05+0100\n" | |||
"POT-Creation-Date: 2020-01-19 10:39+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" | |||
@@ -99,43 +99,43 @@ msgstr "" | |||
msgid "%s and %s are in conjunction" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:28 | |||
#: kosmorrolib/dumper.py:29 | |||
msgid "{day_of_week} {month} {day_number}, {year}" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:30 | |||
#: kosmorrolib/dumper.py:31 | |||
msgid "{hours}:{minutes}" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:98 | |||
#: kosmorrolib/dumper.py:94 | |||
msgid "Expected events:" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:102 | |||
#: kosmorrolib/dumper.py:97 | |||
msgid "Note: All the hours are given in UTC." | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:130 | |||
#: kosmorrolib/dumper.py:143 | |||
msgid "Object" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:130 | |||
#: kosmorrolib/dumper.py:144 | |||
msgid "Rise time" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:130 | |||
#: kosmorrolib/dumper.py:145 | |||
msgid "Culmination time" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:130 | |||
#: kosmorrolib/dumper.py:146 | |||
msgid "Set time" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:144 | |||
msgid "Moon phase: {current_moon_phase}" | |||
#: kosmorrolib/dumper.py:159 | |||
msgid "Moon phase:" | |||
msgstr "" | |||
#: kosmorrolib/dumper.py:147 | |||
#: kosmorrolib/dumper.py:160 | |||
msgid "{next_moon_phase} on {next_moon_phase_date} at {next_moon_phase_time}" | |||
msgstr "" | |||
@@ -203,3 +203,7 @@ msgid "" | |||
"{default_year} (the current year)." | |||
msgstr "" | |||
#: kosmorrolib/main.py:125 | |||
msgid "Disable the colors in the console." | |||
msgstr "" | |||
@@ -57,7 +57,7 @@ def main(): | |||
events_list = events.search_events(compute_date) | |||
dump = output_formats[args.format](ephemerides, events_list, compute_date) | |||
dump = output_formats[args.format](ephemerides, events_list, compute_date, args.colors) | |||
print(dump.to_string()) | |||
return 0 | |||
@@ -121,5 +121,7 @@ def get_args(output_formats: [str]): | |||
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('--no-colors', dest='colors', action='store_false', | |||
help=_('Disable the colors in the console.')) | |||
return parser.parse_args() |
@@ -52,7 +52,7 @@ class DumperTestCase(unittest.TestCase): | |||
'Moon phase: Full Moon\n' | |||
'Last Quarter on Monday October 21, 2019 at 00:00\n\n' | |||
'Note: All the hours are given in UTC.', | |||
TextDumper(ephemerides, [], date=date(2019, 10, 14)).to_string()) | |||
TextDumper(ephemerides, [], date=date(2019, 10, 14), with_colors=False).to_string()) | |||
def test_text_dumper_with_events(self): | |||
ephemerides = self._get_data() | |||
@@ -62,26 +62,26 @@ class DumperTestCase(unittest.TestCase): | |||
'Mars - - -\n\n' | |||
'Moon phase: Full Moon\n' | |||
'Last Quarter on Monday October 21, 2019 at 00:00\n\n' | |||
'Expected events:\n\n' | |||
'Expected events:\n' | |||
'05:12 Mars is in opposition\n\n' | |||
'Note: All the hours are given in UTC.', | |||
TextDumper(ephemerides, [Event('OPPOSITION', | |||
[Planet('Mars', 'MARS')], | |||
get_timescale().utc(2018, 7, 27, 5, 12)) | |||
], date=date(2019, 10, 14)).to_string()) | |||
], date=date(2019, 10, 14), with_colors=False).to_string()) | |||
def test_text_dumper_without_ephemerides_and_with_events(self): | |||
ephemerides = self._get_data(False) | |||
self.assertEqual('Monday October 14, 2019\n\n' | |||
'Moon phase: Full Moon\n' | |||
'Last Quarter on Monday October 21, 2019 at 00:00\n\n' | |||
'Expected events:\n\n' | |||
'Expected events:\n' | |||
'05:12 Mars is in opposition\n\n' | |||
'Note: All the hours are given in UTC.', | |||
TextDumper(ephemerides, [Event('OPPOSITION', | |||
[Planet('Mars', 'MARS')], | |||
get_timescale().utc(2018, 7, 27, 5, 12)) | |||
], date=date(2019, 10, 14)).to_string()) | |||
], date=date(2019, 10, 14), with_colors=False).to_string()) | |||
@staticmethod | |||
def _get_data(has_ephemerides: bool = True): | |||