Changeset View
Changeset View
Standalone View
Standalone View
host/downloadjob.cpp
Show All 19 Lines | 1 | /* | |||
---|---|---|---|---|---|
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE SOFTWARE. | 21 | THE SOFTWARE. | ||
22 | */ | 22 | */ | ||
23 | 23 | | |||
24 | #include "downloadjob.h" | 24 | #include "downloadjob.h" | ||
25 | #include "settings.h" | 25 | #include "settings.h" | ||
26 | 26 | | |||
27 | #include <QJsonObject> | 27 | #include <QJsonObject> | ||
28 | #include <QTimer> | ||||
28 | 29 | | |||
29 | #include <KLocalizedString> | 30 | #include <KLocalizedString> | ||
30 | 31 | | |||
31 | #include <KIO/Global> | 32 | #include <KIO/Global> | ||
32 | 33 | | |||
33 | DownloadJob::DownloadJob(int id) | 34 | DownloadJob::DownloadJob(int id) | ||
34 | : KJob() | 35 | : KJob() | ||
35 | , m_id(id) | 36 | , m_id(id) | ||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Line(s) | 136 | if (endTime.isValid()) { | |||
141 | if (remainingTime > 0) { | 142 | if (remainingTime > 0) { | ||
142 | speed = remainingBytes / remainingTime; | 143 | speed = remainingBytes / remainingTime; | ||
143 | } | 144 | } | ||
144 | } | 145 | } | ||
145 | 146 | | |||
146 | emitSpeed(speed); | 147 | emitSpeed(speed); | ||
147 | } | 148 | } | ||
148 | 149 | | |||
149 | // TODO use the estimatedEndTime to calculate transfer speed | 150 | it = payload.constFind(QStringLiteral("error")); | ||
151 | if (it != payload.constEnd()) { | ||||
152 | m_error = it->toString(); | ||||
153 | } | ||||
150 | 154 | | |||
151 | it = payload.constFind(QStringLiteral("state")); | 155 | it = payload.constFind(QStringLiteral("state")); | ||
152 | if (it != end) { | 156 | if (it != end) { | ||
153 | const QString status = it->toString(); | 157 | m_state = it->toString(); | ||
154 | if (status == QLatin1String("in_progress")) { | 158 | | ||
159 | if (m_state == QLatin1String("interrupted")) { | ||||
fvogt: You could change this into
```QString error = payload.value(QStringLiteral("error")).toString… | |||||
160 | // in Firefox we get the error after we got the state change to "interrupted" | ||||
fvogt: Same here as for error above. | |||||
161 | // so we defer finishing the download a bit where we might have the error | ||||
162 | QTimer::singleShot(1, this, &DownloadJob::interruptDownload); | ||||
163 | } else if (m_state == QLatin1String("complete")) { | ||||
164 | setError(KJob::NoError); | ||||
165 | emitResult(); | ||||
166 | return; | ||||
167 | } | ||||
168 | } | ||||
155 | 169 | | |||
156 | } else if (status == QLatin1String("interrupted")) { | 170 | if (descriptionDirty) { | ||
171 | updateDescription(); | ||||
172 | } | ||||
173 | } | ||||
157 | 174 | | |||
158 | const QString &error = payload.value(QStringLiteral("error")).toString(); | 175 | void DownloadJob::interruptDownload() | ||
176 | { | ||||
177 | // just to be sure | ||||
178 | if (m_state != QLatin1String("interrupted")) { | ||||
179 | qWarning() << "got told to interrupt a download that isn't interrupted anymore"; | ||||
180 | return; | ||||
181 | } | ||||
159 | 182 | | |||
160 | if (error == QLatin1String("USER_CANCELED") | 183 | if (m_error == QLatin1String("USER_CANCELED") | ||
161 | || error == QLatin1String("USER_SHUTDOWN")) { | 184 | || m_error == QLatin1String("USER_SHUTDOWN")) { | ||
162 | setError(KIO::ERR_USER_CANCELED); // will keep Notification applet from showing a "finished"/error message | 185 | setError(KIO::ERR_USER_CANCELED); // will keep Notification applet from showing a "finished"/error message | ||
163 | emitResult(); | 186 | emitResult(); | ||
164 | return; | 187 | return; | ||
165 | } | 188 | } | ||
166 | 189 | | |||
167 | // value is a QVariant so we can be lazy and support both KIO errors and custom test | | |||
168 | // if QVariant is an int: use that as KIO error | | |||
169 | // if QVariant is a QString: set UserError and message | | |||
170 | static const QHash<QString, QString> errors { | 190 | static const QHash<QString, QString> errors { | ||
171 | // for a list of these error codes *and their meaning* instead of looking at browser | 191 | // for a list of these error codes *and their meaning* instead of looking at browser | ||
172 | // extension docs, check out Chromium's source code: download_interrupt_reason_values.h | 192 | // extension docs, check out Chromium's source code: download_interrupt_reason_values.h | ||
173 | {QStringLiteral("FILE_ACCESS_DENIED"), i18n("Access denied.")}, // KIO::ERR_ACCESS_DENIED | 193 | {QStringLiteral("FILE_ACCESS_DENIED"), i18n("Access denied.")}, // KIO::ERR_ACCESS_DENIED | ||
174 | {QStringLiteral("FILE_NO_SPACE"), i18n("Insufficient free space.")}, // KIO::ERR_DISK_FULL | 194 | {QStringLiteral("FILE_NO_SPACE"), i18n("Insufficient free space.")}, // KIO::ERR_DISK_FULL | ||
175 | {QStringLiteral("FILE_NAME_TOO_LONG"), i18n("The file name you have chosen is too long.")}, | 195 | {QStringLiteral("FILE_NAME_TOO_LONG"), i18n("The file name you have chosen is too long.")}, | ||
176 | {QStringLiteral("FILE_TOO_LARGE"), i18n("The file is too large to be downloaded.")}, | 196 | {QStringLiteral("FILE_TOO_LARGE"), i18n("The file is too large to be downloaded.")}, | ||
177 | // haha | | |||
178 | {QStringLiteral("FILE_VIRUS_INFECTED"), i18n("The file possibly contains malicious contents.")}, | 197 | {QStringLiteral("FILE_VIRUS_INFECTED"), i18n("The file possibly contains malicious contents.")}, | ||
179 | {QStringLiteral("FILE_TRANSIENT_ERROR"), i18n("A temporary error has occurred. Please try again later.")}, | 198 | {QStringLiteral("FILE_TRANSIENT_ERROR"), i18n("A temporary error has occurred. Please try again later.")}, | ||
180 | 199 | | |||
181 | {QStringLiteral("NETWORK_FAILED"), i18n("A network error has occurred.")}, | 200 | {QStringLiteral("NETWORK_FAILED"), i18n("A network error has occurred.")}, | ||
182 | {QStringLiteral("NETWORK_TIMEOUT"), i18n("The network operation timed out.")}, // TODO something less geeky | 201 | {QStringLiteral("NETWORK_TIMEOUT"), i18n("The network operation timed out.")}, // TODO something less geeky | ||
183 | {QStringLiteral("NETWORK_DISCONNECTED"), i18n("The network connection has been lost.")}, | 202 | {QStringLiteral("NETWORK_DISCONNECTED"), i18n("The network connection has been lost.")}, | ||
184 | {QStringLiteral("NETWORK_SERVER_DOWN"), i18n("The server is no longer reachable.")}, | 203 | {QStringLiteral("NETWORK_SERVER_DOWN"), i18n("The server is no longer reachable.")}, | ||
185 | 204 | | |||
186 | {QStringLiteral("SERVER_FAILED"), i18n("A server error has occurred.")}, | 205 | {QStringLiteral("SERVER_FAILED"), i18n("A server error has occurred.")}, | ||
187 | // chromium code says "internal use" and this is really not something the user should see | 206 | // chromium code says "internal use" and this is really not something the user should see | ||
188 | // SERVER_NO_RANGE" | 207 | // SERVER_NO_RANGE | ||
189 | // SERVER_PRECONDITION | 208 | // SERVER_PRECONDITION | ||
190 | {QStringLiteral("SERVER_BAD_CONTENT"), i18n("The server does not have the requested data.")}, | 209 | {QStringLiteral("SERVER_BAD_CONTENT"), i18n("The server does not have the requested data.")}, | ||
191 | 210 | | |||
192 | {QStringLiteral("CRASH"), i18n("The browser application closed unexpectedly.")} | 211 | {QStringLiteral("CRASH"), i18n("The browser application closed unexpectedly.")} | ||
193 | }; | 212 | }; | ||
194 | 213 | | |||
195 | 214 | const QString &errorValue = errors.value(m_error); | |||
196 | const QString &errorValue = errors.value(error); | | |||
197 | if (errorValue.isEmpty()) { // unknown error | 215 | if (errorValue.isEmpty()) { // unknown error | ||
198 | setError(KIO::ERR_UNKNOWN); | 216 | setError(KIO::ERR_UNKNOWN); | ||
199 | setErrorText(i18n("An unknown error occurred while downloading.")); | 217 | setErrorText(i18n("An unknown error occurred while downloading.")); | ||
200 | emitResult(); | 218 | emitResult(); | ||
201 | return; | 219 | return; | ||
202 | } | 220 | } | ||
203 | 221 | | |||
204 | // KIO::Error doesn't have a UserDefined one, let's just use magic numbers then | 222 | // KIO::Error doesn't have a UserDefined one, let's just use magic numbers then | ||
205 | // TODO at least set the KIO::Errors that we do have | 223 | // TODO at least set the KIO::Errors that we do have | ||
206 | setError(1000); | 224 | setError(1000); | ||
207 | setErrorText(errorValue); | 225 | setErrorText(errorValue); | ||
208 | 226 | | |||
209 | emitResult(); | 227 | emitResult(); | ||
210 | | ||||
211 | return; | | |||
212 | } else if (status == QLatin1String("complete")) { | | |||
213 | emitResult(); | | |||
214 | return; | | |||
215 | } | | |||
216 | } | | |||
217 | | ||||
218 | if (descriptionDirty) { | | |||
219 | updateDescription(); | | |||
220 | } | | |||
221 | } | 228 | } | ||
222 | 229 | | |||
223 | void DownloadJob::updateDescription() | 230 | void DownloadJob::updateDescription() | ||
224 | { | 231 | { | ||
225 | description(this, i18nc("Job heading, like 'Copying'", "Downloading"), | 232 | description(this, i18nc("Job heading, like 'Copying'", "Downloading"), | ||
226 | qMakePair<QString, QString>(i18nc("The URL being downloaded", "Source"), (m_finalUrl.isValid() ? m_finalUrl : m_url).toDisplayString()), | 233 | qMakePair<QString, QString>(i18nc("The URL being downloaded", "Source"), (m_finalUrl.isValid() ? m_finalUrl : m_url).toDisplayString()), | ||
227 | qMakePair<QString, QString>(i18nc("The location being downloaded to", "Destination"), m_destination.toLocalFile()) | 234 | qMakePair<QString, QString>(i18nc("The location being downloaded to", "Destination"), m_destination.toLocalFile()) | ||
228 | ); | 235 | ); | ||
229 | } | 236 | } |
You could change this into