[pyKoL-users] SF.net SVN: pykol: [4]
Brought to you by:
scelis
From: <mi...@us...> - 2007-03-31 19:51:56
|
Revision: 4 http://pykol.svn.sourceforge.net/pykol/?rev=4&view=rev Author: misza13 Date: 2007-03-31 12:51:56 -0700 (Sat, 31 Mar 2007) Log Message: ----------- Encapsulating site-related methods into a single class. Modified Paths: -------------- login.py Added Paths: ----------- kolsite.py Added: kolsite.py =================================================================== --- kolsite.py (rev 0) +++ kolsite.py 2007-03-31 19:51:56 UTC (rev 4) @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- + +import re, urllib, httplib + +try: + import hashlib + new_md5 = hashlib.md5 +except ImportError: #Old python? + import md5 + new_md5 = md5.md5 + + +def urlEncode(query): + """This can encode a query so that it can be sent as a query using + a http POST request""" + if not query: + return None + l = [] + for key, value in query.iteritems(): + key = urllib.quote(key) + value = urllib.quote(value) + l.append(key + '=' + value) + return '&'.join(l) + + +def challengePassword(challenge,password): + m = new_md5() + m.update(password) + hashedpw = m.hexdigest() + m = new_md5() + m.update(hashedpw+':'+challenge) + return m.hexdigest() + + +class LoginError: + def __init__(self,reason='None'): + self.reason = reason + + def __repr__(self): + return 'LoginError{%s}' % self.reason + + +class KoLSite: + def __init__(self, hostname): + self.hostname = hostname + self.cookie = '' + + + def getPage(self, address, data=''): + #print 'Getting %s...' % address + conn = httplib.HTTPConnection(self.hostname) + + conn.putrequest('GET', '/' + address) + #conn.putheader('Cookie', self.cookie) + conn.endheaders() + conn.send('') + + response = conn.getresponse() + data = response.read().decode('utf-8') + conn.close() + return response, data + + + def postForm(self, address, formdata): + data = urlEncode(formdata) + return self.postData(address, data) + + + def postData(self, address, data=''): + conn = httplib.HTTPConnection(self.hostname) + + conn.putrequest('POST', '/' + address) + conn.putheader('Content-Length', str(len(data))) + #conn.putheader('Content-type', 'application/x-www-form-urlencoded') + conn.endheaders() + conn.send(data) + + response = conn.getresponse() + data = response.read().decode('utf-8') + conn.close() + return response, data + + + def doLogin(self, nick, password): + challenge = self.getChallenge() + #print 'Challenge: "%s"' % challenge + + formFields = {} + formFields['loggingin'] = 'Yup.' + formFields['loginname'] = nick + formFields['challenge'] = challenge + formFields['response'] = challengePassword(challenge,password) + #formFields['password'] = password + formFields['secure'] = '1' + + print 'Now logging in...' + response, data = self.postForm('login.php',formFields) + + if response.status == 302: + self.cookie = response.getheader('set-cookie') + return + + #print response.status + if re.search('Bad password.',data): + raise LoginError, 'Bad password.' + elif re.search('Too many login failures from this IP.',data): + raise LoginError, 'Too many login failures from this IP.' + elif re.search('Too many login attempts',data): + raise LoginError, 'Too many login attempts.' + else: + raise LoginError, data + + + def getChallenge(self): + print 'Getting login challenge...' + response, data = self.getPage('login.php') + challenge = re.search('<input type=hidden name=challenge value="([0-9a-f]+)">',data) + if challenge: + return challenge.group(1) + else: + return '' Modified: login.py =================================================================== --- login.py 2007-03-31 19:04:25 UTC (rev 3) +++ login.py 2007-03-31 19:51:56 UTC (rev 4) @@ -1,134 +1,13 @@ # -*- coding: utf-8 -*- -import re -import urllib, httplib +from kolsite import KoLSite -try: - import hashlib - new_md5 = hashlib.md5 -except ImportError: #Old python? - import md5 - new_md5 = md5.md5 - -class LoginError: - def __init__(self,reason='None'): - self.reason = reason - - def __repr__(self): - return 'LoginError{%s}' % self.reason - - -def urlEncode(query): - """This can encode a query so that it can be sent as a query using - a http POST request""" - if not query: - return None - l = [] - for key, value in query.iteritems(): - key = urllib.quote(key) - value = urllib.quote(value) - l.append(key + '=' + value) - return '&'.join(l) - - -def postForm(hostname, address, predata): - data = urlEncode(predata) - return postData(hostname, address, data) - - -def postData(hostname, address, data, contentType = 'application/x-www-form-urlencoded'): - conn = httplib.HTTPConnection(hostname) - - conn.putrequest('POST', address) - conn.putheader('Content-Length', str(len(data))) - conn.putheader('Content-type', contentType) - conn.endheaders() - conn.send(data) - - response = conn.getresponse() - data = response.read().decode('utf-8') - conn.close() - return response, data - - -def getChallenge(hostname): - print 'Getting login challenge...' - txt = urllib.urlopen('http://'+hostname+'/login.php').read() - challenge = re.search('<input type=hidden name=challenge value="([0-9a-f]+)">',txt) - if challenge: - return challenge.group(1) - else: - return '' - - -def challengePassword(challenge,password): - m = new_md5() - m.update(password) - hashedpw = m.hexdigest() - m = new_md5() - m.update(hashedpw+':'+challenge) - return m.hexdigest() - - -def doLogin(hostname, nick, password): - challenge = getChallenge(hostname) - #print 'Challenge: "%s"' % challenge - - formFields = {} - formFields['loggingin'] = 'Yup.' - formFields['loginname'] = nick - formFields['challenge'] = challenge - formFields['response'] = challengePassword(challenge,password) - #formFields['password'] = password - formFields['secure'] = '1' - - print 'Now logging in...' - response, data = postForm(hostname,'/login.php',formFields) - - if response.status == 302: - return response.getheader('set-cookie') - - print response.status - if re.search('Bad password.',data): - raise LoginError, 'Bad password.' - elif re.search('Too many login failures from this IP.',data): - raise LoginError, 'Too many login failures from this IP.' - elif re.search('Too many login attempts',data): - raise LoginError, 'Too many login attempts.' - else: - print data - raise LoginError, '' - - -def getMain(hostname, cookie): - return getPage(hostname,'/main.html',cookie) - - -def getCharSheet(hostname, cookie): - return getPage(hostname,'/charsheet.php',cookie) - - -def getMain(hostname, page, cookie): - print 'Getting %s...' % page - conn = httplib.HTTPConnection(hostname) - - conn.putrequest('GET', page) - conn.putheader('Cookie', cookie) - conn.endheaders() - conn.send('') - - response = conn.getresponse() - data = response.read().decode('utf-8') - conn.close() - return response, data - - if __name__ == '__main__': - HOSTNAME = 'www.kingdomofloathing.com' + Site = KoLSite('www.kingdomofloathing.com') config = {} execfile('misha.conf') - cookie = doLogin(HOSTNAME,config['nick'],config['password']) - response, data = getMain(HOSTNAME,cookie) + cookie = Site.doLogin(config['nick'],config['password']) + response, data = Site.getPage('main.html') print response.status print data This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |