Spike

drfloob.com

About

My name is AJ, and I'm a web developer and software engineer out of Southern California.

If you're interested in hiring me, take a look at my portfolio and send me an email

CSULB Registration Deadlines: Google Calendar

Finding the registration deadlines took minutes, both times I've tried to do it. Seems to be a common problem, so here's my solution.
The solution

CSULB Registration Dates: Google Calendar iCal Link

That link can be added into Google Calendar (or any other calendaring app that supports iCal format), and contains all the registration dates from the CSULB Key Dates and Deadlines page for Fall 2009

How I did it

I did consider manually typing all that in, but hell, I'm a programmer. Two hours later, I had this non-pythonic bit of python that scraped the page and created new Events in my public calendar. For anyone interested, here's my quick script:

 
import urllib2, sys
from lxml.html import parse
 
from datetime import datetime
import time
import string
 
import gdata.calendar
import gdata.calendar.service
import atom
 
address = "http://www.csulb.edu/depts/enrollment/dates/registration.html"
 
myEmail = 'MY_ACCOUNT'
myPassword = 'MY_PASSWORD'
myFeed = 'MY_PRIVATE_FEED_URL'
 
dateFormat = '%b %d, %Y'
 
def getDates(date):
    """there are three different kinds of dates to parse:
        simple: a single date
        range: a range of dates within a month
        wide-range: a range of dates across months
    """
 
    # type one: simple
    if date.find('-') == -1:
        tstmp = datetime.strptime(date, dateFormat)
        #print "t" + str(tstmp)
        return (tstmp, )
 
    dates = date.split(' - ')
    ds1 = dates[0].split()
    ds2 = dates[1].split()
    # type two: same month in range
    if dates[1].strip()[0] in ('1', '2', '3'):
 
        fromDateStr = ds1[0] + ' ' + ds1[1] + ', ' + ds2[1]
        fromDate = datetime.strptime(fromDateStr, dateFormat)
 
        toDateStr = ds1[0] +  ' ' + ds2[0] + ' ' + ds2[1]
        toDate = datetime.strptime(toDateStr, dateFormat)
 
        return (fromDate, toDate)
    # type three: different months
    else:
 
        fromDateStr = ds1[0] + ' ' + ds1[1] + ', ' + ds2[2]
        fromDate = datetime.strptime(fromDateStr, dateFormat)
 
        toDate = datetime.strptime(dates[1], dateFormat)
 
        return (fromDate, toDate)
 
 
def InsertSingleEvent(calendar_service, title, start_date, end_date=None):
    event = gdata.calendar.CalendarEventEntry()
    event.title = atom.Title(text=title)
    event.content = atom.Content(text=title)
    event.where.append(gdata.calendar.Where(value_string="CSU, Long Beach"))
 
    start_time = start_date.strftime('%Y-%m-%d')
    if end_date is not None:
        end_time = end_date.strftime('%Y-%m-%d')
    else:
        end_time = None
 
    event.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time))
 
    new_event = calendar_service.InsertEvent(event, myFeed)
 
    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
 
 
calendar_service = gdata.calendar.service.CalendarService()
calendar_service.email = myEmail
calendar_service.password = myPassword
calendar_service.source = 'floob's CSULB scraper'
calendar_service.ProgrammaticLogin()
 
doc = parse(address).getroot()
for tr in doc.cssselect('table#dplCalFall2009 tr')[1:]:
 
    title=""
    date=""
 
    # filter out header
 
    for th in tr.iterchildren('th'):
        for elem in th.itertext():
            title += elem
    print title
 
    for td in tr.iterchildren('td'):
        for elem in td.itertext():
            date += elem
    print date
 
    if date == "":
        continue
 
    dates = getDates(date)
 
    InsertSingleEvent(calendar_service, title, *dates)
 

A pint of beer to the coder who will show the most elegant, pythonic rewrite of this code! Coder must live in southern california. all rights reserved, some restrictions apply, you may enter as many times as you'd like