src/download.cpp

changeset 431
ec1e2059319b
parent 430
8458cf2719d1
child 432
ef382b98a8af
equal deleted inserted replaced
430:8458cf2719d1 431:ec1e2059319b
30 #include "gldraw.h" 30 #include "gldraw.h"
31 31
32 PartDownloader g_PartDownloader; 32 PartDownloader g_PartDownloader;
33 33
34 cfg (str, net_downloadpath, ""); 34 cfg (str, net_downloadpath, "");
35 cfg (bool, net_guesspaths, true);
36 cfg (bool, net_autoclose, false);
35 37
36 constexpr const char* PartDownloader::k_OfficialURL, 38 constexpr const char* PartDownloader::k_OfficialURL,
37 *PartDownloader::k_UnofficialURL; 39 *PartDownloader::k_UnofficialURL;
38 40
39 // ============================================================================= 41 // =============================================================================
102 // ============================================================================= 104 // =============================================================================
103 // ----------------------------------------------------------------------------- 105 // -----------------------------------------------------------------------------
104 void PartDownloadPrompt::modifyDest (str& dest) const { 106 void PartDownloadPrompt::modifyDest (str& dest) const {
105 dest = dest.simplified(); 107 dest = dest.simplified();
106 108
107 if (getSource() == CustomURL) 109 // If the user doesn't want us to guess, stop right here.
108 dest = basename (dest); 110 if (net_guesspaths == false)
111 return;
109 112
110 // Ensure .dat extension 113 // Ensure .dat extension
111 if (dest.right (4) != ".dat") { 114 if (dest.right (4) != ".dat") {
112 // Remove the existing extension, if any. It may be we're here over a 115 // Remove the existing extension, if any. It may be we're here over a
113 // typo in the .dat extension. 116 // typo in the .dat extension.
172 } 175 }
173 176
174 // ============================================================================= 177 // =============================================================================
175 // ----------------------------------------------------------------------------- 178 // -----------------------------------------------------------------------------
176 void PartDownloadPrompt::startDownload() { 179 void PartDownloadPrompt::startDownload() {
180 str dest = ui->fname->text();
181 setPrimaryFile (null);
182
183 if (getSource() == CustomURL)
184 dest = basename (getURL());
185
186 modifyDest (dest);
187
188 if (QFile::exists (PartDownloader::getDownloadPath() + dest)) {
189 const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest);
190
191 if (!confirm (tr ("Overwrite?"), overwritemsg))
192 return;
193 }
194
177 ui->progress->setEnabled (true); 195 ui->progress->setEnabled (true);
178 ui->buttonBox->setEnabled (false); 196 ui->buttonBox->setEnabled (false);
179 ui->fname->setEnabled (false); 197 ui->fname->setEnabled (false);
180 ui->source->setEnabled (false); 198 ui->source->setEnabled (false);
181
182 str dest = ui->fname->text();
183 modifyDest (dest);
184 downloadFile (dest, getURL(), true); 199 downloadFile (dest, getURL(), true);
185 } 200 }
186 201
187 // ============================================================================= 202 // =============================================================================
188 // ----------------------------------------------------------------------------- 203 // -----------------------------------------------------------------------------
205 } 220 }
206 221
207 // ============================================================================= 222 // =============================================================================
208 // ----------------------------------------------------------------------------- 223 // -----------------------------------------------------------------------------
209 void PartDownloadPrompt::checkIfFinished() { 224 void PartDownloadPrompt::checkIfFinished() {
225 bool failed = false;
226
210 // If there is some download still working, we're not finished. 227 // If there is some download still working, we're not finished.
211 for (PartDownloadRequest* req : m_requests) 228 for (PartDownloadRequest* req : m_requests) {
212 if (!req->isFinished()) 229 if (!req->isFinished())
213 return; 230 return;
231
232 if (req->state() == PartDownloadRequest::Failed)
233 failed = true;
234 }
235
236 for (PartDownloadRequest* req : m_requests)
237 delete req;
214 238
215 // Update everything now 239 // Update everything now
216 reloadAllSubfiles(); 240 if (primaryFile()) {
217 g_win->fullRefresh(); 241 LDFile::setCurrent (primaryFile());
218 g_win->R()->resetAngles(); 242 reloadAllSubfiles();
219 243 g_win->fullRefresh();
220 // Allow the prompt be closed now. 244 g_win->R()->resetAngles();
221 ui->buttonBox->disconnect (SIGNAL (accepted())); 245 m_requests.clear();
222 connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (accept())); 246
223 ui->buttonBox->setEnabled (true); 247 if (net_autoclose && !failed) {
224 ui->progress->setEnabled (false); 248 // Close automatically if desired.
225 249 accept();
226 // accept(); 250 } else {
251 // Allow the prompt be closed now.
252 ui->buttonBox->disconnect (SIGNAL (accepted()));
253 connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (accept()));
254 ui->buttonBox->setEnabled (true);
255 ui->progress->setEnabled (false);
256 }
257 }
227 } 258 }
228 259
229 // ============================================================================= 260 // =============================================================================
230 // ----------------------------------------------------------------------------- 261 // -----------------------------------------------------------------------------
231 PartDownloadRequest::PartDownloadRequest (str url, str dest, bool primary, PartDownloadPrompt* parent) : 262 PartDownloadRequest::PartDownloadRequest (str url, str dest, bool primary, PartDownloadPrompt* parent) :
235 m_dest (dest), 266 m_dest (dest),
236 m_fpath (PartDownloader::getDownloadPath() + dest), 267 m_fpath (PartDownloader::getDownloadPath() + dest),
237 m_nam (new QNetworkAccessManager), 268 m_nam (new QNetworkAccessManager),
238 m_firstUpdate (true), 269 m_firstUpdate (true),
239 m_state (Requesting), 270 m_state (Requesting),
240 m_primary (primary) 271 m_primary (primary),
272 m_fp (null)
241 { 273 {
242 m_fpath.replace ("\\", "/");
243 QFile::remove (m_fpath);
244
245 // Make sure that we have a valid destination. 274 // Make sure that we have a valid destination.
246 str dirpath = dirname (m_fpath); 275 str dirpath = dirname (m_fpath);
247 276
248 QDir dir (dirpath); 277 QDir dir (dirpath);
249 if (!dir.exists()) { 278 if (!dir.exists()) {
283 prog->setValue (m_bytesRead); 312 prog->setValue (m_bytesRead);
284 break; 313 break;
285 314
286 case Finished: 315 case Finished:
287 case Failed: 316 case Failed:
288 case Aborted:
289 { 317 {
290 QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : 318 QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" :
291 "<b><span style=\"color: #800\">FAILED</span></b>"); 319 "<b><span style=\"color: #800\">FAILED</span></b>");
292 lb->setAlignment (Qt::AlignCenter); 320 lb->setAlignment (Qt::AlignCenter);
293 table->setCellWidget (tableRow(), ProgressColumn, lb); 321 table->setCellWidget (tableRow(), ProgressColumn, lb);
309 } 337 }
310 338
311 // ============================================================================= 339 // =============================================================================
312 // ----------------------------------------------------------------------------- 340 // -----------------------------------------------------------------------------
313 void PartDownloadRequest::downloadFinished() { 341 void PartDownloadRequest::downloadFinished() {
314 m_state = m_reply->error() == QNetworkReply::NoError ? Finished : Failed; 342 if (m_reply->error() != QNetworkReply::NoError)
343 m_state = Failed;
344 elif (state() != Failed)
345 m_state = Finished;
346
315 m_bytesRead = m_bytesTotal; 347 m_bytesRead = m_bytesTotal;
316 updateToTable(); 348 updateToTable();
317 349
350 if (m_fp) {
351 m_fp->close();
352 delete m_fp;
353 m_fp = null;
354 }
355
318 if (m_state != Finished) { 356 if (m_state != Finished) {
319 m_prompt->checkIfFinished(); 357 m_prompt->checkIfFinished();
320 return; 358 return;
321 } 359 }
360
361 print ("state: %1\n", (int) m_state);
322 362
323 // Try to load this file now. 363 // Try to load this file now.
324 LDFile* f = openDATFile (m_fpath, false); 364 LDFile* f = openDATFile (m_fpath, false);
325 if (!f) 365 if (!f)
326 return; 366 return;
343 m_prompt->modifyDest (dest); 383 m_prompt->modifyDest (dest);
344 m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); 384 m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false);
345 } 385 }
346 386
347 if (m_primary) 387 if (m_primary)
348 LDFile::setCurrent (f); 388 m_prompt->setPrimaryFile (f);
349 389
350 m_prompt->checkIfFinished(); 390 m_prompt->checkIfFinished();
351 } 391 }
352 392
353 // ============================================================================= 393 // =============================================================================
360 } 400 }
361 401
362 // ============================================================================= 402 // =============================================================================
363 // ----------------------------------------------------------------------------- 403 // -----------------------------------------------------------------------------
364 void PartDownloadRequest::readyRead() { 404 void PartDownloadRequest::readyRead() {
365 QFile f (m_fpath); 405 if (state() == Failed)
366 if (!f.open (QIODevice::Append)) 406 return;
367 return; 407
368 408 if (m_fp == null) {
369 f.write (m_reply->readAll()); 409 m_fpath.replace ("\\", "/");
370 f.close(); 410
411 // We have already asked the user whether we can overwrite so we're good
412 // to go here.
413 m_fp = new QFile (m_fpath);
414 if (!m_fp->open (QIODevice::WriteOnly)) {
415 critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno)));
416 m_state = Failed;
417 m_reply->abort();
418 updateToTable();
419 m_prompt->checkIfFinished();
420 return;
421 }
422 }
423
424 m_fp->write (m_reply->readAll());
371 } 425 }
372 426
373 // ============================================================================= 427 // =============================================================================
374 // ----------------------------------------------------------------------------- 428 // -----------------------------------------------------------------------------
375 void PartDownloadRequest::downloadError() { 429 void PartDownloadRequest::downloadError() {
382 } 436 }
383 437
384 // ============================================================================= 438 // =============================================================================
385 // ----------------------------------------------------------------------------- 439 // -----------------------------------------------------------------------------
386 bool PartDownloadRequest::isFinished() const { 440 bool PartDownloadRequest::isFinished() const {
387 return m_state == Finished || m_state == Failed || m_state == Aborted; 441 return m_state == Finished || m_state == Failed;
442 }
443
444 // =============================================================================
445 // -----------------------------------------------------------------------------
446 const PartDownloadRequest::State& PartDownloadRequest::state() const {
447 return m_state;
388 } 448 }
389 449
390 // ============================================================================= 450 // =============================================================================
391 // ----------------------------------------------------------------------------- 451 // -----------------------------------------------------------------------------
392 DEFINE_ACTION (DownloadFrom, 0) { 452 DEFINE_ACTION (DownloadFrom, 0) {

mercurial