/*
** Copyright (C) 2007 Jean-François Hovinne - http://www.hovinne.com/
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
using System;
using System.IO;
using System.Net;
using System.Text;
namespace Com.Hovinne {
///
/// HBDump dumps ING's HomeBank account operations HTML responses
/// and saves the results in a CSV file for further manipulations.
/// http://homebank.ing.be/
///
class HBDump {
///
/// Main entry of the console app.
///
public static void Main(string[] args) {
if(args.Length != 3) Usage();
//Account - format 1234567890120123456
//See in HTML source
string sAcc = args[0];
//Session ID - found in the URL or HTML source
//See in HTML source
string sSesId = args[1];
//CSV output file path - must be writable
string sPath = args[2];
string sReq = "http://127.0.0.1:1234/eb/Request"; //Request URL
DateTime dStart = DateTime.Now.AddYears(-1); //Start date - default Now - 1 year
DateTime dEnd = dStart.AddDays(7); //End date
string sMinDate = dStart.AddDays(-1).ToString("yyyyMMdd"); //Minimum date
string sMaxDate = dEnd.ToString("yyyyMMdd"); //Maximum date
while(dStart <= DateTime.Now) {
string sStart = dStart.ToString("yyyyMMdd");
string sEnd = dEnd.ToString("yyyyMMdd");
//Construct the request data
string sData= "lang=/FR/"
+ "&dse_sessionId=" + sSesId
+ "&dse_applicationId=-1"
+ "&dse_operationName=accEntries"
+ "&dse_pageId=7"
+ "&acc=" + sAcc
+ "¢ralisationCode=0"
+ "&dateStart=" + sStart
+ "&dateEnd=" + sEnd
+ "&labelCode=0"
+ "&minDate=" + sMinDate
+ "&maxDate=" + sMaxDate
+ "&nrDaysMaximal=00000014";
try {
string sResult = GetResponse(sReq, sData); //Get the response
sResult = ParseText(GetText(sResult)); //Parse the response
Console.WriteLine(sResult); //Print it
AppendToFile(sPath, sResult); //Write it to file
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
System.Environment.Exit(1);
}
//Loop until 1 year has been dumped
dStart = dEnd.AddDays(1);
dEnd = dStart.AddDays(7);
if(dEnd > DateTime.Now) dEnd = DateTime.Now;
}
}
///
/// GetResponse does the HTTP request and returns the HTML response.
///
private static string GetResponse(string sReq, string sData) {
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string result = "";
byte[] data = encoding.GetBytes(sData);
try {
// Prepare web request...
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sReq);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
Stream reqStream = request.GetRequestStream();
// Send the data.
reqStream.Write(data,0,data.Length);
reqStream.Close();
WebResponse response = request.GetResponse();
Stream respStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(respStream,encoding);
Char[] read = new Char[256];
int count = readStream.Read(read,0,256);
while (count > 0) {
// Dumps the 256 characters on a string
String str = new String(read,0,count);
result += str;
count = readStream.Read(read,0,256);
}
readStream.Close();
respStream.Close();
response.Close();
}
catch(Exception ex) {
throw new ApplicationException(ex.Message);
}
return(result);
}
///
/// GetText removes HTML code and returns raw text, line by line.
///
private static string GetText(string sHtml) {
int iLen = sHtml.Length;
string c, result = "";
bool bTag = false;
for(int i=0; i") { bTag = false; continue; }
if(!bTag && c != "\t") {
if((c == "\r" || c == "\n") && (result.EndsWith("\n") || result.Length == 0)) {}
else if (c == " " && result.EndsWith(" ")) {}
else result += c;
}
}
return(result);
}
///
/// AppendToFile appends text to a file.
///
private static void AppendToFile(string sPath, string sText) {
try {
StreamWriter sw;
sw = File.AppendText(sPath);
sw.WriteLine(sText);
sw.Close();
}
catch (Exception ex) {
throw new ApplicationException(ex.Message);
}
}
///
/// ParseText parses the raw text and outputs CSV data.
///
private static string ParseText(string sText) {
using (StringReader sr = new StringReader(sText)) {
string sLine, sNum = "", sDate = "", sDesc = "", sAmount = "", result = "";
bool bData = false, bDump = false, bEndTrn = false;
int iPos, iEnd;
while ((sLine = sr.ReadLine()) != null) {
if(sLine.StartsWith("Solde au")) bData = !bData;
if(bData) {
if(bDump) {
bEndTrn = false;
if(sLine.StartsWith("Opération ")) {
iPos = sLine.IndexOf(" ");
iEnd = sLine.IndexOf(" ", iPos + 1);
sNum = sLine.Substring(iPos+1, iEnd - iPos - 1);
iPos = sLine.LastIndexOf(" ");
sDate = sLine.Substring(iPos+1);
}
else if(sLine.EndsWith("EUR")) {
iPos = sLine.IndexOf(" ");
sAmount = sLine.Substring(0, iPos);
bEndTrn = true;
}
else if(!sLine.StartsWith("Opérations du")) sDesc += sLine + " ";
if(bEndTrn) {
if(result.Length > 0) result += "\r\n";
result += sNum + ";" + sDate + ";" + sDesc.Trim() + ";" + sAmount + ";";
sDesc = "";
}
}
if(sLine.StartsWith("Opérations du")) bDump = true;
}
}
return(result);
}
}
///
/// Prints usage.
///
private static void Usage() {
Console.WriteLine("Usage: HBDump [ACCOUNT] [SESID] [FILE]");
System.Environment.Exit(1);
}
}
}