banker
Version:
Downloads transactions and balances from online banking websites using Zombie.js.
168 lines (128 loc) • 4.31 kB
JavaScript
var events = require('events'),
util = require('util'),
utils = require('../utils');
function BankSession(config) {
var self = this;
self.config = config;
events.EventEmitter.call(this);
if (!self.config.doesNotUseZombie) {
// Delay require until needed, this loads a bunch of stuff
var zombie = require('zombie');
self.browser = new zombie({
silent : true // Don't display JavaScript errors to stderr
});
self.browser.on('response', function(request, response) {
self.browser.response = response;
});
self.browser.onalert(function(message) {
self.browser.alertMessage = message;
});
}
self.loggedIn = false;
}
BankSession.create = function(config) {
var driver = config.driver || config.bankName,
Session = require('./' + driver);
if (Session.doesNotUseZombie) {
config.doesNotUseZombie = true;
}
return new Session(config);
};
BankSession.suicideTimer = 10 * 60 * 1000;
BankSession.suicide = function() {
console.error(
'No activity in last %d seconds; exiting',
BankSession.suicideTimer / 1000);
process.exit(9);
};
util.inherits(BankSession, events.EventEmitter);
BankSession.prototype.log = function(message) {
var self = this;
self.emit('log', self.config.bankName + ': ' + message);
clearTimeout(BankSession.suicideWatch);
BankSession.suicideWatch =
setTimeout(BankSession.suicide, BankSession.suicideTimer);
};
BankSession.prototype.debug = function(type, value) {
var self = this;
self.emit('debug', type, value);
};
BankSession.prototype.wait = function(cb) {
var self = this;
var args = arguments;
self.browser.wait(function() {
setTimeout(function() {
cb.apply(self, args);
}, self.waitOptions.timeout || 500);
});
};
BankSession.prototype.pageLoaded = function(pageName, cb) {
var self = this;
// If the page hasn't loaded yet, document.documentElement will be null.
if (!self.browser.document || !self.browser.document.documentElement) {
cb(new Error(util.format(
"Failed to load page '%s'.",
pageName)));
return false;
}
if (self.config.debugBrowser) {
self.debug('browser', {
pageName : pageName,
raw : (self.browser.response
? self.browser.response.body
: '(no response captured)'),
parsed : self.browser.html()
});
}
return true;
};
BankSession.prototype.destroy = function() {
var self = this;
if (self.browser) {
self.browser.destroy();
}
};
BankSession.prototype.getBalance = function(el) {
var self = this;
return utils.decimal(self.browser.text(el));
};
BankSession.prototype.enableImages = function(handleImage, doRequest, cb) {
var self = this;
var oldFeatures = self.browser.features;
self.browser.features =
self.browser.features.replace(/\bno-img\b/, 'img');
function handleResponse(request, response) {
if (/^image[\/]/i.test(response.headers['content-type'])) {
handleImage(request, response);
}
}
self.browser.on('response', handleResponse);
doRequest(function() {
self.browser.removeListener('response', handleResponse);
self.browser.features = oldFeatures;
cb.apply(self, arguments);
});
};
BankSession.prototype.makeTransactionId = function(transaction) {
return [
(transaction.date || transaction.datePosted).format('YYYY-MM-DD'),
transaction.type || '',
transaction.description || '',
transaction.memo || '',
transaction.amount.toString()
].join('|');
};
// Any implementation of BankSession must implement the following functions.
BankSession.prototype.info = function() {
throw new Error('No information for this bank.');
};
BankSession.prototype.login = function() {
throw new Error('Not implemented');
};
BankSession.prototype.getTransactions = function() {
throw new Error('Not implemented');
};
BankSession.prototype.logout = function() {
throw new Error('Not implemented');
};
module.exports = BankSession;