Skip to content

Instantly share code, notes, and snippets.

@moshen
Created August 9, 2011 18:27
Show Gist options
  • Save moshen/1134810 to your computer and use it in GitHub Desktop.
Save moshen/1134810 to your computer and use it in GitHub Desktop.
#!python
# This monstrosity was created to sync events from my Work calendar ical feed to a google calendar
# Google Calendar already supports ical feeds you say? Well... it would be nice if they
# updated them every once and awhile.
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
import gdata.calendar.client
import gdata.calendar
import atom
import getopt
import sys
import string
import time
import re
import urllib2
from icalendar import Calendar, Event
import time
from datetime import date, datetime , timedelta
cal_client = gdata.calendar.client.CalendarClient(source='Google-Calendar_Python-2.0')
cal_client.ClientLogin("username", "password", cal_client.source) # Probably a bad idea
ical_feed = 'http://somefeed'
work_calendar = cal_client.GetCalendarEventFeedUri(calendar='somelonguniquestring@group.calendar.google.com',
visibility='private',
projection='full')
def DateRangeQuery(calendar_client, calendar, start_date, end_date):
query = TryGoogleRequest(gdata.calendar.client.CalendarEventQuery)
query.start_min = start_date
query.start_max = end_date
feed = TryGoogleRequest(calendar_client.GetCalendarEventFeed, q=query, uri=calendar)
return feed
def InsertSingleWorkEvent( calendar_client, calendar, title, content, location, start_time, end_time ):
event = gdata.calendar.data.CalendarEventEntry()
event.title = atom.data.Title(text="%s" % title)
if location is not None:
event.where.append(gdata.calendar.data.CalendarWhere(value=location))
if content is not None:
event.content = atom.data.Content(text=content)
start_time = start_time.strftime('%Y-%m-%dT%H:%M:%S.000Z')
end_time = end_time.strftime('%Y-%m-%dT%H:%M:%S.000Z')
event.when.append(gdata.calendar.data.When(start=start_time, end=end_time))
TryGoogleRequest(calendar_client.InsertEvent, event, calendar)
def TryGoogleRequest( fun, *args, **kwargs ):
ret = None
tries = 0
while tries < 10:
if tries in [4, 8]:
time.sleep(120) # Sometimes it seems to error out if you hit it too fast
try:
ret = fun(*args, **kwargs)
break
except gdata.client.RedirectError as e:
tries += 1
if tries is 10:
raise Exception('Repeatedly failed contacting Google Calendar services')
return ret
start_date = (date.today() - timedelta(days=7)).isoformat()
end_date = (date.today() + timedelta(days=30)).isoformat()
work_cal_feed = DateRangeQuery(cal_client, work_calendar , start_date, end_date)
ical = Calendar.from_string( urllib2.urlopen(ical_feed).read() )
# Remove old work events from the default calendar
print "Removing old events...\n"
for i, an_event in enumerate(work_cal_feed.entry):
print 'Removing event: %s' % (an_event.title.text,)
TryGoogleRequest( cal_client.Delete, an_event )
print "\nRe-Adding events from ical feed...\n"
for component in ical.walk('vevent'):
title = component['summary']
location = None
descr = None
start_date = None
end_date = None
print component['summary']
try:
location = u'{0}'.format(component['location'])
except KeyError:
location = None
try:
descr = u'{0}'.format(component['description'])
except KeyError:
descr = None
try:
start_date = datetime.strptime('{0}'.format(component['dtstart']), "%Y%m%dT%H%M%SZ")
except ValueError:
start_date = datetime.strptime('{0}'.format(component['dtstart']), "%Y%m%d")
try:
end_date = datetime.strptime('{0}'.format(component['dtend']), "%Y%m%dT%H%M%SZ")
except ValueError:
end_date = datetime.strptime('{0}'.format(component['dtend']), "%Y%m%d")
InsertSingleWorkEvent( cal_client, work_calendar, title, descr, location, start_date, end_date )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment