Skip to content
Snippets Groups Projects
Select Git revision
  • 0126d12d5f8d7990bf0fba2ae82c2170fb60a8bb
  • test default protected
  • master protected
  • feat/custom-css
  • feat/redesign-improvements-10
  • feat/redesign-improvements-8
  • feat/redesign-fixes-3
  • feat/pirstan-changes
  • feat/separate-import-thread
  • feat/dary-improvements
  • features/add-pdf-page
  • features/add-typed-table
  • features/fix-broken-calendar-categories
  • features/add-embed-to-articles
  • features/create-mastodon-feed-block
  • features/add-custom-numbering-for-candidates
  • features/add-timeline
  • features/create-wordcloud-from-article-page
  • features/create-collapsible-extra-legal-info
  • features/extend-hero-banner
  • features/add-link-to-images
21 results

0003_initial.py

Blame
  • parser.py 2.71 KiB
    from operator import itemgetter
    from typing import TYPE_CHECKING
    from zoneinfo import ZoneInfo
    
    import arrow
    import bleach
    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)
        # 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)