leap-card
Version:
Easily retrieve your Dublin Leap Card informations
188 lines (161 loc) • 6.85 kB
JavaScript
var cheerio = require('cheerio'),
request = require('request').defaults({
jar: true,
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, sdch',
'Accept-Language': 'en-US,en;q=0.8,it;q=0.6',
'Connection': 'keep-alive',
'Host': 'www.leapcard.ie',
'Origin': 'https://www.leapcard.ie',
'Referer': 'https://www.leapcard.ie/en/login.aspx?AspxAutoDetectCookieSupport=1',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36'
}
}),
async = require('async'),
msviewstate = require('ms-viewstate');
var REGEX_CARDS = /<option (?:selected="selected"\s)?value="(\d{6})">(\d{10}) - (.+?)<\/option>/g;
var DETAILS_PREFIX = '#ContentPlaceHolder1_TabContainer2_MyCardsTabPanel_ContentPlaceHolder1_ctrlCardOverViewBODetails_';
var LeapCard = function() {
}
LeapCard.prototype.getCardsInfo = function(username, password, cb) {
LeapCard.prototype._username = username;
LeapCard.prototype._password = password;
async.waterfall([
this._retrieveLoginPage,
this._doLogin,
this._getCardsSummary,
this._getCardsDetails
], cb);
}
LeapCard.prototype._getCardsDetails = function(cards, body, cb) {
var viewState = msviewstate.extractVs(body)
var eventValidation = msviewstate.extractEv(body)
var functions = cards.map(function(card) {
return LeapCard.prototype._getSingleCardDetails.bind(null, card.id, viewState, eventValidation);
});
async.series(functions, function(err, result) {
if(err) {
cb(err);
return;
}
cb(result);
});
};
LeapCard.prototype._getSingleCardDetails = function(id, viewState, eventValidation, cb) {
request.post({
url: LeapCard.prototype.options.summaryUrl,
followAllRedirects: true,
form: {
'__VIEWSTATE': viewState,
'__EVENTVALIDATION': eventValidation,
'__EVENTTARGET': 'ctl00$ctl00$ContentPlaceHolder1$TabContainer2$MyCardsTabPanel$ddlMyCardsList',
'__EVENTARGUMENT': '',
'ctl00$ctl00$AjaxScriptManager': 'tl00$ctl00$ContentPlaceHolder1$TabContainer2$MyCardsTabPanel$UpdatePanel1|ctl00$ctl00$ContentPlaceHolder1$TabContainer2$MyCardsTabPanel$ddlMyCardsList',
'ContentPlaceHolder1_TabContainer2_ClientState': '{"ActiveTabIndex":0,"TabState":[true,true]}',
'__SCROLLPOSITIONX': '0',
'__SCROLLPOSITIONY': '0',
'ctl00$ctl00$ContentPlaceHolder1$TabContainer2$MyCardsTabPanel$ddlMyCardsList': id,
'__ASYNCPOST': 'true'
}
}, function(err, response, body) {
if(err) {
cb(err);
return;
}
request.get(LeapCard.prototype.options.summaryUrl, function (error, response, body) {
if(error) {
cb(error);
return;
}
if(response.statusCode !== 200) {
cb(new Error('Got a '+response.statusCode));
return;
}
$ = cheerio.load(body);
var cardNumber = $(DETAILS_PREFIX+'lblCardNumber').parent().contents().eq(2).text().trim();
var cardLabel = $(DETAILS_PREFIX+'lblCardLabel').parent().contents().eq(2).text().trim();
var cardProfile = $(DETAILS_PREFIX+'lblCardProfile').parent().contents().eq(2).text().trim();
var cardStatus = $(DETAILS_PREFIX+'AccessibleLabel2').parent().contents().eq(2).text().trim();
var cardCreditStatus = $(DETAILS_PREFIX+'Label1').parent().contents().eq(2).text().trim();
var cardAutoTopUp = $(DETAILS_PREFIX+'Label2').parent().contents().eq(2).text().trim();
var cardInitDate = $(DETAILS_PREFIX+'AccessibleLabel4').parent().contents().eq(2).text().trim();
var cardExpiryDate = $(DETAILS_PREFIX+'AccessibleLabel5').parent().contents().eq(2).text().trim();
var cardBalance = $(DETAILS_PREFIX+'lblTravelCreditBalance').parent().contents().eq(2).text().trim();
cb(null, {
number: cardNumber,
label: cardLabel,
profile: cardProfile,
status: cardStatus,
creditStatus: cardCreditStatus,
autoTopUp: cardAutoTopUp,
initDate: cardInitDate,
expiryDate: cardExpiryDate,
balance: cardBalance
});
});
});
}
LeapCard.prototype._getCardsSummary = function(body, cb) {
var results = [];
var search;
while ((search = REGEX_CARDS.exec(body)) !== null) {
results.push({
id: search[1],
cardId: search[2],
name: search[3]
});
}
cb(null, results, body);
}
LeapCard.prototype._doLogin = function(body, cb) {
var viewState = msviewstate.extractVs(body)
var eventValidation = msviewstate.extractEv(body)
request.post({
url: LeapCard.prototype.options.loginUrl,
followAllRedirects: true,
qs: {
'AspxAutoDetectCookieSupport': '1'
},
form: {
'__VIEWSTATE': viewState,
'__EVENTVALIDATION': eventValidation,
//'__PREVIOUSPAGE': 'y2GBSfIbmifdTMHZo_m_YW7AE9Fcqv89Bt67xW-85p2_OBshKNpWeqZFv0jRyg-e-kFSgwKeUQGgtX5XTV5-9nSE55G7w8FNywN3F_mWRk01',
'ctl00$ContentPlaceHolder1$Password': LeapCard.prototype._password,
'ctl00$ContentPlaceHolder1$UserName': LeapCard.prototype._username,
'ctl00$ContentPlaceHolder1$btnlogin': 'Login',
'ctl00$ucSiteSearch$txtSearch': '',
'AjaxScriptManager_HiddenField': '',
'_URLLocalization_Var001': 'False',
'__EVENTTARGET': '',
'__EVENTARGUMENT': '',
'__SCROLLPOSITIONX': '0',
'__SCROLLPOSITIONY': '300'
}
}, function(err, response, body) {
if(err) {
cb(err);
return;
}
cb(null, body);
});
}
LeapCard.prototype._retrieveLoginPage = function(cb) {
request.get(LeapCard.prototype.options.loginUrl, function (error, response, body) {
if(error) {
cb(error);
return;
}
if(response.statusCode !== 200) {
cb(new Error('Got a '+response.statusCode));
return;
}
cb(null, body);
});
}
LeapCard.prototype.leapcard = '[leapcard object]';
LeapCard.prototype.options = {
loginUrl: 'https://www.leapcard.ie/en/login.aspx',
summaryUrl: 'https://www.leapcard.ie/en/SelfServices/CardServices/CardOverView.aspx'
};
module.exports = new LeapCard();