Checking your final grades at Auburn...automatically!!!

During finals week, I found myself constantly checking the Auburn University site to see if new grades are posted. At the time, I did not know that they actually only post grades at midnight. I ended up using Python, BeautifulSoup, and other tools to log in and grab the final grades site, parse for new classes, and then send a push notification if new ones were found. Prowl is the only good push notification app for iOS that I'm aware of. If you are using Android, there exists numerous ones and you can modify as needed. To get this script running, put it in a python (.py) file, and run it through your favorite scheduler. I use launchd on my Mac and cron on Linux. Happy finals and may the curve be ever in your favor!
1:  #!/usr/bin/env python  
2:  from BeautifulSoup import BeautifulSoup  
3:  import mechanize, sys, re, time, shelve  
4:  import prowlpy  
5:    
6:  shelve_file = 'grades.pyshelf'  
7:  apikey = '123khlkjh1l23kjh12l3kjh13lk12hj3lk12jh31lkj3h213lkjh123' #Prowl API Key  
8:  username   = 'tigerid0012'  
9:  password   = 'imsexyandiknowitlalala'  
10:  a_url    = 'https://ssbprod.auburn.edu/pls/PROD/bwskogrd.P_ViewTermGrde'  
11:    
12:  def get_html(username, password):  
13:    br = mechanize.Browser()  
14:    br.open(a_url)  
15:    br.select_form('loginform')  
16:    br['sid']  = username  
17:    br['PIN']  = password  
18:    br.submit();  
19:    br.open(a_url)  
20:    br.select_form(nr=1)  
21:    response   = br.submit()  
22:    return response.read()  
23:  ####  
24:    
25:  def parse_grades(html_doc):  
26:    grades = {}  
27:    soup = BeautifulSoup(html_doc)  
28:    for item in soup.body.find('table', { "class" : "datadisplaytable", "summary" : re.compile('This table displays the final\ngrade') }).findAll('tr'):  
29:      if( item.findAll('td', { "class" : "dddefault" }).__len__() > 6):  
30:        ClassTitle = item.findAll('td', { "class" : "dddefault" })[4].getText()  
31:        ClassGrade = item.findAll('td', { "class" : "dddefault" })[6].getText()  
32:        grades[ ClassTitle ] = ClassGrade  
33:        #print ClassTitle.getText() + " " + ClassGrade.getText()  
34:      ####  
35:    ####  
36:    return grades  
37:    #print grades  
38:  ####  
39:    
40:  def sendpush(textmsg):  
41:    p = prowlpy.Prowl(apikey)  
42:    try:  
43:      p.add('New Final Grade',"You have a new grade: "+ textmsg, 1, None)  
44:      print 'Success'  
45:    except Exception,msg:  
46:      print msg  
47:    ####  
48:  ####  
49:    
50:  def main():  
51:    d = shelve.open(shelve_file, flag='c', protocol=None, writeback=True)  
52:    #print dir(d)  
53:    if d.has_key('num_grades'):  
54:      pass  
55:    else:  
56:      d['num_grades'] = 0  
57:    ####  
58:    d['mygrades'] = {}  
59:    print "Checking Grades"  
60:    d['mygradepage']  = get_html(username, password)  
61:    d['new_mygrades'] = parse_grades(d['mygradepage'])  
62:    d['new_numgrades'] = len(d['new_mygrades'].keys())  
63:    if( d['new_numgrades'] > d['num_grades'] ):  
64:      mykeylist = [diffgrades for diffgrades in d['new_mygrades'].keys() if diffgrades not in d['mygrades'].keys()]  
65:      pushstring = "";  
66:      print "New grade:"  
67:      for classtitle in mykeylist:  
68:        stringy = classtitle + " ("+d['new_mygrades'][classtitle]+")\n"  
69:        pushstring = pushstring + stringy  
70:      ####  
71:      sendpush(pushstring)  
72:      print pushstring  
73:    else:  
74:      print "No new grades"  
75:    ####  
76:    d['num_grades'] = d['new_numgrades']  
77:    d['mygrades']  = d['new_mygrades']  
78:    d.sync()  
79:    d.close()  
80:  #### END main()  
81:    
82:  if __name__ == "__main__":  
83:    main()  
84:  #### END if  

Comments

Popular posts from this blog

Using Audacity as an Oscilloscope

Using Google Command Line Tools to post my Computer Systems Notes

Tracking an LED with OpenCV