00001
00002
00003
00004
00005
00006
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #include <libofx.h>
00025
00026
00027 #include <curl/curl.h>
00028
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
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
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
00094 result.push_back("Innovision");
00095
00096
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
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
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
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
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 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 }
00225
00226
00227