Created
October 23, 2011 19:04
-
-
Save andres-erbsen/1307726 to your computer and use it in GitHub Desktop.
Python API for ekool.eu, (supports accessing homework and grades, tested 2011-06-12)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- encoding: utf-8 -*- | |
### Realeased under LGPL-3 | |
### Copyright Andres Erbsen <andres.erbsen@gmail.com> 2011 | |
import urllib2, urllib | |
import time | |
import re | |
import pickle | |
from random import randint | |
logintimeout = 14*60+30 # actually fifteen minutes, but play safe | |
graderegexp = re.compile('\{.*?gradeTypeId.*?\}') | |
homeworkregexp = re.compile('\{institutionId.*?\}') | |
true = True; false = False; null = none = None; authorName2 = 'authorName2' # to parse javascript dicts using eval | |
def today(): | |
"""Today's date in format supported by eschool""" | |
t = time.localtime() | |
return '.'.join(str (i) for i in [t[2], t[1], t[0]]) | |
def randID(): | |
"""Random string for scriptsessionid field""" | |
hex(randint(10000000000**4,20000000000**4)).upper()[2:][:-1][:32] | |
class EschoolSession(): | |
"""Ekooli keskkonnaga suhtlev objekt. Sisselogimine ja hinnete ning | |
koduste ülesannete allalaadmine.""" | |
def __init__(self,userid='', password='', trylogin=True): | |
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor()) | |
urllib2.install_opener(self.opener) | |
self.userid = userid | |
self.password = password | |
self.logintime = 0 | |
self.sessionid = None | |
self.cachefilename = None | |
self.grades = [] | |
self.homework = [] | |
self.newgrades = 0 | |
self.newhomework = 0 | |
if self.userid and self.password and trylogin: | |
self.login() | |
def load_from_cache(self): | |
""" Load grades and homework from cache file""" | |
try: | |
cachefile = open(self.cachefilename, "rb") | |
self.grades, self.newgrades, self.homework, self.newhomework = pickle.load(cachefile) | |
cachefile.close() | |
return True | |
except: | |
return False | |
def save_state(self): | |
"""Save known homeowrk and grades to cache file""" | |
#~ print (self.cachefilename) | |
cachefile = open(self.cachefilename, "wb") | |
pickle.dump((self.grades, self.newgrades, self.homework, self.newhomework), cachefile) | |
cachefile.close() | |
def loggedin(self): | |
""" Test if current user is logged in""" | |
url = 'https://www.ekool.eu/dwr/call/plaincall/userAccountManager.getPersonProfile.dwr' | |
values = {'callCount':'1', | |
'windowName':'', | |
'c0-scriptName':'userAccountManager', | |
'c0-methodName':'getPersonProfile', | |
'c0-id':'0', | |
'c0-param0':'number:1245699430', | |
'c0-param1':'number:0', | |
'c0-param2':'null:null', | |
'batchId':'10', | |
'page':'/index_et.html?r=1305013436487', | |
'httpSessionId':self.sessionid, | |
'scriptSessionId':randID() } | |
response = self.opener.open(url, urllib.urlencode(values)) | |
return (self.userid in response.read()) | |
def login(self,force=False): | |
"""Ensure the user is logged in. esc.longin(True) to relogin""" | |
if not self.userid or not self.password: | |
return False | |
if self.logintime + logintimeout > time.time() and self.loggedin(): | |
return 'Probably still logged in, login(true) to force (re)login' | |
url = 'https://www.ekool.eu/dwr/call/plaincall/userAccountManager.loginUserWithPassword.dwr' | |
values = {'windowName' : '', | |
'callCount' : '1', | |
'c0-scriptName' : 'userAccountManager', | |
'c0-methodName' : 'loginUserWithPassword', | |
'c0-id':'0', | |
'c0-param0':self.userid, | |
'c0-param1':self.password, | |
'batchId':'3', | |
'page':'', | |
'httpSessionId':'', | |
'scriptSessionId': randID() } | |
response = self.opener.open(url, urllib.urlencode(values)) | |
self.sessionid = self.opener.handlers[-2].cookiejar._cookies['www.ekool.eu']['/']['JSESSIONID'].value | |
return self.loggedin() | |
def logout(self): | |
if not self.logintime or not self.sessionid: | |
return | |
self.logintime = 0 | |
self.sessionid = '' | |
url = 'https://www.ekool.eu/dwr/call/plaincall/userAccountManager.invalidateSession.dwr' | |
values = {'callCount':'1', | |
'windowName':'', | |
'c0-scriptName':'userAccountManager', | |
'c0-methodName':'invalidateSession', | |
'c0-id':'0', | |
'batchId':'12', | |
'page':'/index_et.html?r=1305013436487', | |
'httpSessionId':self.sessionid, | |
'scriptSessionId':randID() } | |
response = self.opener.open(url, urllib.urlencode(values)) | |
def updategrades(self): | |
"""Download new grade data, add to grades list and mark down if | |
there are unseen grades""" | |
if not self.loggedin(): | |
self.login() | |
if not self.loggedin(): | |
self.logout() | |
return False | |
url = 'https://www.ekool.eu/dwr/call/plaincall/dashboardManager.getDashboardData.dwr' | |
values = {'windowName' : '', | |
'callCount' : '1', | |
'c0-scriptName' : 'dashboardManager', | |
'c0-methodName' : 'getDashboardData', | |
'c0-id':'0', | |
'c0-e1':'string:'+today(), | |
'c0-param0':'number:1245699430', | |
'c0-e2' : 'null:null', | |
'c0-param1':'number:0', | |
'c0-param2':'null:null', | |
'c0-param3':'null:null', | |
'c0-param4':'boolean:false', | |
'c0-param5':'boolean:false', | |
'batchId':'3', | |
'page':'/index_et.html', | |
'httpSessionId': self.sessionid, | |
'scriptSessionId':randID(), } | |
dashboard = self.opener.open(url, urllib.urlencode(values)) | |
for gradestring in reversed(graderegexp.findall(dashboard.read())): | |
try: | |
grade = eval(gradestring.decode('string-escape')) | |
for key in grade: | |
try: grade[key] = grade[key].decode('unicode-escape').strip() | |
except: pass | |
#~ for key in grade: print key, ':', grade[key] | |
if grade not in self.grades: | |
self.grades.append(grade) | |
self.newgrades += 1 | |
except: break | |
return True | |
def updatehomework(self): | |
"""Download new homework data, add to homework list and mark down if | |
there are unseen tasks""" | |
if not self.loggedin(): | |
self.login() | |
if not self.loggedin(): | |
self.logout() | |
return False | |
url = 'https://www.ekool.eu/dwr/call/plaincall/todoManager.getMyTodo.dwr' | |
values = {'windowName' : '', | |
'callCount' : '1', | |
'c0-scriptName' : 'todoManager', | |
'c0-methodName' : 'getMyTodo', | |
'c0-id':'0', | |
'c0-e1':'string:'+today(), | |
'c0-param0':'Object_Object:{date:reference:c0-e1}', | |
'c0-e2' : 'null:null', | |
'c0-param1':'Object_Object:{date:reference:c0-e2}', | |
'c0-param2':'null:null', | |
'c0-param3':'null:null', | |
'c0-param4':'null:null', | |
'batchId':'7', | |
'page':'/index_et.html', | |
'httpSessionId': self.sessionid, | |
'scriptSessionId':randID(), } | |
homeworkpage = self.opener.open(url, urllib.urlencode(values)) | |
for taskstring in homeworkregexp.findall(homeworkpage.read()): | |
taskstring2 = taskstring.replace(',id:',',"id":') | |
for key in re.findall(r'[\{,].*?:',taskstring): | |
if not key[1:-1].isalnum(): | |
continue | |
taskstring2 = taskstring2.replace(key,key[0]+'"'+key[1:-1]+'"'+key[-1]) | |
#~ print taskstring2 | |
task = eval(taskstring2) | |
for key in task: | |
try: task[key] = task[key].decode('unicode-escape').strip() | |
except: pass | |
if task not in self.homework: | |
self.homework.append(task) | |
self.newhomework +=1 | |
return True |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Interesting! Would you be interested in making a small documentation of this?