Skip to content

Instantly share code, notes, and snippets.

@lukeredpath
Created March 10, 2009 14:50
Show Gist options
  • Save lukeredpath/76914 to your computer and use it in GitHub Desktop.
Save lukeredpath/76914 to your computer and use it in GitHub Desktop.
// ==UserScript==
// Version: 1.0
// @name Co-op OFX Download Link
// @description Download co-op internet banking statements in OFX format.
// @namespace http://userscripts.org/scripts/show/6976
// @include https://welcome22.smile.co.uk/SmileWeb/getDomesticStatementPage.do*
// @include https://welcome22.smile.co.uk/SmileWeb/paginateDomesticStatement.do*
// @include https://welcome23.smile.co.uk/SmileWeb/getDomesticStatementPage.do*
// @include https://welcome23.smile.co.uk/SmileWeb/paginateDomesticStatement.do*
// @include https://welcome26.co-operativebank.co.uk/CBIBSWeb/domesticRecentItems*
// @include https://welcome26.co-operativebank.co.uk/CBIBSWeb/balances.do*
// @include https://welcome26.co-operativebank.co.uk/CBIBSWeb/getDomesticStatementPage.do*
// @include https://welcome26.co-operativebank.co.uk/CBIBSWeb/paginateDomesticStatement.do*
// @include https://welcome26.co-operativebank.co.uk/CBIBSWeb/getVisaStatementPage.do*
// @include https://welcome26.co-operativebank.co.uk/CBIBSWeb/visaStatement.do*
// @include https://welcome27.co-operativebank.co.uk/CBIBSWeb/domesticRecentItems*
// @include https://welcome27.co-operativebank.co.uk/CBIBSWeb/balances.do*
// @include https://welcome27.co-operativebank.co.uk/CBIBSWeb/getDomesticStatementPage.do*
// @include https://welcome27.co-operativebank.co.uk/CBIBSWeb/paginateDomesticStatement.do*
// @include https://welcome27.co-operativebank.co.uk/CBIBSWeb/getVisaStatementPage.do*
// @include https://welcome27.co-operativebank.co.uk/CBIBSWeb/visaStatements.do*
// ==/UserScript==
//
// Mostly a rewrite but some borrowed code from Chris B (http://userscripts.org/scripts/show/6976)
var OFXUtils = {
formattedDate: function(_date) {
var temp,_year,_month,_day,_hour,_minute,_second;
_year = _date.getFullYear();
_month = _date.getMonth() + 1;
_day = _date.getDate();
_hour = _date.getHours();
_minute = _date.getMinutes();
_second = _date.getSeconds();
temp = _year;
temp += ((_month < 10) ? "0" : "") + _month;
temp += ((_day < 10) ? "0" : "") + _day;
temp += ((_hour < 10) ? "0" : "") + _hour;
temp += ((_minute < 10) ? "0" : "") + _minute;
temp += ((_second < 10) ? "0" : "") + _second;
return temp;
}
}
var OFXDocument = function(sortCode, accountNumber) {
this.sortCode = sortCode;
this.accountNumber = accountNumber;
this.transactions = [];
}
OFXDocument.prototype = {
toString: function() {
var docString = this.xmlHeader();
for(idx in this.transactions) {
var txn = this.transactions[idx];
docString += this.xmlForTransaction(txn);
}
return docString;
},
addTransaction: function(txn) {
this.transactions.push(txn);
},
transactionsSortedByDate: function() {
return this.transactions.sort(function(txnOne, txnTwo) {
return txnOne.date > txnTwo.date;
})
},
startDate: function() {
return this.transactionsSortedByDate()[this.transactions.length-1].date();
},
endDate: function() {
return this.transactionsSortedByDate()[0].date();
},
// pseudo-private methods
xmlHeader: function() {
return '\n\
<OFX>\n\
<SIGNONMSGSRSV1>\n\
<SONRS>\n\
<STATUS>\n\
<CODE>0</CODE>\n\
<SEVERITY>INFO</SEVERITY>\n\
</STATUS>\n\
<DTSERVER>'+ OFXUtils.formattedDate(new Date) +'</DTSERVER>\n\
<LANGUAGE>ENG</LANGUAGE>\n\
</SONRS>\n\
</SIGNONMSGSRSV1>\n\
<BANKMSGSRSV1>\n\
<STMTTRNRS>\n\
<TRNUID>1</TRNUID>\n\
<STATUS>\n\
<CODE>0</CODE>\n\
<SEVERITY>INFO</SEVERITY>\n\
</STATUS>\n\
<STMTRS>\n\
<CURDEF>GBP</CURDEF>\n\
<BANKACCTFROM>\n\
<BANKID>'+ this.sortCode +'</BANKID>\n\
<ACCTID>'+ this.accountNumber +'</ACCTID>\n\
<ACCTTYPE>CHECKING</ACCTTYPE>\n\
</BANKACCTFROM>\n\
<BANKTRANLIST>\n\
<DTSTART>'+ OFXUtils.formattedDate(this.startDate()) +'</DTSTART>\n\
<DTEND>'+ OFXUtils.formattedDate(this.endDate()) +'</DTEND>';
},
xmlForTransaction: function(txn) {
return '\n\
<STMTTRN>\n\
<TRNTYPE>'+ txn.type() +'</TRNTYPE>\n\
<DTPOSTED>'+ OFXUtils.formattedDate(txn.date()) +'</DTPOSTED>\n\
<TRNAMT>'+ txn.amount() +'</TRNAMT>\n\
<FITID>'+ OFXUtils.formattedDate(txn.date()) +'</FITID>\n\
<NAME>'+ txn.description() +'</NAME>\n\
</STMTTRN>'
}
}
var OFXTransaction = function(data) {
this.data = data;
}
OFXTransaction.prototype = {
date: function() {
date = this.data.date;
return new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0,2));
},
description: function() {
return this.data.description.replace(/\s+/g, ' ').replace(/\n/g, '');
},
type: function() {
if(this.data.deposit.length > 0) {
return 'CREDIT';
} else {
return 'DEBIT';
}
},
amount: function() {
if(this.data.deposit.length > 0) {
return new Number(this.data.deposit.slice(1));
} else {
return new Number(this.data.withdrawal.slice(1)) * -1;
}
}
}
function getElementsByXpath(xpath) {
return document.evaluate(xpath, document,
null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
}
function sortCodeFromHeader(header) {
return header.match(/\d{2}-\d{2}-\d{2}/)[0].replace(/-/g, '');
}
function accountNumberFromHeader(header) {
return header.match(/\d{8}/)[0];
}
function getOfxDocumentfromPage() {
var header = document.getElementsByTagName('h4')[0].textContent;
var transactionCells = getElementsByXpath("//td[@class='dataRowL']");
var ofx = new OFXDocument(sortCodeFromHeader(header), accountNumberFromHeader(header));
for (var i = transactionCells.snapshotLength - 1; i >= 0; i--){
var row = transactionCells.snapshotItem(i).parentNode;
ofx.addTransaction(new OFXTransaction({
date: jQuery.trim(row.childNodes[1].textContent),
description: jQuery.trim(row.childNodes[3].textContent),
deposit: jQuery.trim(row.childNodes[5].textContent),
withdrawal: jQuery.trim(row.childNodes[7].textContent),
balance: jQuery.trim(row.childNodes[9].textContent)
}));
};
return ofx;
}
function displayOfxDocumentInPopup() {
var ofx = getOfxDocumentfromPage();
newWindow = window.open("", "newwin", "height=700, width=500,resizable=yes,scrollbars=yes,toolbar=no,menubar=yes");
newWindow.document.open("text/plain", "replace");
newWindow.document.write(ofx.toString());
newWindow.document.close();
}
function init() {
var link = document.createElement("a");
link.href = '#';
link.textContent = 'Download OFX Statement';
link.addEventListener('click', displayOfxDocumentInPopup, 'false');
link.setAttribute('style', "color: #0099CC; font-weight: bold");
var recentItemLink = getElementsByXpath("//a[@title='Recent Items']").snapshotItem(0);
if(recentItemLink) {
recentItemLink.parentNode.appendChild(link);
}
}
var jQuery;
var script = document.createElement('script');
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.js';
document.getElementsByTagName('head')[0].appendChild(script);
window.addEventListener('load', function(event) {
jQuery = unsafeWindow.jQuery;
if(jQuery) {
init();
}
}, 'false');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment