1 /***************************************************************************
2 kofxdirectconnectdlg.cpp
3 -------------------
4 begin : Sat Nov 13 2004
5 copyright : (C) 2002 by Ace Jones
6 email : acejones@users.sourceforge.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "kofxdirectconnectdlg.h"
19 #include "kmymoneysettings.h"
20
21 // ----------------------------------------------------------------------------
22 // QT Includes
23
24 #include <QLabel>
25 #include <QFile>
26 #include <QTextStream>
27 #include <QTemporaryFile>
28 #include <QDebug>
29
30 // ----------------------------------------------------------------------------
31 // KDE Includes
32
33 #include <kio/job_base.h>
34 #include <KJobUiDelegate>
35 #include <KIO/TransferJob>
36 #include <KMessageBox>
37 #include <KLocalizedString>
38
39 // ----------------------------------------------------------------------------
40 // Project Includes
41
42 #include "mymoneyofxconnector.h"
43
44 class KOfxDirectConnectDlg::Private
45 {
46 public:
Private()47 Private() : m_firstData(true) {}
48 QFile m_fpTrace;
49 bool m_firstData;
50 };
51
KOfxDirectConnectDlg(const MyMoneyAccount & account,QWidget * parent)52 KOfxDirectConnectDlg::KOfxDirectConnectDlg(const MyMoneyAccount& account, QWidget *parent) :
53 KOfxDirectConnectDlgDecl(parent),
54 d(new Private),
55 m_tmpfile(0),
56 m_connector(account),
57 m_job(0)
58 {
59 }
60
~KOfxDirectConnectDlg()61 KOfxDirectConnectDlg::~KOfxDirectConnectDlg()
62 {
63 if (d->m_fpTrace.isOpen()) {
64 d->m_fpTrace.close();
65 }
66 delete m_tmpfile;
67 delete d;
68 }
69
init()70 bool KOfxDirectConnectDlg::init()
71 {
72 show();
73
74 QByteArray request = m_connector.statementRequest();
75 if (request.isEmpty()) {
76 hide();
77 return false;
78 }
79
80 // For debugging, dump out the request
81 #if 0
82 QFile g("request.ofx");
83 g.open(QIODevice::WriteOnly);
84 QTextStream(&g) << m_connector.url() << "\n" << QString(request);
85 g.close();
86 #endif
87
88 if (KMyMoneySettings::logOfxTransactions()) {
89 QString logPath = KMyMoneySettings::logPath();
90 d->m_fpTrace.setFileName(QString("%1/ofxlog.txt").arg(logPath));
91 d->m_fpTrace.open(QIODevice::WriteOnly | QIODevice::Append);
92 }
93
94 if (d->m_fpTrace.isOpen()) {
95 QByteArray connectorData = m_connector.url().toUtf8();
96 d->m_fpTrace.write("url: ", 5);
97 d->m_fpTrace.write(connectorData, strlen(connectorData));
98 d->m_fpTrace.write("\n", 1);
99 d->m_fpTrace.write("request:\n", 9);
100 QByteArray trcData(request); // make local copy
101 trcData.replace('\r', ""); // krazy:exclude=doublequote_chars
102 d->m_fpTrace.write(trcData, trcData.size());
103 d->m_fpTrace.write("\n", 1);
104 d->m_fpTrace.write("response:\n", 10);
105 }
106
107 qDebug("creating job");
108 m_job = KIO::http_post(QUrl(m_connector.url()), request, KIO::HideProgressInfo);
109
110 // open the temp file. We come around here twice if init() is called twice
111 if (m_tmpfile) {
112 qDebug() << "Already connected, using " << m_tmpfile->fileName();
113 delete m_tmpfile; //delete otherwise we mem leak
114 }
115 m_tmpfile = new QTemporaryFile();
116 // for debugging purposes one might want to leave the temp file around
117 // in order to achieve this, please uncomment the next line
118 // m_tmpfile->setAutoRemove(false);
119 if (!m_tmpfile->open()) {
120 qWarning("Unable to open tempfile '%s' for download.", qPrintable(m_tmpfile->fileName()));
121 return false;
122 }
123
124 m_job->addMetaData("content-type", "Content-type: application/x-ofx");
125
126 connect(m_job, SIGNAL(result(KJob*)), this, SLOT(slotOfxFinished(KJob*)));
127 connect(m_job, SIGNAL(data(KIO::Job*,QByteArray)), this, SLOT(slotOfxData(KIO::Job*,QByteArray)));
128
129 setStatus(QString("Contacting %1...").arg(m_connector.url()));
130 kProgress1->setMaximum(3);
131 kProgress1->setValue(1);
132 return true;
133 }
134
setStatus(const QString & _status)135 void KOfxDirectConnectDlg::setStatus(const QString& _status)
136 {
137 textLabel1->setText(_status);
138 qDebug() << "STATUS:" << _status;
139 }
140
setDetails(const QString & _details)141 void KOfxDirectConnectDlg::setDetails(const QString& _details)
142 {
143 qDebug() << "DETAILS: " << _details;
144 }
145
slotOfxData(KIO::Job *,const QByteArray & _ba)146 void KOfxDirectConnectDlg::slotOfxData(KIO::Job*, const QByteArray& _ba)
147 {
148 qDebug("Got %d bytes of data", _ba.size());
149 if (d->m_firstData) {
150 setStatus("Connection established, retrieving data...");
151 setDetails(QString("Downloading data to %1...").arg(m_tmpfile->fileName()));
152 kProgress1->setValue(kProgress1->value() + 1);
153 d->m_firstData = false;
154 }
155 m_tmpfile->write(_ba);
156
157 setDetails(QString("Got %1 bytes").arg(_ba.size()));
158
159 if (d->m_fpTrace.isOpen()) {
160 QByteArray trcData(_ba);
161 trcData.replace('\r', ""); // krazy:exclude=doublequote_chars
162 d->m_fpTrace.write(trcData, trcData.size());
163 }
164 }
165
slotOfxFinished(KJob *)166 void KOfxDirectConnectDlg::slotOfxFinished(KJob* /* e */)
167 {
168 qDebug("Job finished");
169 kProgress1->setValue(kProgress1->value() + 1);
170 setStatus("Completed.");
171
172 if (d->m_fpTrace.isOpen()) {
173 d->m_fpTrace.write("\nCompleted\n\n\n\n", 14);
174 }
175
176 int error = m_job->error();
177
178 if (m_tmpfile) {
179 qDebug("Closing tempfile");
180 m_tmpfile->close();
181 }
182 qDebug("Tempfile closed");
183
184 if (error) {
185 qDebug("Show error message");
186 m_job->uiDelegate()->showErrorMessage();
187 } else if (m_job->isErrorPage()) {
188 qDebug("Process error page");
189 QString details;
190 if (m_tmpfile) {
191 QFile f(m_tmpfile->fileName());
192 if (f.open(QIODevice::ReadOnly)) {
193 QTextStream stream(&f);
194 while (!stream.atEnd()) {
195 details += stream.readLine(); // line of text excluding '\n'
196 }
197 f.close();
198
199 qDebug() << "The HTTP request failed: " << details;
200 }
201 }
202 KMessageBox::detailedSorry(this, i18n("The HTTP request failed."), details, i18nc("The HTTP request failed", "Failed"));
203 } else if (m_tmpfile) {
204 qDebug("Emit statementReady signal with '%s'", qPrintable(m_tmpfile->fileName()));
205 emit statementReady(m_tmpfile->fileName());
206 qDebug("Return from signal statementReady() processing");
207 }
208 delete m_tmpfile;
209 m_tmpfile = 0;
210 hide();
211 qDebug("Finishing slotOfxFinished");
212 }
213
reject()214 void KOfxDirectConnectDlg::reject()
215 {
216 if (m_job)
217 m_job->kill();
218 if (m_tmpfile) {
219 m_tmpfile->close();
220 delete m_tmpfile;
221 m_tmpfile = 0;
222 }
223 QDialog::reject();
224 }
225