forked from zulip/zulip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gcal-bot
executable file
·131 lines (105 loc) · 3.78 KB
/
gcal-bot
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
#!/usr/bin/env python
import sys
import time
import datetime
import optparse
import urlparse
import itertools
import traceback
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '../api'))
import zulip
parser = optparse.OptionParser(r"""
%prog \
--user [email protected] \
--calendar http://www.google.com/calendar/feeds/foo%40zulip.com/private-fedcba9876543210fedcba9876543210/basic
Send yourself reminders on Zulip of Google Calendar events.
To get the calendar URL:
- Load Google Calendar in a web browser
- Find your calendar in the "My calendars" list on the left
- Click the down-wedge icon that appears on mouseover, and select "Calendar settings"
- Copy the link address for the "XML" button under "Private Address"
Run this on your personal machine. Your API key and calendar URL are revealed to local
users through the command line.
Depends on: python-gdata
""")
parser.add_option('--calendar',
dest='calendar',
action='store',
help='Google Calendar XML "Private Address"',
metavar='URL')
parser.add_option('--interval',
dest='interval',
default=10,
type=int,
action='store',
help='Minutes before event for reminder [default: 10]',
metavar='MINUTES')
parser.add_option_group(zulip.generate_option_group(parser))
(options, args) = parser.parse_args()
if not (options.zulip_email and options.calendar):
parser.error('You must specify --user and --calendar')
try:
from gdata.calendar.client import CalendarClient
except ImportError:
parser.error('Install python-gdata')
def get_calendar_url():
parts = urlparse.urlparse(options.calendar)
pat = os.path.split(parts.path)
if pat[1] != 'basic':
parser.error('The --calendar URL should be the XML "Private Address" ' +
'from your calendar settings')
return urlparse.urlunparse((parts.scheme, parts.netloc, pat[0] + '/full',
'', 'futureevents=true&orderby=startdate', ''))
calendar_url = get_calendar_url()
client = zulip.init_from_options(options)
def get_events():
feed = CalendarClient().GetCalendarEventFeed(uri=calendar_url)
for event in feed.entry:
start = event.when[0].start.split('.')[0]
# All-day events can have only a date
fmt = '%Y-%m-%dT%H:%M:%S' if 'T' in start else '%Y-%m-%d'
start = datetime.datetime.strptime(start, fmt)
yield (event.uid.value, start, event.title.text)
# Our cached view of the calendar, updated periodically.
events = []
# Unique keys for events we've already sent, so we don't remind twice.
sent = set()
def send_reminders():
global sent
messages = []
keys = set()
now = datetime.datetime.now()
for uid, start, title in events:
dt = start - now
if dt.days == 0 and dt.seconds < 60*options.interval:
# The unique key includes the start time, because of
# repeating events.
key = (uid, start)
if key not in sent:
line = '%s starts at %s' % (title, start.strftime('%H:%M'))
print 'Sending reminder:', line
messages.append(line)
keys.add(key)
if not messages:
return
if len(messages) == 1:
message = 'Reminder: ' + messages[0]
else:
message = 'Reminder:\n\n' + '\n'.join('* ' + m for m in messages)
client.send_message(dict(
type = 'private',
to = options.user,
content = message))
sent |= keys
# Loop forever
for i in itertools.count():
try:
# We check reminders every minute, but only
# download the calendar every 10 minutes.
if not i % 10:
events = list(get_events())
send_reminders()
except:
traceback.print_exc()
time.sleep(60)