/* ** 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); } } }