2018-06-23 01:00:43 +02:00
|
|
|
"""
|
|
|
|
.. moduleauthor:: Fabio Manganiello <blacklight86@gmail.com>
|
|
|
|
"""
|
|
|
|
|
2018-05-30 15:59:07 +02:00
|
|
|
import datetime
|
|
|
|
import dateutil.parser
|
|
|
|
import requests
|
|
|
|
|
2018-07-06 02:08:38 +02:00
|
|
|
from platypush.plugins import Plugin, action
|
2018-05-30 15:59:07 +02:00
|
|
|
from platypush.plugins.calendar import CalendarInterface
|
|
|
|
|
|
|
|
|
2019-06-18 18:29:49 +02:00
|
|
|
class CalendarIcalPlugin(Plugin, CalendarInterface):
|
2018-06-23 01:00:43 +02:00
|
|
|
"""
|
|
|
|
iCal calendars plugin. Interact with remote calendars in iCal format.
|
2018-06-26 23:19:35 +02:00
|
|
|
|
|
|
|
Requires:
|
|
|
|
|
|
|
|
* **icalendar** (``pip install icalendar``)
|
2018-12-19 00:09:21 +01:00
|
|
|
* **python-dateutil** (``pip install python-dateutil``)
|
2018-06-23 01:00:43 +02:00
|
|
|
"""
|
|
|
|
|
2018-05-30 15:59:07 +02:00
|
|
|
def __init__(self, url, *args, **kwargs):
|
2018-06-23 01:00:43 +02:00
|
|
|
"""
|
|
|
|
:param url: iCal URL to parse
|
|
|
|
:type url: str
|
|
|
|
"""
|
2018-05-30 15:59:07 +02:00
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.url = url
|
|
|
|
|
|
|
|
|
|
|
|
def _translate_event(self, event):
|
|
|
|
return {
|
|
|
|
'id': str(event.get('uid')) if event.get('uid') else None,
|
|
|
|
'kind': 'calendar#event',
|
|
|
|
'summary': str(event.get('summary')) if event.get('summary') else None,
|
|
|
|
'description': str(event.get('description')) if event.get('description') else None,
|
|
|
|
'status': str(event.get('status')).lower() if event.get('status') else None,
|
|
|
|
'responseStatus': str(event.get('partstat')).lower() if event.get('partstat') else None,
|
|
|
|
'location': str(event.get('location')) if event.get('location') else None,
|
|
|
|
'htmlLink': str(event.get('url')) if event.get('url') else None,
|
|
|
|
'organizer': {
|
|
|
|
'email': str(event.get('organizer')).replace('MAILTO:', ''),
|
|
|
|
'displayName': event.get('organizer').params['cn']
|
|
|
|
} if event.get('organizer') else None,
|
|
|
|
|
|
|
|
'created': event.get('created').dt.isoformat() if event.get('created') else None,
|
|
|
|
'updated': event.get('last-modified').dt.isoformat() if event.get('last-modified') else None,
|
|
|
|
'start': {
|
|
|
|
'dateTime': event.get('dtstart').dt.isoformat() if event.get('dtstart') else None,
|
|
|
|
'timeZone': 'UTC', # TODO Support multiple timezone IDs
|
|
|
|
},
|
|
|
|
|
|
|
|
'end': {
|
|
|
|
'dateTime': event.get('dtend').dt.isoformat() if event.get('dtend') else None,
|
|
|
|
'timeZone': 'UTC',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-06 02:08:38 +02:00
|
|
|
@action
|
2018-05-30 15:59:07 +02:00
|
|
|
def get_upcoming_events(self, max_results=10, only_participating=True):
|
2018-06-23 01:00:43 +02:00
|
|
|
"""
|
|
|
|
Get the upcoming events. See
|
|
|
|
:func:`~platypush.plugins.calendar.CalendarPlugin.get_upcoming_events`.
|
|
|
|
"""
|
|
|
|
|
2019-06-18 18:29:49 +02:00
|
|
|
import pytz
|
2019-12-01 23:35:05 +01:00
|
|
|
from icalendar import Calendar
|
2019-06-18 18:29:49 +02:00
|
|
|
|
2018-05-30 15:59:07 +02:00
|
|
|
events = []
|
2021-03-05 11:16:14 +01:00
|
|
|
response = requests.get(self.url)
|
|
|
|
assert response.ok, \
|
|
|
|
"HTTP error while getting events from {}: {}".format(self.url, response.text)
|
|
|
|
|
|
|
|
calendar = Calendar.from_ical(response.text)
|
|
|
|
for event in calendar.walk():
|
|
|
|
if event.name != 'VEVENT':
|
|
|
|
continue # Not an event
|
|
|
|
|
|
|
|
event = self._translate_event(event)
|
|
|
|
|
|
|
|
if event['status'] and event['responseStatus'] \
|
|
|
|
and dateutil.parser.parse(event['end']['dateTime']) >= \
|
|
|
|
datetime.datetime.now(pytz.timezone('UTC')) \
|
|
|
|
and (
|
|
|
|
(only_participating
|
|
|
|
and event['status'] == 'confirmed'
|
|
|
|
and event['responseStatus'] in ['accepted', 'tentative'])
|
|
|
|
or not only_participating):
|
|
|
|
events.append(event)
|
2018-05-30 15:59:07 +02:00
|
|
|
|
2018-07-06 02:08:38 +02:00
|
|
|
return events
|
2018-05-30 15:59:07 +02:00
|
|
|
|
|
|
|
|
|
|
|
# vim:sw=4:ts=4:et:
|
|
|
|
|