Skip to content

Instantly share code, notes, and snippets.

@logc
Last active June 8, 2017 10:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save logc/f70faf298248d6465890700296e0031f to your computer and use it in GitHub Desktop.
Save logc/f70faf298248d6465890700296e0031f to your computer and use it in GitHub Desktop.
Script to retrieve events from a Google Calendar, check if any of them happens tomorrow earlier than 11AM, and set a reminder in Reminders.app for today at 9PM
#!/usr/bin/env python
"""
Script to retrieve events from a Google Calendar, check if any of them happens
tomorrow earlier than 11AM, and set a reminder in Reminders.app for today at
9PM
"""
import argparse
import datetime
import sys
import os
import applescript
import httplib2
from apiclient import discovery
from dateutil.parser import parse
from dateutil import tz
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
def main():
"""
Gets events for next day and schedules a reminder late in today's evening
if there is an event that starts early.
"""
events = get_next_day_events()
if not events:
print "No events found"
sys.exit(1)
if any_starts_early(events):
create_reminder()
else:
print "No early events found"
sys.exit(0)
def get_next_day_events():
"""
Gets events from Google Calendar API for the next day.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('calendar', 'v3', http=http)
now = datetime.datetime.utcnow().isoformat() + 'Z' # indicates UTC time
next_day = datetime.datetime.utcnow() + datetime.timedelta(hours=48)
next_midnight = next_day.replace(
hour=0, minute=0, second=0, microsecond=0).isoformat() + 'Z'
events_result = service.events().list(
calendarId='primary', timeMin=now, timeMax=next_midnight,
singleEvents=True, orderBy='startTime').execute()
events = events_result.get('items', [])
return events or []
def any_starts_early(events):
"""
Returns True if any of the events starts early.
"""
starts = [parse(event['start'].get('dateTime', event['start'].get('date')))
for event in events]
to_zone = tz.tzlocal()
starts = [s.astimezone(to_zone) for s in starts]
return any(s.hour <= 10 for s in starts)
def create_reminder():
"""
Creates a reminder.
"""
reminders_script = applescript.AppleScript(r'''
tell application "Reminders"
set todayAtNine to (current date)
set hours of todayAtNine to 21
set minutes of todayAtNine to 0
set seconds of todayAtNine to 0
set newremin to make new reminder
set name of newremin to "Check your calendar"
set due date of newremin to todayAtNine
end tell''')
reminders_script.run()
def get_credentials():
"""
Returns valid credentials for the Google Calendar API, whether from a file
or by requesting an OAuth flow.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir, 'calendar-notifier.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
client_secret_file = 'client_secret.json'
scopes = 'https://www.googleapis.com/auth/calendar.readonly'
flow = client.flow_from_clientsecrets(client_secret_file, scopes)
application_name = 'Google Calendar API Notifier'
flow.user_agent = application_name
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
credentials = tools.run_flow(flow, store, flags)
return credentials
if __name__ == '__main__':
main()
@logc
Copy link
Author

logc commented Jun 8, 2017

Requirements

dateutil
google-api-python-client
py-applescript
pyobjc

Schedule

Copy the script to somewhere in your path and then from a root terminal issue:

# cat << EOF >> /etc/crontab
> 00 17 * * * <your_user> calendar_reminder.py
> EOF

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment