-
Alexa Valentová authoredAlexa Valentová authored
parser.py 2.87 KiB
from operator import itemgetter
from typing import TYPE_CHECKING
from zoneinfo import ZoneInfo
import arrow
import bleach
import nh3
from django.conf import settings
from django.utils.timezone import is_naive
if TYPE_CHECKING:
from .icalevents.icalparser import Event
EVENT_KEYS = ("start", "end", "all_day", "summary", "description", "location", "url")
def split_event_dict_list(event_list: "list[dict]") -> tuple[list[dict], list[dict]]:
"""Splits events and returns list of past events and future events."""
singularity = arrow.utcnow().shift(hours=-2)
past = [ev for ev in event_list if ev["end"] < singularity]
future = list(reversed([ev for ev in event_list if ev["end"] > singularity]))
return past, future
def set_event_description(event: "Event") -> "Event":
"""Clears even description from unwanted tags."""
description: str = event.description or ""
event.description = bleach.clean(description, tags=["a", "br"], strip=True)
return event
def set_event_duration(event: "Event") -> "Event":
"""Sets duration for event."""
if event.all_day:
event.duration = "celý den"
return event
delta = event.end - event.start
if delta.days < 1:
begin = arrow.get(event.start).to(settings.TIME_ZONE).format("H:mm")
end = arrow.get(event.end).to(settings.TIME_ZONE).format("H:mm")
event.duration = f"{begin} - {end}"
else:
begin = arrow.get(event.start).to(settings.TIME_ZONE).format("H:mm")
end = arrow.get(event.end).to(settings.TIME_ZONE).format("H:mm (D.M.)")
event.duration = f"{begin} - {end}"
return event
def set_event_timezone(event: "Event") -> "Event":
"""Sets default project timezone for event if missing."""
if is_naive(event.start) or is_naive(event.end):
event.start = event.start.replace(tzinfo=ZoneInfo(settings.TIME_ZONE))
event.end = event.end.replace(tzinfo=ZoneInfo(settings.TIME_ZONE))
return event
def process_event(event: "Event") -> dict:
"""Processes single event for use in Majak"""
event = set_event_timezone(event)
event = set_event_duration(event)
event = set_event_description(event)
event.description = nh3.clean(
event.description,
tags={"h1", "h2", "h3", "h4", "h5", "h6", "a", "em", "p", "b", "strong", "br"},
)
# for event in sorted(cal.events, key=attrgetter("start"), reverse=True): TODO check
return {key: getattr(event, key) for key in EVENT_KEYS}
def process_event_list(event_list: "list[Event]") -> tuple[list[dict], list[dict]]:
"""Parses iCalendar source and returns events as list of dicts. Returns
tuple of past and future events.
"""
processed_event_list = list(map(process_event, event_list))
processed_event_list = sorted(
processed_event_list, key=itemgetter("start"), reverse=True
)
return split_event_dict_list(processed_event_list)