defmodule Excalt.Helpers.EventFormatter do
@doc """
Returns the filtered list of events containing only the events that start and end in the same day.
The input is the list of events as returned by Excalt.Event.parsed_list!/6).
"""
@spec intraday_events(events :: [Excalt.Event.t()]) :: {[Excalt.Event.t()], [Excalt.Event.t()]}
def intraday_events(events) do
events
|> Enum.filter(fn e ->
event = List.first(e.icalendar.events)
dtstart_date = DateTime.to_date(event.dtstart)
dtend_date = DateTime.to_date(event.dtend)
dtstart_date == dtend_date
end)
|> Enum.sort(fn a, b ->
a_event = List.first(a.icalendar.events)
b_event = List.first(b.icalendar.events)
a_event.dtstart > b_event.dtstart
end)
|> Enum.sort(fn a, b ->
a_event = List.first(a.icalendar.events)
b_event = List.first(b.icalendar.events)
dtstart_a = DateTime.to_date(a_event.dtstart)
dtstart_b = DateTime.to_date(b_event.dtstart)
dtstart_a == dtstart_b
end)
end
@doc """
Returns the filtered list of events containing only the events where the start and end are on a differnt day.
The input is the list of events as returned by Excalt.Event.parsed_list!/6).
"""
@spec multiday_events(events :: [Excalt.Event.t()]) :: {[Excalt.Event.t()], [Excalt.Event.t()]}
def multiday_events(events) do
Enum.filter(events, fn e ->
event = List.first(e.icalendar.events)
dtstart_date = DateTime.to_date(event.dtstart)
dtend_date = DateTime.to_date(event.dtend)
dtstart_date != dtend_date
end)
|> Enum.sort(fn a, b ->
a_event = List.first(a.icalendar.events)
b_event = List.first(b.icalendar.events)
dtstart_a = DateTime.to_date(a_event.dtstart)
dtstart_b = DateTime.to_date(b_event.dtstart)
dtstart_a == dtstart_b
end)
end
@doc """
Extracts the basic information about a list of events
"""
def basic_info(events) do
Enum.map(events, fn e ->
event = List.first(e.icalendar.events)
{event.dtstart, event.dtend, event.summary}
end)
end
@doc """
Formats the list of events by grouping them per day
"""
def daily_grouping(events) do
Enum.chunk_by(events, fn {dtstart_a, _, _} ->
dtstart_a = DateTime.to_date(dtstart_a)
dtstart_a
end)
end
@doc """
Formats the list of multiday-events into a human-readable text.
"""
def multiday_txt(events) do
multiday_events = events |> multiday_events |> basic_info
"Multiday events\n" <>
Enum.reduce(multiday_events, "", fn {dtstart, dtend, summary}, acc ->
acc <>
Timex.format!(dtstart, " %d-%b-%Y", :strftime) <>
" - " <>
Timex.format!(dtend, "%d-%b-%Y", :strftime) <> " #{summary}\n"
end)
end
@doc """
Formats the list of intraday-events into a human-readable text.
"""
def intraday_txt(events) do
day_list = events |> intraday_events |> basic_info |> daily_grouping
"Intraday events:\n" <>
Enum.reduce(day_list, "", fn day, acc ->
{day_date, _, _} = List.first(day)
acc <>
Timex.format!(day_date, "%a %d-%b-%Y", :strftime) <>
if DateTime.to_date(day_date) == Date.utc_today(),
do: " <- today",
else:
"" <>
"\n" <>
Enum.reduce(day, "", fn {dtstart, dtend, summary}, acc ->
acc <>
Timex.format!(dtstart, " %H:%M", :strftime) <>
" - " <>
Timex.format!(dtend, "%H:%M", :strftime) <> " #{summary}\n"
end)
end)
end
end