131 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #!/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 foo@zulip.com \
 | |
|     --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.user 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)
 | 
