Skip to content

Commit

Permalink
feat: add event searching
Browse files Browse the repository at this point in the history
only parse from and to dates when searching

toggle between date formats when searching

refactoring

change date formatting for searched events

raise exception when search dates not given
  • Loading branch information
nicfb committed Oct 9, 2022
1 parent 997ccc8 commit dc587f3
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 12 deletions.
116 changes: 106 additions & 10 deletions kosmorro/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,15 @@
import os.path

from babel.dates import format_date
from kosmorrolib import Position, get_ephemerides, get_events, get_moon_phase
from kosmorrolib.exceptions import OutOfRangeDateError
from kosmorrolib import (
Position,
get_ephemerides,
get_events,
get_moon_phase,
search_events,
)
from kosmorrolib.exceptions import OutOfRangeDateError, InvalidDateRangeError
from kosmorrolib.enum import EventType
from datetime import date

from . import dumper, environment, debug
Expand All @@ -37,6 +44,7 @@
)
from .exceptions import (
InvalidOutputFormatError,
SearchDatesNotGivenError,
UnavailableFeatureError,
OutOfRangeDateError as DateRangeError,
)
Expand All @@ -55,6 +63,8 @@ def run():
if args.special_action is not None:
return 0 if args.special_action() else 1

search_enabled = args.search is not None

try:
compute_date = parse_date(args.date)
except ValueError as error:
Expand Down Expand Up @@ -105,14 +115,34 @@ def run():
try:
use_colors = not environment.NO_COLOR and args.colors

output = get_information(
compute_date,
position,
timezone,
output_format,
use_colors,
args.show_graph,
)
output = None
if search_enabled:
output = get_search_information(
args.search,
args.from_,
args.to,
timezone,
output_format,
use_colors,
args.show_graph,
)
else:
output = get_information(
compute_date,
position,
timezone,
output_format,
use_colors,
args.show_graph,
)
except SearchDatesNotGivenError as error:
print_stderr(colored(error.msg, "red"))
debug.debug_print(error)
return 5
except ValueError as error:
print_stderr(colored(error.args[0], color="red", attrs=["bold"]))
debug.debug_print(error)
return 4
except InvalidOutputFormatError as error:
print_stderr(colored(error.msg, "red"))
debug.debug_print(error)
Expand Down Expand Up @@ -204,13 +234,61 @@ def get_information(
timezone=timezone,
with_colors=colors,
show_graph=show_graph,
search_enabled=False,
)
except KeyError as error:
raise InvalidOutputFormatError(output_format, list(get_dumpers().keys()))
except OutOfRangeDateError as error:
raise DateRangeError(error.min_date, error.max_date)


def get_search_information(
requested_events: [EventType],
search_from: date,
search_to: date,
timezone: int,
output_format: str,
colors: bool,
show_graph: bool,
) -> dumper.Dumper:
try:
if search_from is None or search_to is None:
raise SearchDatesNotGivenError

event_types = [EventType[event.upper()] for event in requested_events]
from_ = parse_date(search_from)
to = parse_date(search_to)
events_list = search_events(event_types, to, from_, timezone)

return get_dumpers()[output_format](
ephemerides=[],
moon_phase=None,
events=events_list,
date=None,
timezone=timezone,
with_colors=colors,
show_graph=show_graph,
search_enabled=True,
)
except InvalidDateRangeError as error:
print(
colored(
_(
"Search start date {start_search} must be before end date {end_search}"
).format(
start_search=format_date(error.start_date, "long"),
end_search=format_date(error.end_date, "long"),
),
"red",
)
)
except KeyError as error:
raise InvalidOutputFormatError(output_format, list(get_dumpers().keys()))
except OutOfRangeDateError as error:
print(colored(error.msg, "red"))
debug.debug_print(error)


def get_dumpers() -> {str: dumper.Dumper}:
return {
"txt": dumper.TextDumper,
Expand Down Expand Up @@ -308,6 +386,24 @@ def get_args(output_formats: [str]):
"Can also be set in the KOSMORRO_TIMEZONE environment variable."
),
)
parser.add_argument(
"--search",
"-s",
type=str,
nargs="*",
default=None,
help=_("Search for specific event types by date."),
)
parser.add_argument(
"--from",
dest="from_",
type=str,
default=None,
help=_("The date to begin searching for events."),
)
parser.add_argument(
"--to", type=str, default=None, help=_("The date to end searching for events.")
)
parser.add_argument(
"--no-colors",
dest="colors",
Expand Down
7 changes: 5 additions & 2 deletions kosmorro/dumper.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import shutil
from pathlib import Path

from babel.dates import format_date, format_time
from babel.dates import format_date, format_time, format_datetime
from tabulate import tabulate
from termcolor import colored

Expand Down Expand Up @@ -60,6 +60,7 @@ def __init__(
timezone: int,
with_colors: bool,
show_graph: bool,
search_enabled: bool,
):
self.ephemerides = ephemerides
self.moon_phase = moon_phase
Expand All @@ -68,6 +69,7 @@ def __init__(
self.timezone = timezone
self.with_colors = with_colors
self.show_graph = show_graph
self.search_enabled = search_enabled

def get_date_as_string(self, capitalized: bool = False) -> str:
date = format_date(self.date, "full")
Expand Down Expand Up @@ -220,9 +222,10 @@ def get_events(self, events: [Event]) -> str:
if description is None:
continue

date_format = "MMM dd, yyyy hh:mm a" if self.search_enabled else "hh:mm a"
data.append(
[
self.style(format_time(event.start_time, "short"), "th"),
self.style(format_datetime(event.start_time, date_format), "th"),
description,
]
)
Expand Down
21 changes: 21 additions & 0 deletions kosmorro/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,19 @@ def __init__(self, min_date: date, max_date: date):
)


class InvalidDateRangeError(RuntimeError):
def __init__(self, start_date: date, end_date: date):
super().__init__()
self.start_date = start_date
self.end_date = end_date
self.msg = _(
"The start date {starting_date} must be before the end date {ending_date}"
).format(
starting_date=format_date(start_date, "long"),
ending_date=format_date(end_date, "long"),
)


class InvalidOutputFormatError(RuntimeError):
def __init__(self, output_format: str, accepted_extensions: [str]):
super().__init__()
Expand All @@ -53,6 +66,14 @@ def __init__(self, output_format: str, accepted_extensions: [str]):
)


class SearchDatesNotGivenError(RuntimeError):
def __init__(self):
super().__init__()
self.msg = _(
"Both 'from' and 'to' dates are required when searching for events."
)


class CompileError(RuntimeError):
def __init__(self, msg):
super().__init__()
Expand Down

0 comments on commit dc587f3

Please sign in to comment.