ofxpartner.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                              ofx_partner.cpp 
00003                              -------------------
00004     copyright            : (C) 2005 by Ace Jones
00005     email                : acejones@users.sourceforge.net
00006 ***************************************************************************/
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Public License as published by  *
00015  *   the Free Software Foundation; either version 2 of the License, or     *
00016  *   (at your option) any later version.                                   *
00017  *                                                                         *
00018  ***************************************************************************/
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 #include <libofx.h>
00025 
00026 //#ifdef HAVE_LIBCURL
00027 #include <curl/curl.h>
00028 //#endif
00029 
00030 #include "ofxpartner.h"
00031 #include "nodeparser.h"
00032 
00033 #include <sys/stat.h>
00034 
00035 #include <iostream>
00036 #include <string>
00037 #include <vector>
00038 
00039 using std::string;
00040 using std::vector;
00041 using std::cout;
00042 using std::endl;
00043 
00044 namespace OfxPartner
00045 {
00046 bool post(const string& request, const string& url, const string& filename);
00047 
00048 const string kBankFilename = "ofx-bank-index.xml";
00049 const string kCcFilename = "ofx-cc-index.xml";
00050 const string kInvFilename = "ofx-inv-index.xml";
00051 
00052 void ValidateIndexCache(void)
00053 {
00054   // TODO Check whether these files exist and are recent enough before getting them again
00055 
00056   struct stat filestats;
00057   if ( stat( kBankFilename.c_str(), &filestats ) || difftime(time(0),filestats.st_mtime) > 7.0*24.0*60.0*60.0 )
00058     post("T=1&S=*&R=1&O=0&TEST=0","http://moneycentral.msn.com/money/2005/mnynet/service/ols/filist.aspx?SKU=3&VER=6",kBankFilename);
00059   if ( stat( kCcFilename.c_str(), &filestats ) || difftime(time(0),filestats.st_mtime) > 7.0*24.0*60.0*60.0 )
00060     post("T=2&S=*&R=1&O=0&TEST=0","http://moneycentral.msn.com/money/2005/mnynet/service/ols/filist.aspx?SKU=3&VER=6",kCcFilename);
00061   if ( stat( kInvFilename.c_str(), &filestats ) || difftime(time(0),filestats.st_mtime) > 7.0*24.0*60.0*60.0 )
00062     post("T=3&S=*&R=1&O=0&TEST=0","http://moneycentral.msn.com/money/2005/mnynet/service/ols/filist.aspx?SKU=3&VER=6",kInvFilename);
00063 }
00064 
00065 vector<string> BankNames(void)
00066 {
00067   vector<string> result;
00068 
00069   // Make sure the index files are up to date
00070   ValidateIndexCache();
00071   
00072   xmlpp::DomParser parser;
00073   parser.set_substitute_entities();
00074   parser.parse_file(kBankFilename);
00075   if ( parser ) 
00076   {
00077     vector<string> names = NodeParser(parser).Path("fi/prov/name").Text();
00078     result.insert(result.end(),names.begin(),names.end());
00079   }
00080   parser.parse_file(kCcFilename);
00081   if ( parser ) 
00082   {
00083     vector<string> names = NodeParser(parser).Path("fi/prov/name").Text();
00084     result.insert(result.end(),names.begin(),names.end());
00085   }
00086   parser.parse_file(kInvFilename);
00087   if ( parser ) 
00088   {
00089     vector<string> names = NodeParser(parser).Path("fi/prov/name").Text();
00090     result.insert(result.end(),names.begin(),names.end());
00091   }
00092 
00093   // Add Innovision
00094   result.push_back("Innovision");
00095           
00096   // sort the list and remove duplicates, to return one unified list of all supported banks 
00097   sort(result.begin(),result.end());
00098   result.erase(unique(result.begin(),result.end()),result.end());
00099   return result;
00100 }
00101 
00102 vector<string> FipidForBank(const string& bank)
00103 {
00104   vector<string> result;
00105 
00106   xmlpp::DomParser parser;
00107   parser.set_substitute_entities();
00108   parser.parse_file(kBankFilename);
00109   if ( parser ) 
00110   {
00111     vector<string> fipids = NodeParser(parser).Path("fi/prov").Select("name",bank).Path("guid").Text();
00112     if ( ! fipids.back().empty() )
00113       result.insert(result.end(),fipids.begin(),fipids.end());
00114   }
00115   parser.parse_file(kCcFilename);
00116   if ( parser ) 
00117   {
00118     vector<string> fipids = NodeParser(parser).Path("fi/prov").Select("name",bank).Path("guid").Text();
00119     if ( ! fipids.back().empty() )
00120       result.insert(result.end(),fipids.begin(),fipids.end());
00121   }
00122   parser.parse_file(kInvFilename);
00123   if ( parser ) 
00124   {
00125     vector<string> fipids = NodeParser(parser).Path("fi/prov").Select("name",bank).Path("guid").Text();
00126     if ( ! fipids.back().empty() )
00127       result.insert(result.end(),fipids.begin(),fipids.end());
00128   }
00129 
00130   // the fipid for Innovision is 1.
00131   if ( bank == "Innovision" )
00132     result.push_back("1");
00133           
00134   sort(result.begin(),result.end());
00135   result.erase(unique(result.begin(),result.end()),result.end());
00136   
00137   return result;
00138 }
00139 
00140 OfxFiServiceInfo ServiceInfo(const std::string& fipid)
00141 {
00142   OfxFiServiceInfo result;
00143   memset(&result,0,sizeof(OfxFiServiceInfo));
00144 
00145   // Hard-coded values for Innovision test server
00146   if ( fipid == "1" )
00147   {
00148     strncpy(result.fid,"00000",OFX_FID_LENGTH-1);
00149     strncpy(result.org,"ReferenceFI",OFX_ORG_LENGTH-1);
00150     strncpy(result.url,"http://ofx.innovision.com",OFX_URL_LENGTH-1);
00151     result.accountlist = 1;
00152     result.statements = 1;
00153     result.billpay = 1;
00154     result.investments = 1;
00155 
00156     return result;
00157   }
00158   
00159   string url = "http://moneycentral.msn.com/money/2005/mnynet/service/olsvcupd/OnlSvcBrandInfo.aspx?MSNGUID=&GUID=%1&SKU=3&VER=6";
00160   url.replace(url.find("%1"),2,fipid);
00161           
00162   // TODO: Check whether this file exists and is recent enough before getting it again
00163   string guidfile = "fipid-%1.xml";
00164   guidfile.replace(guidfile.find("%1"),2,fipid);
00165 
00166   struct stat filestats;
00167   if ( stat( guidfile.c_str(), &filestats ) || difftime(time(0),filestats.st_mtime) > 7.0*24.0*60.0*60.0 )
00168     post("",url.c_str(),guidfile.c_str());
00169 
00170           // Print the FI details
00171     xmlpp::DomParser parser;
00172           parser.set_substitute_entities(); 
00173           parser.parse_file(guidfile);
00174           if ( parser )
00175           {
00176             NodeParser nodes(parser);
00177             
00178             strncpy(result.fid,nodes.Path("ProviderSettings/FID").Text().back().c_str(),OFX_FID_LENGTH-1);
00179             strncpy(result.org,nodes.Path("ProviderSettings/Org").Text().back().c_str(),OFX_ORG_LENGTH-1);
00180             strncpy(result.url,nodes.Path("ProviderSettings/ProviderURL").Text().back().c_str(),OFX_URL_LENGTH-1);
00181             result.accountlist = (nodes.Path("ProviderSettings/AcctListAvail").Text().back() == "1");
00182             result.statements = (nodes.Path("BankingCapabilities/Bank").Text().back() == "1");
00183             result.billpay = (nodes.Path("BillPayCapabilities/Pay").Text().back() == "1");
00184             result.investments = (nodes.Path("InvestmentCapabilities/BrkStmt").Text().back() == "1");
00185           }
00186   return result;
00187 }
00188 
00189 bool post(const string& request, const string& url, const string& filename)
00190 {
00191 #if 1 //#ifdef HAVE_LIBCURL
00192   CURL *curl = curl_easy_init();
00193   if(! curl)
00194     return false;
00195 
00196   unlink(filename.c_str());  
00197   FILE* file = fopen(filename.c_str(),"wb");
00198   if (! file )
00199   {
00200     curl_easy_cleanup(curl);
00201     return false;
00202   }
00203     
00204   curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
00205   if ( request.length() )
00206     curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.c_str());
00207   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
00208   curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)file);
00209     
00210   /*CURLcode res =*/ curl_easy_perform(curl);
00211 
00212   curl_easy_cleanup(curl);
00213   
00214   fclose(file);
00215   
00216   return true;
00217 #else
00218   request; url; filename;
00219   cerr << "ERROR: libox must be configured with libcurl to post this request" << endl;
00220   return false;
00221 #endif
00222 }
00223 
00224 } // namespace OfxPartner
00225 
00226 
00227 // vim:cin:si:ai:et:ts=2:sw=2:

Generated on Mon Feb 9 21:21:59 2009 for LibOFX by  doxygen 1.5.0