| [27] | 1 | |
|---|
| 2 | import csv,re,random,time |
|---|
| 3 | from itertools import izip, izip_longest |
|---|
| 4 | try: |
|---|
| 5 | from xml.etree import ElementTree |
|---|
| 6 | except ImportError: |
|---|
| 7 | from elementtree import ElementTree |
|---|
| 8 | import gdata.calendar.service |
|---|
| 9 | import gdata.service |
|---|
| 10 | import atom.service |
|---|
| 11 | import gdata.calendar |
|---|
| 12 | import atom |
|---|
| 13 | import getopt |
|---|
| 14 | import sys |
|---|
| 15 | import string |
|---|
| 16 | import time |
|---|
| 17 | |
|---|
| 18 | class examGoogleCal: |
|---|
| 19 | |
|---|
| 20 | def __init__(self, password, email): |
|---|
| 21 | self.departments = set() |
|---|
| 22 | self.modules = set() |
|---|
| 23 | self.cal_client = gdata.calendar.service.CalendarService() |
|---|
| 24 | self.cal_client.email = email |
|---|
| 25 | self.cal_client.password = password |
|---|
| 26 | self.cal_client.source = 'Google-Calendar_Python_Sample-1.0' |
|---|
| 27 | self.cal_client.ProgrammaticLogin() |
|---|
| 28 | |
|---|
| 29 | self.deptColours = [] |
|---|
| 30 | self.colours = ["#A32929","#B1365F","#7A367A","#5229A3","#29527A","#2952A3","#1B887A","#28754E","#0D7813","#88880E","#AB8B00","#BE6D00","#B1440E","#865A5A","#705770", |
|---|
| 31 | "#4E5D6C","#5A6986","#4A716C","#6E6E41","#8D6F47"] |
|---|
| 32 | |
|---|
| 33 | def InsertCalendar(self, title='Exams', |
|---|
| 34 | description='This calendar contains exam times', |
|---|
| 35 | time_zone='Europe/London', hidden=False, location='University of Sheffield', |
|---|
| 36 | color='#2952A3'): |
|---|
| 37 | """Creates a new calendar using the specified data.""" |
|---|
| 38 | print 'Creating new calendar with title "%s"' % title |
|---|
| 39 | calendar = gdata.calendar.CalendarListEntry() |
|---|
| 40 | calendar.title = atom.Title(text=title) |
|---|
| 41 | calendar.summary = atom.Summary(text=description) |
|---|
| 42 | calendar.where = gdata.calendar.Where(value_string=location) |
|---|
| 43 | calendar.color = gdata.calendar.Color(value=color) |
|---|
| 44 | calendar.timezone = gdata.calendar.Timezone(value=time_zone) |
|---|
| 45 | |
|---|
| 46 | if hidden: |
|---|
| 47 | calendar.hidden = gdata.calendar.Hidden(value='true') |
|---|
| 48 | else: |
|---|
| 49 | calendar.hidden = gdata.calendar.Hidden(value='false') |
|---|
| 50 | |
|---|
| 51 | new_calendar = self.cal_client.InsertCalendar(new_calendar=calendar) |
|---|
| 52 | return new_calendar |
|---|
| 53 | |
|---|
| 54 | def _InsertEvent(self, title='Tennis with Beth', |
|---|
| 55 | content='Meet for a quick lesson', where='On the courts', |
|---|
| 56 | start_time=None, end_time=None, recurrence_data=None): |
|---|
| 57 | """Inserts a basic event using either start_time/end_time definitions |
|---|
| 58 | or gd:recurrence RFC2445 icalendar syntax. Specifying both types of |
|---|
| 59 | dates is not valid. Note how some members of the CalendarEventEntry |
|---|
| 60 | class use arrays and others do not. Members which are allowed to occur |
|---|
| 61 | more than once in the calendar or GData "kinds" specifications are stored |
|---|
| 62 | as arrays. Even for these elements, Google Calendar may limit the number |
|---|
| 63 | stored to 1. The general motto to use when working with the Calendar data |
|---|
| 64 | API is that functionality not available through the GUI will not be |
|---|
| 65 | available through the API. Please see the GData Event "kind" document: |
|---|
| 66 | http://code.google.com/apis/gdata/elements.html#gdEventKind |
|---|
| 67 | for more information""" |
|---|
| 68 | |
|---|
| 69 | event = gdata.calendar.CalendarEventEntry() |
|---|
| 70 | event.title = atom.Title(text=title) |
|---|
| 71 | event.content = atom.Content(text=content) |
|---|
| 72 | event.where.append(gdata.calendar.Where(value_string=where)) |
|---|
| 73 | |
|---|
| 74 | if recurrence_data is not None: |
|---|
| 75 | |
|---|
| 76 | event.recurrence = gdata.calendar.Recurrence(text=recurrence_data) |
|---|
| 77 | else: |
|---|
| 78 | if start_time is None: |
|---|
| 79 | |
|---|
| 80 | start_time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', time.gmtime()) |
|---|
| 81 | end_time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z', |
|---|
| 82 | time.gmtime(time.time() + 3600)) |
|---|
| 83 | event.when.append(gdata.calendar.When(start_time=start_time, |
|---|
| 84 | end_time=end_time)) |
|---|
| 85 | |
|---|
| 86 | new_event = self.cal_client.InsertEvent(event, |
|---|
| 87 | '/calendar/feeds/otk9e3141o9desfrf39op6rod8%40group.calendar.google.com/private/full') |
|---|
| 88 | |
|---|
| 89 | return new_event |
|---|
| 90 | |
|---|
| 91 | def InsertSingleEvent(self, title='One-time Tennis with Beth', |
|---|
| 92 | content='Meet for a quick lesson', where='On the courts', |
|---|
| 93 | start_time=None, end_time=None): |
|---|
| 94 | """Uses the _InsertEvent helper method to insert a single event which |
|---|
| 95 | does not have any recurrence syntax specified.""" |
|---|
| 96 | |
|---|
| 97 | new_event = self._InsertEvent(title, content, where, start_time, end_time, |
|---|
| 98 | recurrence_data=None) |
|---|
| 99 | |
|---|
| 100 | print 'New single event inserted: %s' % (new_event.id.text,) |
|---|
| 101 | print '\tEvent edit URL: %s' % (new_event.GetEditLink().href,) |
|---|
| 102 | print '\tEvent HTML URL: %s' % (new_event.GetHtmlLink().href,) |
|---|
| 103 | |
|---|
| 104 | return new_event |
|---|
| 105 | |
|---|
| 106 | def parseCSV(self,filename): |
|---|
| 107 | exams = [] |
|---|
| 108 | months = {"January":"01", |
|---|
| 109 | "February":"02", |
|---|
| 110 | "March":"03", |
|---|
| 111 | "April":"04", |
|---|
| 112 | "May":"05", |
|---|
| 113 | "June":"06", |
|---|
| 114 | "July":"07", |
|---|
| 115 | "August":"08", |
|---|
| 116 | "September":"09", |
|---|
| 117 | "October":"10", |
|---|
| 118 | "November":"11", |
|---|
| 119 | "December":"12" |
|---|
| 120 | } |
|---|
| 121 | deptRE = re.compile('[A-Z][A-Z]*') |
|---|
| 122 | modCodeRE = re.compile('^[A-Z][A-Z]*[0-9][0-9]*$') |
|---|
| 123 | reader = csv.reader(open(filename), delimiter=';') |
|---|
| 124 | for row in reader: |
|---|
| 125 | if modCodeRE.match(row[3]): |
|---|
| 126 | date = row[0].split() |
|---|
| 127 | month = months[date[1]] |
|---|
| 128 | day = date[0] |
|---|
| 129 | gcalTimeStart = "2009-%s-%sT%s:00.000Z" % (month, day, row[4]) |
|---|
| 130 | gcalTimeEnd = "2009-%s-%sT%s:00.000Z" % (month, day, row[2]) |
|---|
| 131 | exam = { |
|---|
| 132 | "module":row[3], |
|---|
| 133 | "title":row[5], |
|---|
| 134 | "start":gcalTimeStart, |
|---|
| 135 | "end":gcalTimeEnd, |
|---|
| 136 | "date":row[0], |
|---|
| 137 | "day":row[1], |
|---|
| 138 | "location":row[6], |
|---|
| 139 | "department":deptRE.match(row[3]).group() |
|---|
| 140 | } |
|---|
| 141 | exams.append(exam) |
|---|
| 142 | self.modules.add(row[3]) |
|---|
| 143 | self.departments.add(deptRE.match(row[3]).group()) |
|---|
| 144 | return exams |
|---|
| 145 | |
|---|
| 146 | def PrintOwnCalendars(self): |
|---|
| 147 | """Retrieves the list of calendars to which the authenticated user |
|---|
| 148 | owns -- |
|---|
| 149 | Although we are only printing the title of the |
|---|
| 150 | calendar in this case, other information, including the color of the |
|---|
| 151 | calendar, the timezone, and more. See CalendarListEntry for more details |
|---|
| 152 | on available attributes.""" |
|---|
| 153 | |
|---|
| 154 | feed = self.cal_client.GetOwnCalendarsFeed() |
|---|
| 155 | print 'Printing owncalendars: %s' % feed.title.text |
|---|
| 156 | for i, a_calendar in zip(xrange(len(feed.entry)), feed.entry): |
|---|
| 157 | print '\t%s. %s' % (i, a_calendar.title.text,) |
|---|
| 158 | |
|---|
| 159 | def addCalendars(self): |
|---|
| 160 | colourDepts = [] |
|---|
| 161 | depts = list(self.departments) |
|---|
| 162 | colours = self.colours |
|---|
| 163 | j = 0 |
|---|
| 164 | for i in range(len(depts)): |
|---|
| 165 | j = j+1 |
|---|
| 166 | if j == len(colours): |
|---|
| 167 | j = 0 |
|---|
| 168 | desc = "The exam timetable for the %s department" % (depts[i]) |
|---|
| 169 | colourDepts.append((depts[i],colours[j])) |
|---|
| 170 | |
|---|
| 171 | return colourDepts |
|---|
| 172 | def run(self,filename): |
|---|
| 173 | exams = self.parseCSV(filename) |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | |
|---|
| 177 | for exam in exams: |
|---|
| 178 | try: |
|---|
| 179 | self.InsertSingleEvent(exam["module"], exam["title"], exam["location"], exam["start"], exam["end"]) |
|---|
| 180 | except gdata.service.RequestError: |
|---|
| 181 | print "Oh dear" |
|---|
| 182 | time.sleep(3) |
|---|
| 183 | self.InsertSingleEvent(exam["module"], exam["title"], exam["location"], exam["start"], exam["end"]) |
|---|
| 184 | def main(): |
|---|
| 185 | test = examGoogleCal() |
|---|
| 186 | test.run("scraped_items.csv") |
|---|
| 187 | if __name__ == '__main__': |
|---|
| 188 | main() |
|---|