Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add search #287

Draft
wants to merge 6 commits into
base: features
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 109 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,8 +44,10 @@
)
from .exceptions import (
InvalidOutputFormatError,
SearchDatesNotGivenError,
UnavailableFeatureError,
OutOfRangeDateError as DateRangeError,
InvalidEventTypeError,
)
from kosmorro.i18n.utils import _

Expand All @@ -55,6 +64,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 +116,42 @@ 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.until,
timezone,
output_format,
use_colors,
args.show_graph,
)
else:
output = get_information(
compute_date,
position,
timezone,
output_format,
use_colors,
args.show_graph,
)
except InvalidEventTypeError as error:
print_stderr(colored(error.msg, "red"))
debug.debug_print(error)
return 7
except InvalidDateRangeError as error:
print_stderr(colored(error, "red"))
debug.debug_print(error)
return 6
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,6 +243,45 @@ 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_until: date,
timezone: int,
output_format: str,
colors: bool,
show_graph: bool,
) -> dumper.Dumper:
try:
if search_until is None:
raise SearchDatesNotGivenError

try:
event_types = [EventType[event.upper()] for event in requested_events]
except KeyError as error:
raise InvalidEventTypeError(error.args[0])

from_ = parse_date(search_from)
until = parse_date(search_until)
events_list = search_events(event_types, until, 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 KeyError as error:
raise InvalidOutputFormatError(output_format, list(get_dumpers().keys()))
Expand Down Expand Up @@ -308,6 +386,27 @@ 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=today.strftime("%Y-%m-%d"),
help=_("The date to begin searching for events. Default is today."),
)
parser.add_argument(
"--until",
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
20 changes: 20 additions & 0 deletions kosmorro/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from datetime import date
from babel.dates import format_date
from kosmorro.i18n.utils import _, SHORT_DATE_FORMAT
from kosmorrolib.enum import EventType


class UnavailableFeatureError(RuntimeError):
Expand Down Expand Up @@ -53,6 +54,25 @@ def __init__(self, output_format: str, accepted_extensions: [str]):
)


class SearchDatesNotGivenError(RuntimeError):
def __init__(self):
super().__init__()
self.msg = _("Search end date (--until) is required when searching events.")


class InvalidEventTypeError(RuntimeError):
def __init__(self, invalid_event: EventType):
super().__init__()
self.invalid_event = invalid_event
supported_events = ", ".join([event.name for _, event in enumerate(EventType)])
self.msg = _(
"Invalid event type {event}.\nSupported events are {events}."
).format(
event=self.invalid_event,
events=supported_events,
)


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