1 | /* |
2 | * dataretriever.cpp |
3 | * |
4 | * Copyright (c) 2001, 2002, 2003 Frerich Raabe <raabe@kde.org> |
5 | * |
6 | * This program is distributed in the hope that it will be useful, but WITHOUT |
7 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
8 | * FOR A PARTICULAR PURPOSE. For licensing and distribution details, check the |
9 | * accompanying file 'COPYING'. |
10 | */ |
11 | |
12 | #include "dataretriever.h" |
13 | #include "global.h" |
14 | |
15 | #include <kio/job.h> |
16 | |
17 | #include <kprocess.h> |
18 | #include <kurl.h> |
19 | |
20 | #include <QtCore/QBuffer> |
21 | #include <QtCore/QTimer> |
22 | |
23 | namespace Syndication { |
24 | |
25 | DataRetriever::DataRetriever() |
26 | { |
27 | } |
28 | |
29 | DataRetriever::~DataRetriever() |
30 | { |
31 | } |
32 | |
33 | struct FileRetriever::FileRetrieverPrivate |
34 | { |
35 | FileRetrieverPrivate() |
36 | : buffer(NULL), |
37 | lastError(0), job(NULL) |
38 | { |
39 | } |
40 | |
41 | ~FileRetrieverPrivate() |
42 | { |
43 | delete buffer; |
44 | } |
45 | |
46 | QBuffer *buffer; |
47 | int lastError; |
48 | KIO::TransferJob *job; |
49 | }; |
50 | |
51 | FileRetriever::FileRetriever() |
52 | : d(new FileRetrieverPrivate) |
53 | { |
54 | } |
55 | |
56 | FileRetriever::~FileRetriever() |
57 | { |
58 | delete d; |
59 | } |
60 | |
61 | bool FileRetriever::m_useCache = true; |
62 | QString FileRetriever::m_userAgent = QString::fromLatin1("Syndication %1" ).arg(QString::fromLatin1(SYNDICATION_VERSION)); |
63 | |
64 | void FileRetriever::setUserAgent(const QString& userAgent) |
65 | { |
66 | m_userAgent = userAgent; |
67 | } |
68 | |
69 | void FileRetriever::setUseCache(bool enabled) |
70 | { |
71 | m_useCache = enabled; |
72 | } |
73 | |
74 | void FileRetriever::retrieveData(const KUrl &url) |
75 | { |
76 | if (d->buffer) |
77 | return; |
78 | |
79 | d->buffer = new QBuffer; |
80 | d->buffer->open(QIODevice::WriteOnly); |
81 | |
82 | KUrl u = url; |
83 | |
84 | if (u.protocol() == QLatin1String("feed" )) |
85 | u.setProtocol(QLatin1String("http" )); |
86 | |
87 | d->job = KIO::get(u, KIO::NoReload, KIO::HideProgressInfo); |
88 | |
89 | d->job->addMetaData(QLatin1String("UserAgent" ), m_userAgent); |
90 | d->job->addMetaData(QLatin1String("cache" ), m_useCache ? QLatin1String("refresh" ) : QLatin1String("reload" )); |
91 | |
92 | QTimer::singleShot(1000*90, this, SLOT(slotTimeout())); |
93 | |
94 | connect(d->job, SIGNAL(data(KIO::Job*,QByteArray)), |
95 | SLOT(slotData(KIO::Job*,QByteArray))); |
96 | connect(d->job, SIGNAL(result(KJob*)), SLOT(slotResult(KJob*))); |
97 | connect(d->job, SIGNAL(permanentRedirection(KIO::Job*,KUrl,KUrl)), |
98 | SLOT(slotPermanentRedirection(KIO::Job*,KUrl,KUrl))); |
99 | } |
100 | |
101 | void FileRetriever::slotTimeout() |
102 | { |
103 | abort(); |
104 | |
105 | delete d->buffer; |
106 | d->buffer = NULL; |
107 | |
108 | d->lastError = KIO::ERR_SERVER_TIMEOUT; |
109 | |
110 | emit dataRetrieved(QByteArray(), false); |
111 | } |
112 | |
113 | int FileRetriever::errorCode() const |
114 | { |
115 | return d->lastError; |
116 | } |
117 | |
118 | void FileRetriever::slotData(KIO::Job *, const QByteArray &data) |
119 | { |
120 | d->buffer->write(data.data(), data.size()); |
121 | } |
122 | |
123 | void FileRetriever::slotResult(KJob *job) |
124 | { |
125 | QByteArray data = d->buffer->buffer(); |
126 | data.detach(); |
127 | |
128 | delete d->buffer; |
129 | d->buffer = NULL; |
130 | |
131 | d->lastError = job->error(); |
132 | emit dataRetrieved(data, d->lastError == 0); |
133 | } |
134 | |
135 | void FileRetriever::slotPermanentRedirection(KIO::Job*, const KUrl&, |
136 | const KUrl& newUrl) |
137 | { |
138 | emit permanentRedirection(newUrl); |
139 | } |
140 | |
141 | void FileRetriever::abort() |
142 | { |
143 | if (d->job) |
144 | { |
145 | d->job->kill(); |
146 | d->job = NULL; |
147 | } |
148 | } |
149 | |
150 | struct OutputRetriever::OutputRetrieverPrivate |
151 | { |
152 | OutputRetrieverPrivate() : process(0L), buffer(0L), lastError(0) |
153 | { |
154 | } |
155 | |
156 | ~OutputRetrieverPrivate() |
157 | { |
158 | delete process; |
159 | delete buffer; |
160 | } |
161 | |
162 | KProcess *process; |
163 | QBuffer *buffer; |
164 | int lastError; |
165 | }; |
166 | |
167 | OutputRetriever::OutputRetriever() : d(new OutputRetrieverPrivate) |
168 | { |
169 | } |
170 | |
171 | OutputRetriever::~OutputRetriever() |
172 | { |
173 | delete d; |
174 | } |
175 | |
176 | void OutputRetriever::retrieveData(const KUrl &url) |
177 | { |
178 | // Ignore subsequent calls if we didn't finish the previous job yet. |
179 | if (d->buffer || d->process) |
180 | return; |
181 | |
182 | d->buffer = new QBuffer; |
183 | d->buffer->open(QIODevice::WriteOnly); |
184 | |
185 | d->process = new KProcess(); |
186 | connect(d->process, SIGNAL(finished(int,QProcess::ExitStatus)), |
187 | SLOT(slotFinished(int,QProcess::ExitStatus))); |
188 | d->process->setShellCommand(url.path()); |
189 | d->process->start(); |
190 | } |
191 | |
192 | int OutputRetriever::errorCode() const |
193 | { |
194 | return d->lastError; |
195 | } |
196 | |
197 | void OutputRetriever::slotFinished(int exitCode, QProcess::ExitStatus exitStatus) |
198 | { |
199 | Q_UNUSED( exitCode ); |
200 | if (!d->process->exitCode()) |
201 | d->lastError = d->process->exitCode(); |
202 | |
203 | QByteArray data = d->process->readAllStandardOutput(); |
204 | |
205 | delete d->buffer; |
206 | d->buffer = NULL; |
207 | |
208 | int code = d->process->exitCode(); |
209 | |
210 | delete d->process; |
211 | d->process = NULL; |
212 | |
213 | emit dataRetrieved(data, exitStatus == QProcess::NormalExit && code == 0); |
214 | } |
215 | |
216 | } // namespace Syndication |
217 | |
218 | |