# HG changeset patch # User Daniel O'Connor # Date 1497680963 -34200 # Node ID 4b6c811e77dfc8f743a67f1013404a461341c855 # Parent a53f90508a06a3b4644cfb468856db7b0bfc7d62 Save & load session cookie so we don't have to reauth every time. It seems even successful auth attemps are rate limited and get a 503. diff -r a53f90508a06 -r 4b6c811e77df adslstats.py --- a/adslstats.py Thu Jun 15 15:07:01 2017 +0930 +++ b/adslstats.py Sat Jun 17 15:59:23 2017 +0930 @@ -39,6 +39,7 @@ import mysrp as srp import optparse import os +import os.path import re import requests import rrdtool @@ -51,6 +52,7 @@ conf.set('global', 'username', 'admin') conf.set('global', 'password', 'admin') conf.set('global', 'name', '10.0.2.14') +conf.set('global', 'cookiejar', os.path.expanduser('~/.adslstats.cj')) conflist = ['adslstats.ini'] if ('HOME' in os.environ): @@ -100,15 +102,32 @@ stats = DSLStats() parser = ConfigParser.ConfigParser() base = 'http://%s' % (conf.get('global', 'name')) + br = mechanize.Browser() + #br.set_debug_http(True) + #br.set_debug_responses(True) + #br.set_debug_redirects(True) + cj = mechanize.LWPCookieJar() + if os.path.exists(conf.get('global', 'cookiejar')): + cj.load(conf.get('global', 'cookiejar'), ignore_discard = True) + br.set_cookiejar(cj) + if not fillstats(br, base, stats): + if not authenticate(br, base, conf.get('global', 'username'), conf.get('global', 'password')): + print('login failed') + return None + print('login succeeded, getting stats') + fillstats(br, base, stats) + cj.save(conf.get('global', 'cookiejar'), ignore_discard = True) + return stats + +def authenticate(br, base, username, password): # Connect and authenticate - br = mechanize.Browser() r = br.open(base) bs = bs4.BeautifulSoup(r) token = bs.head.find(lambda tag: tag.has_attr('name') and tag['name'] == 'CSRFtoken')['content'] #print('Got CSRF token ' + token) - usr = srp.User(conf.get('global', 'username'), conf.get('global', 'password'), hash_alg = srp.SHA256, ng_type = srp.NG_2048) + usr = srp.User(username, password, hash_alg = srp.SHA256, ng_type = srp.NG_2048) uname, A = usr.start_authentication() req = mechanize.Request(base + '/authenticate', data = urllib.urlencode({'CSRFtoken' : token, 'I' : uname, 'A' : binascii.hexlify(A)})) @@ -125,11 +144,15 @@ usr.verify_session(binascii.unhexlify(j['M'])) if not usr.authenticated(): print('Failed to authenticate') - return None + return False + return True +def fillstats(br, base, stats): # Fetch stats and parse r = br.open(base + '/modals/broadband-bridge-modal.lp') bs = bs4.BeautifulSoup(r) + if bs.find('div', 'login') != None: + return False # Helper function to extract data def getvals(bs, text): @@ -161,7 +184,7 @@ else: stats.uptime = reduce(lambda a, b: a + b, map(lambda a: int(a[0]) * a[1], zip(uptime, mults))) - return stats + return True # Setup RRD # We expect data to be logged every 5 minutes