Browse Source

feat: display a graph in the PDF output for the ephemerides

Show a graph instead of a table for the ephemerides in the PDF output
tags/v0.8.0
Jérôme Deuchnord 4 years ago
parent
commit
4ea148e8d1
No known key found for this signature in database GPG Key ID: BF7828A4E3722466
9 changed files with 309 additions and 92 deletions
  1. +3
    -1
      .gitignore
  2. +1
    -0
      .scripts/tests-e2e.sh
  3. +115
    -0
      kosmorrolib/assets/pdf/kosmorro.sty
  4. +9
    -45
      kosmorrolib/assets/pdf/template.tex
  5. +60
    -7
      kosmorrolib/dumper.py
  6. +41
    -35
      kosmorrolib/locales/messages.pot
  7. +6
    -4
      kosmorrolib/main.py
  8. +3
    -0
      manpage/kosmorro.1.md
  9. +71
    -0
      test/dumper.py

+ 3
- 1
.gitignore View File

@@ -6,8 +6,10 @@ kosmorro.egg-info
coverage.xml coverage.xml
node_modules/ node_modules/
package-lock.json package-lock.json

/kosmorrolib/assets/pdf/* /kosmorrolib/assets/pdf/*
!/assets/pdf/*.tex
!/kosmorrolib/assets/pdf/*.tex
!/kosmorrolib/assets/pdf/*.sty


/manpage/* /manpage/*
!/manpage/*.md !/manpage/*.md


+ 1
- 0
.scripts/tests-e2e.sh View File

@@ -104,6 +104,7 @@ assertSuccess "$PIP_BIN install latex" "CI"


# Dependencies installed, should not fail # Dependencies installed, should not fail
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf" assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf"
assertSuccess "kosmorro --latitude=50.5876 --longitude=3.0624 -d 2020-01-27 --format=pdf -o /tmp/document.pdf --no-graph"


# man page # man page
assertSuccess "man --pager=cat kosmorro" assertSuccess "man --pager=cat kosmorro"


+ 115
- 0
kosmorrolib/assets/pdf/kosmorro.sty View File

@@ -0,0 +1,115 @@
%! Package = kosmorro
%! Author = Jérôme Deuchnord
%! Date = 2020-04-26

\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{kosmorro}[2020/04/26 Kosmorro Package]

\RequirePackage{xcolor}
\RequirePackage{fp}

\newcommand{\moonphase}[2]{
\begin{center}
\begin{minipage}{2cm}
\includegraphics[width=\linewidth]{#1}
\end{minipage}
\hspace{5mm}
\begin{minipage}{7cm}
\textbf{\currentmoonphasetitle}\\#2
\end{minipage}
\end{center}
}

\newenvironment{ephemerides}{
\begin{table}[h]
\centering
\begin{tabular}{lccc}
\textbf{\ephemeridesobjecttitle} &
\textbf{\ephemeridesrisetimetitle} &
\textbf{\ephemeridesculminationtimetitle} &
\textbf{\ephemeridessettimetitle}\\
\hline
}{
\end{tabular}
\end{table}
}

\newcommand{\object}[4]{
\hline
\textbf{#1} & {#2} & {#3} & {#4}\\
}

\newenvironment{graphephemerides}{\setlength{\unitlength}{0.02\linewidth}
\begin{picture}(20,20)
% Axes
\put(0,-2){\vector(1,0){50}}
\multiput(0,-2)(2,0){24}{
\line(0,-1){0.25}
}
\newcounter{hour}
\multiput(-0.25,-3.5)(4,0){12}{
\sffamily\footnotesize
\arabic{hour}\stepcounter{hour}\stepcounter{hour}
}
\put(49,-3.5){\sffamily\footnotesize hours}

% Graduation

\put(50,-0.5){\sffamily\footnotesize Pluto}
\put(50,1.5){\sffamily\footnotesize Neptune}
\put(50,3.5){\sffamily\footnotesize Uranus}
\put(50,5.5){\sffamily\footnotesize Saturn}
\put(50,7.5){\sffamily\footnotesize Jupiter}
\put(50,9.5){\sffamily\footnotesize Mars}
\put(50,11.5){\sffamily\footnotesize Venus}
\put(50,13.5){\sffamily\footnotesize Mercury}
\put(50,15.5){\sffamily\footnotesize Moon}
\put(50,17.5){\sffamily\footnotesize Sun}

\multiput(0,0)(0,2){10}{
\color{gray}\line(1,0){48}
}

\linethickness{1.5mm}
}{
\end{picture}
\vspace{1cm}
}

\newcommand{\graphobject}[8]{%
% #1: Y coordinate component
% #2: Color
% #3: Hour rise time
% #4: Minute rise time
% #5: Hour set time
% #6: Minute set time
% #7: Human-readable rise time
% #8: Human-readable set time

\FPeval{\start}{#3*2+(#4/60)*2}%
\FPeval{\length}{#5*2+(#6/60)*2 - \start}%
\FPeval{\starttext}{\start+0.7}%
\FPeval{\endtext}{\start+\length-3.25}%

{\color{#2}%
\put(\start,#1){%
\line(1, 0){\length}%
}}%

\put(\starttext,#1.5){\sffamily\footnotesize #7}%
\put(\endtext,#1.5){\sffamily\footnotesize #8}%
}

\newcommand{\event}[2]{
\textbf{#1} & {#2}\\
}

\newenvironment{events}{
\begin{table}[h]
\begin{tabular}{ll}
}{
\end{tabular}
\end{table}
}

\endinput

+ 9
- 45
kosmorrolib/assets/pdf/template.tex View File

@@ -5,12 +5,19 @@
\usepackage[margin=25mm]{geometry} \usepackage[margin=25mm]{geometry}
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{hyperref} \usepackage{hyperref}
\usepackage{kosmorro}

\newcommand{\currentmoonphasetitle}{+++CURRENT-MOON-PHASE-TITLE+++}
\newcommand{\ephemeridesobjecttitle}{+++EPHEMERIDES-OBJECT+++}
\newcommand{\ephemeridesrisetimetitle}{+++EPHEMERIDES-RISE-TIME+++}
\newcommand{\ephemeridesculminationtimetitle}{+++EPHEMERIDES-CULMINATION-TIME+++}
\newcommand{\ephemeridessettimetitle}{+++EPHEMERIDES-SET-TIME+++}


% Fix Unicode issues % Fix Unicode issues
\DeclareUnicodeCharacter{202F}{~} \DeclareUnicodeCharacter{202F}{~}
\DeclareUnicodeCharacter{00B0}{$^\circ$} \DeclareUnicodeCharacter{00B0}{$^\circ$}


\hypersetup{pdfinfo={
\hypersetup{pdfinfo={%
Title={+++DOCUMENT-TITLE+++}, Title={+++DOCUMENT-TITLE+++},
Creator={Kosmorro v+++KOSMORRO-VERSION+++} Creator={Kosmorro v+++KOSMORRO-VERSION+++}
}} }}
@@ -23,49 +30,6 @@


\begin{document} \begin{document}


\newcommand{\object}[4]{
\hline
\textbf{#1} & {#2} & {#3} & {#4}\\
}

\newcommand{\moonphase}[2]{
\begin{center}
\begin{minipage}{2cm}
\includegraphics[width=\linewidth]{#1}
\end{minipage}
\hspace{5mm}
\begin{minipage}{7cm}
\textbf{+++CURRENT-MOON-PHASE-TITLE+++}\\#2
\end{minipage}
\end{center}
}

\newenvironment{ephemerides}{
\begin{table}[h]
\centering
\begin{tabular}{lccc}
\textbf{+++EPHEMERIDES-OBJECT+++} &
\textbf{+++EPHEMERIDES-RISE-TIME+++} &
\textbf{+++EPHEMERIDES-CULMINATION-TIME+++} &
\textbf{+++EPHEMERIDES-SET-TIME+++}\\
\hline
}{
\end{tabular}
\end{table}
}

\newcommand{\event}[2]{
\textbf{#1} & {#2}\\
}

\newenvironment{events}{
\begin{table}[h]
\begin{tabular}{ll}
}{
\end{tabular}
\end{table}
}

\maketitle \maketitle


+++INTRODUCTION+++ +++INTRODUCTION+++
@@ -76,7 +40,7 @@
\section{\sffamily +++SECTION-EPHEMERIDES+++} \section{\sffamily +++SECTION-EPHEMERIDES+++}


\begin{ephemerides} \begin{ephemerides}
+++EPHEMERIDES+++
+++EPHEMERIDES+++
\end{ephemerides} \end{ephemerides}
%%% END-EPHEMERIDES-SECTION %%% END-EPHEMERIDES-SECTION




+ 60
- 7
kosmorrolib/dumper.py View File

@@ -20,6 +20,7 @@ from abc import ABC, abstractmethod
import datetime import datetime
import json import json
import os import os
from pathlib import Path
from tabulate import tabulate from tabulate import tabulate
from numpy import int64 from numpy import int64
from termcolor import colored from termcolor import colored
@@ -41,13 +42,15 @@ TIME_FORMAT = _('{hours}:{minutes}').format(hours='%H', minutes='%M')


class Dumper(ABC): class Dumper(ABC):
def __init__(self, ephemerides: [AsterEphemerides] = None, moon_phase: MoonPhase = None, events: [Event] = None, def __init__(self, ephemerides: [AsterEphemerides] = None, moon_phase: MoonPhase = None, events: [Event] = None,
date: datetime.date = datetime.date.today(), timezone: int = 0, with_colors: bool = True):
date: datetime.date = datetime.date.today(), timezone: int = 0, with_colors: bool = True,
show_graph: bool = False):
self.ephemerides = ephemerides self.ephemerides = ephemerides
self.moon_phase = moon_phase self.moon_phase = moon_phase
self.events = events self.events = events
self.date = date self.date = date
self.timezone = timezone self.timezone = timezone
self.with_colors = with_colors self.with_colors = with_colors
self.show_graph = show_graph


if self.timezone != 0: if self.timezone != 0:
self._convert_dates_to_timezones() self._convert_dates_to_timezones()
@@ -282,10 +285,17 @@ class _LatexDumper(Dumper):
.replace('+++SECTION-EVENTS+++', _('Expected events')) \ .replace('+++SECTION-EVENTS+++', _('Expected events')) \
.replace('+++EVENTS+++', self._make_events()) .replace('+++EVENTS+++', self._make_events())


if self.show_graph:
# The graphephemerides environment beginning tag must end with a percent symbol to ensure
# that no extra space will interfere with the graph.
document = document.replace(r'\begin{ephemerides}', r'\begin{graphephemerides}%')\
.replace(r'\end{ephemerides}', r'\end{graphephemerides}')

return document return document


def _make_ephemerides(self) -> str: def _make_ephemerides(self) -> str:
latex = [] latex = []
graph_y_component = 18


if self.ephemerides is not None: if self.ephemerides is not None:
for ephemeris in self.ephemerides: for ephemeris in self.ephemerides:
@@ -308,10 +318,46 @@ class _LatexDumper(Dumper):
else: else:
aster_set = '-' aster_set = '-'


latex.append(r'\object{%s}{%s}{%s}{%s}' % (ephemeris.object.name,
aster_rise,
aster_culmination,
aster_set))
if not self.show_graph:
latex.append(r'\object{%s}{%s}{%s}{%s}' % (ephemeris.object.name,
aster_rise,
aster_culmination,
aster_set))
else:
if ephemeris.rise_time is not None:
raise_hour = ephemeris.rise_time.hour
raise_minute = ephemeris.rise_time.minute
else:
raise_hour = raise_minute = 0
aster_rise = ''

if ephemeris.set_time is not None:
set_hour = ephemeris.set_time.hour
set_minute = ephemeris.set_time.minute
else:
set_hour = 24
set_minute = 0
aster_set = ''
sets_after_end = set_hour > raise_hour

if not sets_after_end:
latex.append(r'\graphobject{%d}{gray}{0}{0}{%d}{%d}{}{%s}' % (graph_y_component,
set_hour,
set_minute,
aster_set))
set_hour = 24
set_minute = 0

latex.append(r'\graphobject{%d}{gray}{%d}{%d}{%d}{%d}{%s}{%s}' % (
graph_y_component,
raise_hour,
raise_minute,
set_hour,
set_minute,
aster_rise,
aster_set if sets_after_end else ''
))
graph_y_component -= 2


return ''.join(latex) return ''.join(latex)


@@ -345,10 +391,15 @@ class _LatexDumper(Dumper):




class PdfDumper(Dumper): class PdfDumper(Dumper):
def _convert_dates_to_timezones(self):
"""This method is disabled in this dumper, because the timezone is already converted
in :class:`_LatexDumper`."""

def to_string(self): def to_string(self):
try: try:
latex_dumper = _LatexDumper(self.ephemerides, self.moon_phase, self.events, latex_dumper = _LatexDumper(self.ephemerides, self.moon_phase, self.events,
date=self.date, timezone=self.timezone, with_colors=self.with_colors)
date=self.date, timezone=self.timezone, with_colors=self.with_colors,
show_graph=self.show_graph)
return self._compile(latex_dumper.to_string()) return self._compile(latex_dumper.to_string())
except RuntimeError: except RuntimeError:
raise UnavailableFeatureError(_("Building PDFs was not possible, because some dependencies are not" raise UnavailableFeatureError(_("Building PDFs was not possible, because some dependencies are not"
@@ -364,4 +415,6 @@ class PdfDumper(Dumper):
if build_pdf is None: if build_pdf is None:
raise RuntimeError('Python latex module not found') raise RuntimeError('Python latex module not found')


return bytes(build_pdf(latex_input))
package = str(Path(__file__).parent.absolute()) + '/assets/pdf/'

return bytes(build_pdf(latex_input, [package]))

+ 41
- 35
kosmorrolib/locales/messages.pot View File

@@ -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-18 15:51+0200\n"
"POT-Creation-Date: 2020-05-12 13:42+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"
@@ -119,80 +119,80 @@ msgstr ""
msgid "Pluto" msgid "Pluto"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:35
#: kosmorrolib/dumper.py:36
msgid "{day_of_week} {month} {day_number}, {year}" msgid "{day_of_week} {month} {day_number}, {year}"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:37
#: kosmorrolib/dumper.py:38
msgid "{month} {day_number}, {hours}:{minutes}" msgid "{month} {day_number}, {hours}:{minutes}"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:39
#: kosmorrolib/dumper.py:40
msgid "{hours}:{minutes}" msgid "{hours}:{minutes}"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:150
#: kosmorrolib/dumper.py:153
msgid "Expected events:" msgid "Expected events:"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:154
#: kosmorrolib/dumper.py:157
msgid "Note: All the hours are given in UTC." msgid "Note: All the hours are given in UTC."
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:159
#: kosmorrolib/dumper.py:162
msgid "Note: All the hours are given in the UTC{offset} timezone." msgid "Note: All the hours are given in the UTC{offset} timezone."
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:205 kosmorrolib/dumper.py:274
#: kosmorrolib/dumper.py:208 kosmorrolib/dumper.py:277
msgid "Object" msgid "Object"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:206 kosmorrolib/dumper.py:275
#: kosmorrolib/dumper.py:209 kosmorrolib/dumper.py:278
msgid "Rise time" msgid "Rise time"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:207 kosmorrolib/dumper.py:276
#: kosmorrolib/dumper.py:210 kosmorrolib/dumper.py:279
msgid "Culmination time" msgid "Culmination time"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:208 kosmorrolib/dumper.py:277
#: kosmorrolib/dumper.py:211 kosmorrolib/dumper.py:280
msgid "Set time" msgid "Set time"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:222 kosmorrolib/dumper.py:280
#: kosmorrolib/dumper.py:225 kosmorrolib/dumper.py:283
msgid "Moon phase:" msgid "Moon phase:"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:223
#: kosmorrolib/dumper.py:226
msgid "{next_moon_phase} on {next_moon_phase_date} at {next_moon_phase_time}" msgid "{next_moon_phase} on {next_moon_phase_date} at {next_moon_phase_time}"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:261
#: kosmorrolib/dumper.py:264
msgid "A Summary of your Sky" msgid "A Summary of your Sky"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:265
#: kosmorrolib/dumper.py:268
msgid "" msgid ""
"This document summarizes the ephemerides and the events of {date}. It " "This document summarizes the ephemerides and the events of {date}. It "
"aims to help you to prepare your observation session. All the hours are " "aims to help you to prepare your observation session. All the hours are "
"given in {timezone}." "given in {timezone}."
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:271
#: kosmorrolib/dumper.py:274
msgid "" msgid ""
"Don't forget to check the weather forecast before you go out with your " "Don't forget to check the weather forecast before you go out with your "
"equipment." "equipment."
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:273
#: kosmorrolib/dumper.py:276
msgid "Ephemerides of the day" msgid "Ephemerides of the day"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:282
#: kosmorrolib/dumper.py:285
msgid "Expected events" msgid "Expected events"
msgstr "" msgstr ""


#: kosmorrolib/dumper.py:354
#: kosmorrolib/dumper.py:405
msgid "" msgid ""
"Building PDFs was not possible, because some dependencies are not " "Building PDFs was not possible, because some dependencies are not "
"installed.\n" "installed.\n"
@@ -213,82 +213,88 @@ msgid ""
"the observation coordinate." "the observation coordinate."
msgstr "" msgstr ""


#: kosmorrolib/main.py:93
#: kosmorrolib/main.py:94
msgid "Could not save the output in \"{path}\": {error}" msgid "Could not save the output in \"{path}\": {error}"
msgstr "" msgstr ""


#: kosmorrolib/main.py:98
#: kosmorrolib/main.py:99
msgid "Selected output format needs an output file (--output)." msgid "Selected output format needs an output file (--output)."
msgstr "" msgstr ""


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


#: kosmorrolib/main.py:123
#: kosmorrolib/main.py:122
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:130
#: kosmorrolib/main.py:129
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:139
#: kosmorrolib/main.py:138
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:141
#: kosmorrolib/main.py:140
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:146
#: kosmorrolib/main.py:145
msgid "Show the program version" msgid "Show the program version"
msgstr "" msgstr ""


#: kosmorrolib/main.py:148
#: kosmorrolib/main.py:147
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:150
#: kosmorrolib/main.py:149
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:152
#: kosmorrolib/main.py:151
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:155
#: kosmorrolib/main.py:154
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:158
#: kosmorrolib/main.py:157
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:162
#: kosmorrolib/main.py:161
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:165
#: kosmorrolib/main.py:164
msgid "Disable the colors in the console." msgid "Disable the colors in the console."
msgstr "" msgstr ""


#: kosmorrolib/main.py:167
#: kosmorrolib/main.py:166
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."
msgstr "" msgstr ""


#: kosmorrolib/main.py:169
msgid ""
"Generate a graph instead of a table to show the rise, culmination set "
"times (PDF only)"
msgstr ""


+ 6
- 4
kosmorrolib/main.py View File

@@ -79,7 +79,8 @@ def main():
timezone = 0 timezone = 0


format_dumper = output_formats[output_format](ephemerides=eph, moon_phase=moon_phase, events=events_list, format_dumper = output_formats[output_format](ephemerides=eph, moon_phase=moon_phase, events=events_list,
date=compute_date, timezone=timezone, with_colors=args.colors)
date=compute_date, timezone=timezone, with_colors=args.colors,
show_graph=args.show_graph)
output = format_dumper.to_string() output = format_dumper.to_string()
except UnavailableFeatureError as error: except UnavailableFeatureError as error:
print(colored(error.msg, 'red')) print(colored(error.msg, 'red'))
@@ -101,13 +102,11 @@ def main():
return 0 return 0






def get_dumpers() -> {str: dumper.Dumper}: def get_dumpers() -> {str: dumper.Dumper}:
return { return {
'text': dumper.TextDumper, 'text': dumper.TextDumper,
'json': dumper.JsonDumper, 'json': dumper.JsonDumper,
'pdf': dumper.PdfDumper
'pdf': dumper.PdfDumper,
} }




@@ -166,5 +165,8 @@ def get_args(output_formats: [str]):
parser.add_argument('--output', '-o', type=str, default=None, parser.add_argument('--output', '-o', type=str, default=None,
help=_('A file to export the output to. If not given, the standard output is used. ' help=_('A file to export the output to. If not given, the standard output is used. '
'This argument is needed for PDF format.')) 'This argument is needed for PDF format.'))
parser.add_argument('--no-graph', dest='show_graph', action='store_false',
help=_('Generate a graph instead of a table to show the rise, culmination set times '
'(PDF only)'))


return parser.parse_args() return parser.parse_args()

+ 3
- 0
manpage/kosmorro.1.md View File

@@ -37,6 +37,9 @@
`--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


`--no-graph`
present the ephemerides in a table instead of a graph; PDF output format only

## ENVIRONMENT VARIABLES ## ENVIRONMENT VARIABLES


The environment variable listed below may be used instead of the options. The environment variable listed below may be used instead of the options.


+ 71
- 0
test/dumper.py View File

@@ -229,6 +229,77 @@ class DumperTestCase(unittest.TestCase):


self.assertNotRegex(latex, r'\\section{\\sffamily Expected events}') self.assertNotRegex(latex, r'\\section{\\sffamily Expected events}')


def test_latex_dumper_with_graph(self):
latex = _LatexDumper(self._get_ephemerides(True), self._get_moon_phase(), self._get_events(),
date=date(2019, 10, 14), show_graph=True).to_string()

self.assertRegex(latex, 'Monday October 14, 2019')
self.assertRegex(latex, 'Full Moon')
self.assertRegex(latex, r'\\section{\\sffamily Expected events}')
self.assertRegex(latex, r'\\section{\\sffamily Ephemerides of the day}')
self.assertRegex(latex, r'\\graphobject\{18\}\{gray\}\{8\}\{0\}\{23\}\{0\}\{08:00\}\{23:00\}')
self.assertRegex(latex, r'\\event\{23:00\}\{Mars is in opposition\}')
self.assertRegex(latex, r"\\event\{12:00\}\{Venus's largest elongation \(42.0°\)\}")

latex = _LatexDumper(self._get_ephemerides(aster_rise_set=True), self._get_moon_phase(),
self._get_events(), date=date(2019, 10, 14)).to_string()
self.assertRegex(latex, r'\\object\{Mars\}\{08:00\}\{13:00\}\{23:00\}')

def test_latex_dumper_with_graph_but_without_rise_time(self):
ephemerides = self._get_ephemerides(True)
ephemerides[0].rise_time = None
latex = _LatexDumper(ephemerides, self._get_moon_phase(), self._get_events(),
date=date(2019, 10, 14), show_graph=True).to_string()

self.assertRegex(latex, 'Monday October 14, 2019')
self.assertRegex(latex, 'Full Moon')
self.assertRegex(latex, r'\\section{\\sffamily Expected events}')
self.assertRegex(latex, r'\\section{\\sffamily Ephemerides of the day}')
self.assertRegex(latex, r'\\graphobject\{18\}\{gray\}\{0\}\{0\}\{23\}\{0\}\{\}\{23:00\}')
self.assertRegex(latex, r'\\event\{23:00\}\{Mars is in opposition\}')
self.assertRegex(latex, r"\\event\{12:00\}\{Venus's largest elongation \(42.0°\)\}")

latex = _LatexDumper(self._get_ephemerides(aster_rise_set=True), self._get_moon_phase(),
self._get_events(), date=date(2019, 10, 14)).to_string()
self.assertRegex(latex, r'\\object\{Mars\}\{08:00\}\{13:00\}\{23:00\}')

def test_latex_dumper_with_graph_but_without_set_time(self):
ephemerides = self._get_ephemerides(True)
ephemerides[0].set_time = None
latex = _LatexDumper(ephemerides, self._get_moon_phase(), self._get_events(),
date=date(2019, 10, 14), show_graph=True).to_string()

self.assertRegex(latex, 'Monday October 14, 2019')
self.assertRegex(latex, 'Full Moon')
self.assertRegex(latex, r'\\section{\\sffamily Expected events}')
self.assertRegex(latex, r'\\section{\\sffamily Ephemerides of the day}')
self.assertRegex(latex, r'\\graphobject\{18\}\{gray\}\{8\}\{0\}\{24\}\{0\}\{08:00\}\{\}')
self.assertRegex(latex, r'\\event\{23:00\}\{Mars is in opposition\}')
self.assertRegex(latex, r"\\event\{12:00\}\{Venus's largest elongation \(42.0°\)\}")

latex = _LatexDumper(self._get_ephemerides(aster_rise_set=True), self._get_moon_phase(),
self._get_events(), date=date(2019, 10, 14)).to_string()
self.assertRegex(latex, r'\\object\{Mars\}\{08:00\}\{13:00\}\{23:00\}')

def test_latex_dumper_with_graph_but_mars_sets_tomorrow(self):
ephemerides = self._get_ephemerides(True)
ephemerides[0].set_time = datetime(2019, 10, 15, 1)
latex = _LatexDumper(ephemerides, self._get_moon_phase(), self._get_events(),
date=date(2019, 10, 14), show_graph=True).to_string()

self.assertRegex(latex, 'Monday October 14, 2019')
self.assertRegex(latex, 'Full Moon')
self.assertRegex(latex, r'\\section{\\sffamily Expected events}')
self.assertRegex(latex, r'\\section{\\sffamily Ephemerides of the day}')
self.assertRegex(latex, r'\\graphobject\{18\}\{gray\}\{8\}\{0\}\{24\}\{0\}\{08:00\}\{\}')
self.assertRegex(latex, r'\\graphobject\{18\}\{gray\}\{0\}\{0\}\{1\}\{0\}\{\}\{Oct 15, 01:00\}')
self.assertRegex(latex, r'\\event\{23:00\}\{Mars is in opposition\}')
self.assertRegex(latex, r"\\event\{12:00\}\{Venus's largest elongation \(42.0°\)\}")

latex = _LatexDumper(self._get_ephemerides(aster_rise_set=True), self._get_moon_phase(),
self._get_events(), date=date(2019, 10, 14)).to_string()
self.assertRegex(latex, r'\\object\{Mars\}\{08:00\}\{13:00\}\{23:00\}')

@staticmethod @staticmethod
def _get_ephemerides(aster_rise_set=False) -> [AsterEphemerides]: def _get_ephemerides(aster_rise_set=False) -> [AsterEphemerides]:
rise_time = datetime(2019, 10, 14, 8) if aster_rise_set else None rise_time = datetime(2019, 10, 14, 8) if aster_rise_set else None


Loading…
Cancel
Save