-
Tom Teichler authoredTom Teichler authored
event_feed.py 2.50 KiB
import logging
from django.utils import formats, timezone
import requests
from cache_memoize import cache_memoize
from ics import Calendar
logger = logging.getLogger(__name__)
def get_current_events(calendar: Calendar, limit: int = 5) -> list:
"""Get upcoming events from a calendar (ICS) object.
:param calendar: The calendar object
:param limit: Count of events
:return: List of upcoming events
"""
i: int = 0
events: list = []
for event in calendar.timeline.start_after(timezone.now()):
# Check for limit
if i >= limit:
break
i += 1
# Create formatted dates and times for begin and end
begin_date_formatted = formats.date_format(event.begin)
end_date_formatted = formats.date_format(event.end)
begin_time_formatted = formats.time_format(event.begin.time())
end_time_formatted = formats.time_format(event.end.time())
if event.begin.date() == event.end.date():
# Event is only on one day
formatted = begin_date_formatted
if not event.all_day:
# No all day event
formatted += f" {begin_time_formatted}"
if event.begin.time != event.end.time():
# Event has an end time
formatted += f" – {end_time_formatted}"
else:
# Event is on multiple days
if event.all_day:
# Event is all day
formatted = f"{begin_date_formatted} – {end_date_formatted}"
else:
# Event has begin and end times
formatted = f(
"{begin_date_formatted} {begin_time_formatted} –"
"{end_date_formatted} {end_time_formatted}"
)
events.append(
{
"name": event.name,
"begin_timestamp": event.begin.timestamp,
"end_timestamp": event.end.timestamp,
"date_formatted": formatted,
}
)
return events
@cache_memoize(300)
def get_current_events_with_cal(calendar_url: str, limit: int = 5) -> list:
"""
Download an iCalendar file from an URL, parse using the ICS library
and return a limited number of events.
"""
try:
content = requests.get(calendar_url, timeout=3)
except requests.RequestException as e:
logger.error(str(e))
return []
calendar: Calendar = Calendar(content.text)
return get_current_events(calendar, limit)