# -*- coding: utf-8 -*- import csv,re,random,time from itertools import izip, izip_longest try: from xml.etree import ElementTree # for Python 2.5 users except ImportError: from elementtree import ElementTree import gdata.calendar.service import gdata.service import atom.service import gdata.calendar import atom import getopt import sys import string import time class examGoogleCal: def __init__(self, password, email): self.departments = set() self.modules = set() self.cal_client = gdata.calendar.service.CalendarService() self.cal_client.email = email self.cal_client.password = password self.cal_client.source = 'Google-Calendar_Python_Sample-1.0' self.cal_client.ProgrammaticLogin() self.deptColours = [] self.colours = ["#A32929","#B1365F","#7A367A","#5229A3","#29527A","#2952A3","#1B887A","#28754E","#0D7813","#88880E","#AB8B00","#BE6D00","#B1440E","#865A5A","#705770", "#4E5D6C","#5A6986","#4A716C","#6E6E41","#8D6F47"] def InsertCalendar(self, title='Exams', description='This calendar contains exam times', time_zone='Europe/London', hidden=False, location='University of Sheffield', color='#2952A3'): """Creates a new calendar using the specified data.""" print 'Creating new calendar with title "%s"' % title calendar = gdata.calendar.CalendarListEntry() calendar.title = atom.Title(text=title) calendar.summary = atom.Summary(text=description) calendar.where = gdata.calendar.Where(value_string=location) calendar.color = gdata.calendar.Color(value=color) calendar.timezone = gdata.calendar.Timezone(value=time_zone) if hidden: calendar.hidden = gdata.calendar.Hidden(value='true') else: calendar.hidden = gdata.calendar.Hidden(value='false') new_calendar = self.cal_client.InsertCalendar(new_calendar=calendar) return new_calendar def _InsertEvent(self, title='Tennis with Beth', content='Meet for a quick lesson', where='On the courts', start_time=None, end_time=None, recurrence_data=None): """Inserts a basic event using either start_time/end_time definitions or gd:recurrence RFC2445 icalendar syntax. Specifying both types of dates is not valid. Note how some members of the CalendarEventEntry class use arrays and others do not. Members which are allowed to occur more than once in the calendar or GData "kinds" specifications are stored as arrays. Even for these elements, Google Calendar may limit the number stored to 1. The general motto to use when working with the Calendar data API is that functionality not available through the GUI will not be available through the API. Please see the GData Event "kind" document: http://code.google.com/apis/gdata/elements.html#gdEventKind for more information""" event = gdata.calendar.CalendarEventEntry() event.title = atom.Title(text=title) event.content = atom.Content(text=content) event.where.append(gdata.calendar.Where(value_string=where)) if recurrence_data is not None: # Set a recurring event event.recurrence = gdata.calendar.Recurrence(text=recurrence_data) else: if start_time is None: # Use current time for the start_time and have the event last 1 hour start_time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()) end_time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime(time.time() + 3600)) event.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time)) new_event = self.cal_client.InsertEvent(event, '/calendar/feeds/otk9e3141o9desfrf39op6rod8%40group.calendar.google.com/private/full') return new_event def InsertSingleEvent(self, title='One-time Tennis with Beth', content='Meet for a quick lesson', where='On the courts', start_time=None, end_time=None): """Uses the _InsertEvent helper method to insert a single event which does not have any recurrence syntax specified.""" new_event = self._InsertEvent(title, content, where, start_time, end_time, recurrence_data=None) print 'New single event inserted: %s' % (new_event.id.text,) print '\tEvent edit URL: %s' % (new_event.GetEditLink().href,) print '\tEvent HTML URL: %s' % (new_event.GetHtmlLink().href,) return new_event def parseCSV(self,filename): exams = [] months = {"January":"01", "February":"02", "March":"03", "April":"04", "May":"05", "June":"06", "July":"07", "August":"08", "September":"09", "October":"10", "November":"11", "December":"12" } deptRE = re.compile('[A-Z][A-Z]*') modCodeRE = re.compile('^[A-Z][A-Z]*[0-9][0-9]*$') reader = csv.reader(open(filename), delimiter=';') for row in reader: if modCodeRE.match(row[3]): date = row[0].split() month = months[date[1]] day = date[0] gcalTimeStart = "2009-%s-%sT%s:00.000Z" % (month, day, row[4]) gcalTimeEnd = "2009-%s-%sT%s:00.000Z" % (month, day, row[2]) exam = { "module":row[3], "title":row[5], "start":gcalTimeStart, "end":gcalTimeEnd, "date":row[0], "day":row[1], "location":row[6], "department":deptRE.match(row[3]).group() } exams.append(exam) self.modules.add(row[3]) self.departments.add(deptRE.match(row[3]).group()) return exams def PrintOwnCalendars(self): """Retrieves the list of calendars to which the authenticated user owns -- Although we are only printing the title of the calendar in this case, other information, including the color of the calendar, the timezone, and more. See CalendarListEntry for more details on available attributes.""" feed = self.cal_client.GetOwnCalendarsFeed() print 'Printing owncalendars: %s' % feed.title.text for i, a_calendar in zip(xrange(len(feed.entry)), feed.entry): print '\t%s. %s' % (i, a_calendar.title.text,) def addCalendars(self): colourDepts = [] depts = list(self.departments) colours = self.colours j = 0 for i in range(len(depts)): j = j+1 if j == len(colours): j = 0 desc = "The exam timetable for the %s department" % (depts[i]) colourDepts.append((depts[i],colours[j])) #self.InsertCalendar(depts[i],desc,'Europe/London',False,'University of Sheffield',colours[j]) return colourDepts def run(self,filename): exams = self.parseCSV(filename) #print exams #self.PrintOwnCalendars() #self.colourDepts = self.addCalendars() for exam in exams: try: self.InsertSingleEvent(exam["module"], exam["title"], exam["location"], exam["start"], exam["end"]) except gdata.service.RequestError: print "Oh dear" time.sleep(3) self.InsertSingleEvent(exam["module"], exam["title"], exam["location"], exam["start"], exam["end"]) def main(): test = examGoogleCal() test.run("scraped_items.csv") if __name__ == '__main__': main()