-
Notifications
You must be signed in to change notification settings - Fork 15
/
calendar_events.py
153 lines (113 loc) · 4.57 KB
/
calendar_events.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""Module to add and update events on GOOGLE_CALENDAR_ID."""
import datetime
import os
import re
from apiclient import discovery
import httplib2
from oauth2client.service_account import ServiceAccountCredentials
from util import stream_topic_to_narrow_url
GOOGLE_APPLICATION_CREDENTIALS = os.getenv('GOOGLE_APPLICATION_CREDENTIALS', None)
GOOGLE_CALENDAR_ID = os.getenv('GOOGLE_CALENDAR_ID', None)
def add_rsvpbot_event_to_gcal(rsvpbot_event, rsvpbot_event_id):
"""Given an RSVPBot event dict, create a calendar event."""
event_dict = _format_rsvpbot_event_for_gcal(rsvpbot_event, rsvpbot_event_id)
return create_event_on_calendar(event_dict, GOOGLE_CALENDAR_ID)
def update_gcal_event(rsvpbot_event, rsvpbot_event_id):
"""Updates an existing calendar event based on an updated rsvpbot event
It is expected that the rsvp_bot event has an existing calendar event
id stored so it knows which event to update.
"""
event_id = rsvpbot_event['calendar_event']['id']
new_event_details = _format_rsvpbot_event_for_gcal(rsvpbot_event, rsvpbot_event_id)
return update_event_on_calendar(event_id, new_event_details, GOOGLE_CALENDAR_ID)
def create_event_on_calendar(event_dict, calendar_id):
"""Creates `event_dict` on the given `calendar_id`."""
service = _get_calendar_service()
if service and calendar_id:
calendar = service.calendars().get(calendarId=calendar_id).execute()
result = {'calendar_name': calendar['summary']}
event = service.events().insert(
calendarId=calendar_id,
body=event_dict,
).execute()
result.update(event)
return result
else:
return None
def update_event_on_calendar(event_id, event_dict, calendar_id):
"""Updates `event_id` on the given `calendar_id`."""
service = _get_calendar_service()
if service and calendar_id:
event = service.events().patch(
calendarId=calendar_id,
eventId=event_id,
body=event_dict
).execute()
return event
else:
return None
def _get_calendar_service():
scopes = ['https://www.googleapis.com/auth/calendar']
path_to_keyfile = GOOGLE_APPLICATION_CREDENTIALS
if not path_to_keyfile:
raise KeyfilePathNotSpecifiedError
credentials = ServiceAccountCredentials.from_json_keyfile_name(
path_to_keyfile, scopes=scopes)
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)
return service
def _format_rsvpbot_event_for_gcal(rsvpbot_event, event_id):
"""Convert an RSVPBot event dict into the format needed for
the Google Calendar API."""
name = rsvpbot_event.get('name')
location = rsvpbot_event.get('place')
description = rsvpbot_event.get('description') or ''
event_id_parts = event_id.split('/')
stream = event_id_parts[0]
topic = '/'.join(event_id_parts[1:])
description += '\r\rFor more information or to RSVP, see {zulip_url}'.format(
zulip_url=stream_topic_to_narrow_url(stream, topic))
date = rsvpbot_event.get('date')
time = rsvpbot_event.get('time')
if not (date and time):
raise DateAndTimeNotSuppliedError
full_date_string = '{date} {time}'.format(
date=rsvpbot_event.get('date'),
time=rsvpbot_event.get('time')
)
duration = rsvpbot_event.get('duration')
if not duration:
raise DurationNotSuppliedError
duration = datetime.timedelta(seconds=duration)
start_date = datetime.datetime.strptime(full_date_string, '%Y-%m-%d %H:%M')
end_date = start_date + duration
email_regex = re.compile(r"[^@]+@[^@]+\.[^@]+")
rsvp_yes_attendee_list = [
{'email': entity, 'responseStatus': 'accepted'} for entity in rsvpbot_event['yes']
if email_regex.match(entity)
]
rsvp_maybe_attendee_list = [
{'email': entity, 'responseStatus': 'tentative'} for entity in rsvpbot_event['maybe']
if email_regex.match(entity)
]
calendar_event = {
'summary': name,
'location': location,
'description': description,
'start': {
'dateTime': start_date.isoformat(),
'timeZone': 'America/New_York',
},
'end': {
'dateTime': end_date.isoformat(),
'timeZone': 'America/New_York',
},
'attendees': rsvp_yes_attendee_list + rsvp_maybe_attendee_list,
}
return calendar_event
class DurationNotSuppliedError(Exception):
pass
class DateAndTimeNotSuppliedError(Exception):
pass
class KeyfilePathNotSpecifiedError(Exception):
pass