mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-20 22:37:44 +00:00
48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
from datetime import datetime, time
|
|
from typing import cast
|
|
|
|
import pytz
|
|
from icalendar import Calendar, Event
|
|
|
|
from data.alert import Alert
|
|
from providers.alert.http_alert_provider import HTTPAlertProvider
|
|
|
|
|
|
class ICALAlertProvider(HTTPAlertProvider):
|
|
"""Generic alert provider for iCal calendars. Defines an abstract method event_to_alert(event) that subclasses must
|
|
implement, and use it to convert an iCal event to an Alert object based on whatever format their iCal events use."""
|
|
|
|
def __init__(self, name, provider_config, url, poll_interval):
|
|
super().__init__(name, provider_config, url, poll_interval)
|
|
|
|
def _http_response_to_alerts(self, http_response):
|
|
new_alerts = []
|
|
cal = Calendar.from_ical(http_response.content)
|
|
|
|
# Iterate through events, passing each one in turn to the subclass' event_to_alert method to turn it into
|
|
# a Spothole alert object
|
|
for component in cal.walk():
|
|
if component.name != "VEVENT":
|
|
continue
|
|
|
|
event = cast(Event, component)
|
|
alert = self.event_to_alert(event)
|
|
new_alerts.append(alert)
|
|
return new_alerts
|
|
|
|
def event_to_alert(self, event: Event) -> Alert:
|
|
"""Convert an ICal event to an Alert object. Subclasses must implement this method."""
|
|
|
|
@staticmethod
|
|
def _to_utc_timestamp(value):
|
|
"""Convert a date or datetime value from an iCal field into a UTC UNIX timestamp."""
|
|
|
|
# Datetime object so we can treat it as-is, check if it has a non-UTC tz and convert it if necessary
|
|
if isinstance(value, datetime):
|
|
if value.tzinfo is None:
|
|
value = pytz.UTC.localize(value)
|
|
return value.astimezone(pytz.UTC).timestamp()
|
|
|
|
# Date object so this is an all day event
|
|
return pytz.UTC.localize(datetime.combine(value, time.min)).timestamp()
|