Skip to content

Instantly share code, notes, and snippets.

@wezm
Created July 18, 2009 13:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save wezm/149565 to your computer and use it in GitHub Desktop.
Save wezm/149565 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'nokogiri'
require 'mechanize'
require 'logger'
module BankBalance
class NabFetcher
def fetch(client_number, password)
agent = WWW::Mechanize.new() do |a|
a.log = Logger.new("mech.log")
a.user_agent_alias = 'Mac FireFox'
# http://rubyforge.org/tracker/index.php?func=detail&aid=24950&group_id=1453&atid=5709
a.keep_alive = false # For slow site
end
# puts "Requesting login page"
login_page = agent.get('https://ib.nab.com.au/nabib/index.jsp')
login_form = login_page.form('sf_1')
key = ''
alphabet = ''
sf1_password = 'document\.sf_1\.password\.value'
login_page.search('//script[6]').each do |js|
if js.text =~ /#{sf1_password}=check\(#{sf1_password},"([^"]+)","([^"]+)"\);/
key = $1
alphabet = $2
end
end
login_form.userid = client_number
login_form.password = check(password, key, alphabet)
accounts = []
# puts "Submitting login form"
balances_page = agent.submit(login_form)
balances_page.root.css('table#accountBalances_nonprimary_subaccounts tbody tr').each do |elem|
accounts << {
:name => elem.css('td:first-child').text.strip,
:balance => elem.css('td:last-child').text.strip.gsub(',', '').to_f,
:formatted_balance => elem.css('td:last-child').text.strip.sub(/^(-?)(.*)$/, '\1$\2'),
}
# puts "#{account_name}: #{account_balance}"
end
# Logout, not sure if this is the right path though
# puts "Logging out"
agent.get('https://ib.nab.com.au/nabib/preLogout.ctl')
accounts
end
protected
def check(p, k, a)
# Implementation of the following javascript function
# function check(p, k, a) {
# for (var i=a.length-1;i>0;i--) {
# if (i!=a.indexOf(a.charAt(i))) {
# a=a.substring(0,i)+a.substring(i+1);
# }
# }
# var r=new Array(p.length);
# for (var i=0;i<p.length;i++) {
# r[i]=p.charAt(i);
# var pi=a.indexOf(p.charAt(i));
# if (pi>=0 && i<k.length) {
# var ki=a.indexOf(k.charAt(i));
# if (ki>=0) {
# pi-=ki;
# if (pi<0) pi+=a.length;
# r[i]=a.charAt(pi);
# }
# }
# }
# return r.join("");
# }
# puts "check(password, #{k})"
# 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
# Generate this above as an array of chars
r = []
last_index = p.length - 1
# TODO: Use the passed alphabet instead
alphabet = ('0'..'9').to_a + ('a'..'z').to_a + ('A'..'Z').to_a
(0..last_index).each do |i|
r[i] = p[i,1]
pi = alphabet.index(r[i])
unless pi.nil? or i >= k.length
ki = alphabet.index(k[i,1])
unless ki.nil?
pi -= ki
pi += alphabet.size if pi < 0
r[i] = alphabet[pi]
end
end
end
r.join('')
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment