from operator import attrgetter import arrow from django.conf import settings from ics import Calendar EVENT_KEYS = ("begin", "end", "all_day", "name", "description", "location") def parse_ical(source): """Parses iCalendar source and returns events as list of dicts.""" cal = Calendar(source) events = [] for event in sorted(cal.events, key=attrgetter("begin"), reverse=True): events.append({key: getattr(event, key) for key in EVENT_KEYS}) return events def split_events(events): """Splits events and returns list of past events and future events.""" now = arrow.utcnow() past = [ev for ev in events if ev["end"] < now] future = [ev for ev in events if ev["end"] > now] return past, future def set_event_duration(event): """Sets duration for event.""" if event["all_day"]: event["duration"] = "celĂ˝ den" return event delta = event["end"] - event["begin"] if delta.days < 1: begin = event["begin"].to(settings.TIME_ZONE).format("H:mm") end = event["end"].to(settings.TIME_ZONE).format("H:mm") event["duration"] = f"{begin} - {end}" else: begin = event["begin"].to(settings.TIME_ZONE).format("H:mm") end = event["end"].to(settings.TIME_ZONE).format("H:mm (D.M.)") event["duration"] = f"{begin} - {end}" return event def process_ical(source): """Parses iCalendar source and returns events as list of dicts. Returns tuple of past and future events. """ events = parse_ical(source) events = list(map(set_event_duration, events)) return split_events(events)