• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdenetwork API Reference
  • KDE Home
  • Contact Us
 

kget

  • sources
  • kde-4.12
  • kdenetwork
  • kget
  • transfer-plugins
  • metalink
metalink.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2 
3  Copyright (C) 2004 Dario Massarin <nekkar@libero.it>
4  Copyright (C) 2007 Manolo Valdes <nolis71cu@gmail.com>
5  Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 */
12 
13 #include "metalink.h"
14 #include "fileselectiondlg.h"
15 #include "metalinksettings.h"
16 
17 #include "core/kget.h"
18 #include "core/transfergroup.h"
19 #include "core/download.h"
20 #include "core/transferdatasource.h"
21 #include "core/filemodel.h"
22 #include "core/urlchecker.h"
23 #include "core/verifier.h"
24 #include "core/signature.h"
25 #ifdef HAVE_NEPOMUK
26  #include "core/nepomukhandler.h"
27  #include <Nepomuk2/Variant>
28 #endif //HAVE_NEPOMUK
29 
30 #include <KIconLoader>
31 #include <KIO/DeleteJob>
32 #include <KIO/NetAccess>
33 #include <KIO/RenameDialog>
34 #include <KLocale>
35 #include <KMessageBox>
36 #include <KDebug>
37 #include <KDialog>
38 #include <KStandardDirs>
39 
40 #include <QtCore/QFile>
41 #include <QtXml/QDomElement>
42 
43 Metalink::Metalink(TransferGroup * parent, TransferFactory * factory,
44  Scheduler * scheduler, const KUrl & source, const KUrl & dest,
45  const QDomElement * e)
46  : Transfer(parent, factory, scheduler, source, dest, e),
47  m_fileModel(0),
48  m_currentFiles(0),
49  m_metalinkJustDownloaded(false),
50  m_ready(false),
51  m_speedCount(0),
52  m_tempAverageSpeed(0),
53  m_averageSpeed(0)
54 {
55 }
56 
57 Metalink::~Metalink()
58 {
59 }
60 
61 void Metalink::start()
62 {
63  kDebug(5001) << "metalink::start";
64 
65  if (!m_ready)
66  {
67  if (m_localMetalinkLocation.isValid() && metalinkInit()) {
68  startMetalink();
69  } else {
70  downloadMetalink();
71  }
72  }
73  else
74  {
75  startMetalink();
76  }
77 }
78 
79 void Metalink::downloadMetalink()
80 {
81  m_metalinkJustDownloaded = true;
82 
83  setStatus(Job::Stopped, i18n("Downloading Metalink File...."), SmallIcon("document-save"));
84  setTransferChange(Tc_Status, true);
85  Download *download = new Download(m_source, QString(KStandardDirs::locateLocal("appdata", "metalinks/") + m_source.fileName()));
86  connect(download, SIGNAL(finishedSuccessfully(KUrl,QByteArray)), SLOT(metalinkInit(KUrl,QByteArray)));
87 }
88 
89 bool Metalink::metalinkInit(const KUrl &src, const QByteArray &data)
90 {
91  kDebug(5001);
92 
93  if (!src.isEmpty()) {
94  m_localMetalinkLocation = src;
95  }
96 
97  //use the downloaded metalink-file data directly if possible
98  if (!data.isEmpty()) {
99  KGetMetalink::HandleMetalink::load(data, &m_metalink);
100  }
101 
102  //try to parse the locally stored metalink-file
103  if (!m_metalink.isValid() && m_localMetalinkLocation.isValid()) {
104  KGetMetalink::HandleMetalink::load(m_localMetalinkLocation.toLocalFile(), &m_metalink);
105  }
106 
107  if (!m_metalink.isValid()) {
108  kError(5001) << "Unknown error when trying to load the .metalink-file. Metalink is not valid.";
109  setStatus(Job::Aborted);
110  setTransferChange(Tc_Status, true);
111  return false;
112  }
113 
114  //offers a dialog to download the newest version of a dynamic metalink
115  if ((m_source.isLocalFile() || !m_metalinkJustDownloaded) &&
116  m_metalink.dynamic && (UrlChecker::checkSource(m_metalink.origin) == UrlChecker::NoError)) {
117  if (KMessageBox::questionYesNo(0, i18n("A newer version of this Metalink might exist, do you want to download it?"),
118  i18n("Redownload Metalink")) == KMessageBox::Yes) {
119  m_localMetalinkLocation.clear();
120  m_source = m_metalink.origin;
121  downloadMetalink();
122  return false;
123  }
124  }
125 
126  QList<KGetMetalink::File>::const_iterator it;
127  QList<KGetMetalink::File>::const_iterator itEnd = m_metalink.files.files.constEnd();
128  m_totalSize = 0;
129  KIO::fileoffset_t segSize = 500 * 1024;//TODO use config here!
130  const KUrl tempDest = KUrl(m_dest.directory());
131  KUrl dest;
132  for (it = m_metalink.files.files.constBegin(); it != itEnd ; ++it)
133  {
134  dest = tempDest;
135  dest.addPath((*it).name);
136 
137  QList<KGetMetalink::Url> urlList = (*it).resources.urls;
138  //sort the urls according to their priority (highest first)
139  qSort(urlList.begin(), urlList.end(), qGreater<KGetMetalink::Url>());
140 
141  KIO::filesize_t fileSize = (*it).size;
142  m_totalSize += fileSize;
143 
144  //create a DataSourceFactory for each separate file
145  DataSourceFactory *dataFactory = new DataSourceFactory(this, dest, fileSize, segSize);
146  dataFactory->setMaxMirrorsUsed(MetalinkSettings::mirrorsPerFile());
147 
148 #ifdef HAVE_NEPOMUK
149  nepomukHandler()->setProperties((*it).properties(), QList<KUrl>() << dest);
150 #endif //HAVE_NEPOMUK
151 
152 //TODO compare available file size (<size>) with the sizes of the server while downloading?
153 
154  connect(dataFactory, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities()));
155  connect(dataFactory, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags)));
156  connect(dataFactory->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool)));
157  connect(dataFactory->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified()));
158  connect(dataFactory, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel)));
159 
160  //add the DataSources
161  for (int i = 0; i < urlList.size(); ++i)
162  {
163  const KUrl url = urlList[i].url;
164  if (url.isValid())
165  {
166  dataFactory->addMirror(url, MetalinkSettings::connectionsPerUrl());
167  }
168  }
169  //no datasource has been created, so remove the datasource factory
170  if (dataFactory->mirrors().isEmpty())
171  {
172  delete dataFactory;
173  }
174  else
175  {
176  dataFactory->verifier()->addChecksums((*it).verification.hashes);
177  foreach (const KGetMetalink::Pieces &pieces, (*it).verification.pieces) {
178  dataFactory->verifier()->addPartialChecksums(pieces.type, pieces.length, pieces.hashes);
179  }
180 
181  const QHash <QString, QString> signatures = (*it).verification.signatures;
182  QHash<QString, QString>::const_iterator it;
183  QHash<QString, QString>::const_iterator itEnd = signatures.constEnd();
184  for (it = signatures.constBegin(); it != itEnd; ++it) {
185  if (it.key().toLower() == "pgp") {
186  dataFactory->signature()->setAsciiDetatchedSignature(*it);
187  }
188  }
189 
190  m_dataSourceFactory[dataFactory->dest()] = dataFactory;
191  }
192  }
193 
194  if ((m_metalink.files.files.size() == 1) && m_dataSourceFactory.size())
195  {
196  m_dest = dest;
197  }
198 
199  if (!m_dataSourceFactory.size()) {
200  //TODO make this via log in the future + do not display the KMessageBox
201  kWarning(5001) << "Download of" << m_source << "failed, no working URLs were found.";
202  KMessageBox::error(0, i18n("Download failed, no working URLs were found."), i18n("Error"));
203  setStatus(Job::Aborted);
204  setTransferChange(Tc_Status, true);
205  return false;
206  }
207 
208  m_ready = !m_dataSourceFactory.isEmpty();
209  slotUpdateCapabilities();
210 
211  //the metalink-file has just been downloaded, so ask the user to choose the files that
212  // should be downloaded
213  if (m_metalinkJustDownloaded) {
214  KDialog *dialog = new FileSelectionDlg(fileModel());
215  dialog->setAttribute(Qt::WA_DeleteOnClose);
216  connect(dialog, SIGNAL(finished(int)), this, SLOT(fileDlgFinished(int)));
217 
218  dialog->show();
219  }
220 
221  return true;
222 }
223 
224 void Metalink::untickAllFiles()
225 {
226  for (int row = 0; row < fileModel()->rowCount(); ++row) {
227  QModelIndex index = fileModel()->index(row, FileItem::File);
228  if (index.isValid()) {
229  fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole);
230  }
231  }
232 }
233 
234 void Metalink::fileDlgFinished(int result)
235 {
236  //the dialog was not accepted untick every file, this ensures that the user does not
237  //press start by accident without first selecting the desired files
238  if (result != QDialog::Accepted) {
239  untickAllFiles();
240  }
241 
242  filesSelected();
243 
244  //no files selected to download or dialog rejected, stop the download
245  if (!m_numFilesSelected || (result != QDialog::Accepted)) {
246  setStatus(Job::Stopped);
247  setTransferChange(Tc_Status, true);
248  return;
249  }
250 
251  startMetalink();
252 }
253 
254 void Metalink::startMetalink()
255 {
256  if (m_ready)
257  {
258  foreach (DataSourceFactory *factory, m_dataSourceFactory)
259  {
260  //specified number of files is downloaded simultanously
261  if (m_currentFiles < MetalinkSettings::simultanousFiles())
262  {
263  const int status = factory->status();
264  //only start factories that should be downloaded
265  if (factory->doDownload() &&
266  (status != Job::Finished) &&
267  (status != Job::FinishedKeepAlive) &&
268  (status != Job::Running))
269  {
270  ++m_currentFiles;
271  factory->start();
272  }
273  }
274  else
275  {
276  break;
277  }
278  }
279  }
280 }
281 
282 void Metalink::deinit(Transfer::DeleteOptions options)
283 {
284  foreach (DataSourceFactory *factory, m_dataSourceFactory) {
285  if (options & Transfer::DeleteFiles) {
286  factory->deinit();
287  }
288  }//TODO: Ask the user if he/she wants to delete the *.part-file? To discuss (boom1992)
289 
290  //FIXME does that mean, that the metalink file is always removed, even if
291  //downloaded by the user?
292  if ((options & Transfer::DeleteTemporaryFiles) && m_localMetalinkLocation.isLocalFile())
293  {
294  KIO::Job *del = KIO::del(m_localMetalinkLocation, KIO::HideProgressInfo);
295  KIO::NetAccess::synchronousRun(del, 0);
296  }
297 
298 #ifdef HAVE_NEPOMUK
299  nepomukHandler()->deinit();
300 #endif //HAVE_NEPOMUK
301 }
302 
303 void Metalink::stop()
304 {
305  kDebug(5001) << "metalink::Stop";
306  if (m_ready && status() != Stopped)
307  {
308  m_currentFiles = 0;
309  foreach (DataSourceFactory *factory, m_dataSourceFactory)
310  {
311  factory->stop();
312  }
313  }
314 }
315 
316 void Metalink::slotDataSourceFactoryChange(Transfer::ChangesFlags change)
317 {
318  if ((change & Tc_Status) | (change & Tc_TotalSize)) {
319  DataSourceFactory *factory = qobject_cast<DataSourceFactory*>(sender());
320  if (change & Tc_Status) {
321  bool changeStatus;
322  updateStatus(factory, &changeStatus);
323  if (!changeStatus) {
324  change &= ~Tc_Status;
325  }
326  }
327  if (change & Tc_TotalSize) {
328  recalculateTotalSize(factory);
329  }
330  }
331  if (change & Tc_DownloadedSize) {
332  recalculateProcessedSize();
333  change |= Tc_Percent;
334  }
335  if (change & Tc_DownloadSpeed) {
336  recalculateSpeed();
337  }
338 
339  setTransferChange(change, true);
340 }
341 
342 void Metalink::recalculateTotalSize(DataSourceFactory *sender)
343 {
344  m_totalSize = 0;
345  foreach (DataSourceFactory *factory, m_dataSourceFactory)
346  {
347  if (factory->doDownload())
348  {
349  m_totalSize += factory->size();
350  }
351  }
352 
353  if (m_fileModel) {
354  if (sender) {
355  QModelIndex sizeIndex = m_fileModel->index(sender->dest(), FileItem::Size);
356  m_fileModel->setData(sizeIndex, static_cast<qlonglong>(sender->size()));
357  }
358  }
359 }
360 
361 void Metalink::recalculateProcessedSize()
362 {
363  m_downloadedSize = 0;
364  foreach (DataSourceFactory *factory, m_dataSourceFactory)
365  {
366  if (factory->doDownload())
367  {
368  m_downloadedSize += factory->downloadedSize();
369  }
370  }
371 
372  if (m_totalSize)
373  {
374  m_percent = (m_downloadedSize * 100) / m_totalSize;
375  }
376  else
377  {
378  m_percent = 0;
379  }
380 }
381 
382 void Metalink::recalculateSpeed()
383 {
384  m_downloadSpeed = 0;
385  foreach (DataSourceFactory *factory, m_dataSourceFactory)
386  {
387  if (factory->doDownload())
388  {
389  m_downloadSpeed += factory->currentSpeed();
390  }
391  }
392 
393  //calculate the average of the last three speeds
394  m_tempAverageSpeed += m_downloadSpeed;
395  ++m_speedCount;
396  if (m_speedCount == 3)
397  {
398  m_averageSpeed = m_tempAverageSpeed / 3;
399  m_speedCount = 0;
400  m_tempAverageSpeed = 0;
401  }
402 }
403 
404 int Metalink::remainingTime() const
405 {
406  if (!m_averageSpeed)
407  {
408  m_averageSpeed = m_downloadSpeed;
409  }
410  return KIO::calculateRemainingSeconds(m_totalSize, m_downloadedSize, m_averageSpeed);
411 }
412 
413 void Metalink::updateStatus(DataSourceFactory *sender, bool *changeStatus)
414 {
415  Job::Status status = (sender ? sender->status() : Job::Stopped);
416  *changeStatus = true;
417  switch (status)
418  {
419  case Job::Aborted:
420  case Job::Stopped: {
421  m_currentFiles = 0;
422  foreach (DataSourceFactory *factory, m_dataSourceFactory) {
423  //one factory is still running, do not change the status
424  if (factory->doDownload() && (factory->status() == Job::Running)) {
425  *changeStatus = false;
426  ++m_currentFiles;
427  }
428  }
429 
430  if (*changeStatus) {
431  setStatus(status);
432  }
433  break;
434  }
435  case Job::Finished:
436  //one file that has been downloaded now is finished//FIXME ignore downloads that were finished in the previous download!!!!
437  if (m_currentFiles)
438  {
439  --m_currentFiles;
440  startMetalink();
441  }
442  foreach (DataSourceFactory *factory, m_dataSourceFactory)
443  {
444  //one factory is not finished, do not change the status
445  if (factory->doDownload() && (factory->status() != Job::Finished))
446  {
447  *changeStatus = false;
448  break;
449  }
450  }
451 
452  if (*changeStatus) {
453  setStatus(Job::Finished);
454  }
455  break;
456 
457  default:
458  setStatus(status);
459  break;
460  }
461 
462  if (m_fileModel) {
463  if (sender) {
464  QModelIndex statusIndex = m_fileModel->index(sender->dest(), FileItem::Status);
465  m_fileModel->setData(statusIndex, status);
466  }
467  }
468 }
469 
470 void Metalink::slotVerified(bool isVerified)
471 {
472  Q_UNUSED(isVerified)
473 
474  if (status() == Job::Finished)
475  {
476  //see if some files are NotVerified
477  QStringList brokenFiles;
478  foreach (DataSourceFactory *factory, m_dataSourceFactory)
479  {
480  if (m_fileModel) {
481  QModelIndex checksumVerified = m_fileModel->index(factory->dest(), FileItem::ChecksumVerified);
482  m_fileModel->setData(checksumVerified, factory->verifier()->status());
483  }
484  if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified))
485  {
486  brokenFiles.append(factory->dest().pathOrUrl());
487  }
488  }
489 
490  if (brokenFiles.count())
491  {
492  if (KMessageBox::warningYesNoCancelList(0,
493  i18n("The download could not be verified, do you want to repair (if repairing does not work the download would be restarted) it?"),
494  brokenFiles) == KMessageBox::Yes) {
495  if (repair()) {
496  return;
497  }
498  }
499  }
500  }
501 }
502 
503 void Metalink::slotSignatureVerified()
504 {
505  if (status() == Job::Finished)
506  {
507  //see if some files are NotVerified
508  QStringList brokenFiles;
509  foreach (DataSourceFactory *factory, m_dataSourceFactory)
510  {
511  if (m_fileModel) {
512  QModelIndex signatureVerified = m_fileModel->index(factory->dest(), FileItem::SignatureVerified);
513  m_fileModel->setData(signatureVerified, factory->signature()->status());
514  }
515  if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified))
516  {
517  brokenFiles.append(factory->dest().pathOrUrl());
518  }
519  }
520 /*
521  if (brokenFiles.count())//TODO
522  {
523  if (KMessageBox::warningYesNoCancelList(0,
524  i18n("The download could not be verified, try to repair it?"),
525  brokenFiles) == KMessageBox::Yes)
526  {
527  if (repair())
528  {
529  return;
530  }
531  }
532  }*/
533  }
534 }
535 
536 bool Metalink::repair(const KUrl &file)
537 {
538  if (file.isValid())
539  {
540  if (m_dataSourceFactory.contains(file))
541  {
542  DataSourceFactory *broken = m_dataSourceFactory[file];
543  if (broken->verifier()->status() == Verifier::NotVerified)
544  {
545  broken->repair();
546  return true;
547  }
548  }
549  }
550  else
551  {
552  QList<DataSourceFactory*> broken;
553  foreach (DataSourceFactory *factory, m_dataSourceFactory)
554  {
555  if (factory->doDownload() && (factory->verifier()->status() == Verifier::NotVerified))
556  {
557  broken.append(factory);
558  }
559  }
560  if (broken.count())
561  {
562  foreach (DataSourceFactory *factory, broken)
563  {
564  factory->repair();
565  }
566  return true;
567  }
568  }
569 
570  return false;
571 }
572 
573 void Metalink::load(const QDomElement *element)
574 {
575  Transfer::load(element);
576 
577  if (!element)
578  {
579  return;
580  }
581 
582  const QDomElement e = *element;
583  m_localMetalinkLocation = KUrl(e.attribute("LocalMetalinkLocation"));
584  QDomNodeList factories = e.firstChildElement("factories").elementsByTagName("factory");
585 
586  //no stored information found, stop right here
587  if (!factories.count())
588  {
589  return;
590  }
591 
592  while (factories.count())
593  {
594  QDomDocument doc;
595  QDomElement factory = doc.createElement("factories");
596  factory.appendChild(factories.item(0).toElement());
597  doc.appendChild(factory);
598 
599  DataSourceFactory *file = new DataSourceFactory(this);
600  file->load(&factory);
601  connect(file, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities()));
602  connect(file, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags)));
603  m_dataSourceFactory[file->dest()] = file;
604  connect(file->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool)));
605  connect(file->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified()));
606  connect(file, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel)));
607 
608  //start the DataSourceFactories that were Started when KGet was closed
609  if (file->status() == Job::Running) {
610  if (m_currentFiles < MetalinkSettings::simultanousFiles()) {
611  ++m_currentFiles;
612  file->start();
613  } else {
614  //enough simultanous files already, so increase the number and set file to stop --> that will decrease the number again
615  file->stop();
616  }
617  }
618  }
619  m_ready = !m_dataSourceFactory.isEmpty();
620  slotUpdateCapabilities();
621 }
622 
623 void Metalink::save(const QDomElement &element)
624 {
625  Transfer::save(element);
626 
627  QDomElement e = element;
628  e.setAttribute("LocalMetalinkLocation", m_localMetalinkLocation.url());
629 
630  foreach (DataSourceFactory *factory, m_dataSourceFactory)
631  {
632  factory->save(e);
633  }
634 }
635 
636 Verifier *Metalink::verifier(const KUrl &file)
637 {
638  if (!m_dataSourceFactory.contains(file))
639  {
640  return 0;
641  }
642 
643  return m_dataSourceFactory[file]->verifier();
644 }
645 
646 Signature *Metalink::signature(const KUrl &file)
647 {
648  if (!m_dataSourceFactory.contains(file)) {
649  return 0;
650  }
651 
652  return m_dataSourceFactory[file]->signature();
653 }
654 
655 QList<KUrl> Metalink::files() const
656 {
657  return m_dataSourceFactory.keys();
658 }
659 
660 FileModel *Metalink::fileModel()
661 {
662  if (!m_fileModel)
663  {
664  m_fileModel = new FileModel(files(), directory(), this);
665  connect(m_fileModel, SIGNAL(rename(KUrl,KUrl)), this, SLOT(slotRename(KUrl,KUrl)));
666  connect(m_fileModel, SIGNAL(checkStateChanged()), this, SLOT(filesSelected()));
667 
668  foreach (DataSourceFactory *factory, m_dataSourceFactory)
669  {
670  const KUrl dest = factory->dest();
671  QModelIndex size = m_fileModel->index(dest, FileItem::Size);
672  m_fileModel->setData(size, static_cast<qlonglong>(factory->size()));
673  QModelIndex status = m_fileModel->index(dest, FileItem::Status);
674  m_fileModel->setData(status, factory->status());
675  QModelIndex checksumVerified = m_fileModel->index(dest, FileItem::ChecksumVerified);
676  m_fileModel->setData(checksumVerified, factory->verifier()->status());
677  QModelIndex signatureVerified = m_fileModel->index(dest, FileItem::SignatureVerified);
678  m_fileModel->setData(signatureVerified, factory->signature()->status());
679  if (!factory->doDownload())
680  {
681  QModelIndex index = m_fileModel->index(factory->dest(), FileItem::File);
682  m_fileModel->setData(index, Qt::Unchecked, Qt::CheckStateRole);
683  }
684  }
685  }
686 
687  return m_fileModel;
688 }
689 
690 void Metalink::filesSelected()
691 {
692  bool overwriteAll = false;
693  bool autoSkip = false;
694  bool cancel = false;
695  QModelIndexList files = fileModel()->fileIndexes(FileItem::File);
696  m_numFilesSelected = 0;
697 
698  //sets the CheckState of the fileModel to the according DataSourceFactories
699  //and asks the user if there are existing files already
700  foreach (const QModelIndex &index, files)
701  {
702  const KUrl dest = fileModel()->getUrl(index);
703  bool doDownload = index.data(Qt::CheckStateRole).toBool();
704  if (m_dataSourceFactory.contains(dest))
705  {
706  DataSourceFactory *factory = m_dataSourceFactory[dest];
707  //ignore finished transfers
708  if ((factory->status() == Job::Finished) || (factory->status() == Job::FinishedKeepAlive)) {
709  continue;
710  }
711 
712  //check if the file at dest exists already and ask the user what to do in this case, ignore already running transfers
713  if (doDownload && (factory->status() != Job::Running) && QFile::exists(dest.toLocalFile())) {
714  //usere has chosen to skip all files that exist already before
715  if (autoSkip) {
716  fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole);
717  doDownload = false;
718  //ask the user, unless he has choosen overwriteAll before
719  } else if (!overwriteAll) {
720  KIO::RenameDialog dlg(0, i18n("File already exists"), index.data().toString(), dest, KIO::RenameDialog_Mode(KIO::M_MULTI | KIO::M_OVERWRITE | KIO::M_SKIP));
721  const int result = dlg.exec();
722 
723  if (result == KIO::R_RENAME) {
724  //no reason to use FileModel::rename() since the file does not exist yet, so simply skip it
725  //avoids having to deal with signals
726  const KUrl newDest = dlg.newDestUrl();
727  factory->setDoDownload(doDownload);
728  factory->setNewDestination(newDest);
729  fileModel()->setData(index, newDest.fileName(), FileItem::File);
730  ++m_numFilesSelected;
731 
732  m_dataSourceFactory.remove(dest);
733  m_dataSourceFactory[newDest] = factory;
734  continue;
735  } else if (result == KIO::R_SKIP) {
736  fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole);
737  doDownload = false;
738  } else if (result == KIO::R_CANCEL) {
739  cancel = true;
740  break;
741  } else if (result == KIO::R_AUTO_SKIP) {
742  autoSkip = true;
743  fileModel()->setData(index, Qt::Unchecked, Qt::CheckStateRole);
744  doDownload = false;
745  } else if (result == KIO::R_OVERWRITE_ALL) {
746  overwriteAll = true;
747  }
748  }
749  }
750 
751  factory->setDoDownload(doDownload);
752  if (doDownload && (factory->status() != Finished) && (factory->status() != FinishedKeepAlive)) {
753  ++m_numFilesSelected;
754  }
755  }
756  }
757 
758  //the user decided to cancel, so untick all files
759  if (cancel) {
760  m_numFilesSelected = 0;
761  untickAllFiles();
762  foreach (DataSourceFactory *factory, m_dataSourceFactory) {
763  factory->setDoDownload(false);
764  }
765  }
766 
767  Transfer::ChangesFlags change = (Tc_TotalSize | Tc_DownloadSpeed);
768  //some files have been selected that are not finished yet, set them to stop if the transfer is not running (checked in slotStatus)
769  if (m_numFilesSelected) {
770  change |= Tc_Status;
771  }
772  slotDataSourceFactoryChange(change);
773 }
774 
775 void Metalink::slotRename(const KUrl &oldUrl, const KUrl &newUrl)
776 {
777  if (!m_dataSourceFactory.contains(oldUrl))
778  {
779  return;
780  }
781 
782  m_dataSourceFactory[newUrl] = m_dataSourceFactory[oldUrl];
783  m_dataSourceFactory.remove(oldUrl);
784  m_dataSourceFactory[newUrl]->setNewDestination(newUrl);
785 
786  setTransferChange(Tc_FileName);
787 }
788 
789 bool Metalink::setDirectory(const KUrl &new_directory)
790 {
791  if (new_directory == directory())
792  {
793  return false;
794  }
795 
796  if (m_fileModel)
797  {
798  m_fileModel->setDirectory(new_directory);
799  }
800 
801  const QString oldDirectory = directory().pathOrUrl(KUrl::AddTrailingSlash);
802  const QString newDirectory = new_directory.pathOrUrl(KUrl::AddTrailingSlash);
803  const QString fileName = m_dest.fileName();
804  m_dest = new_directory;
805  m_dest.addPath(fileName);
806 
807  QHash<KUrl, DataSourceFactory*> newStorage;
808  foreach (DataSourceFactory *factory, m_dataSourceFactory)
809  {
810  const KUrl oldUrl = factory->dest();
811  const KUrl newUrl = KUrl(oldUrl.pathOrUrl().replace(oldDirectory, newDirectory));
812  factory->setNewDestination(newUrl);
813  newStorage[newUrl] = factory;
814  }
815  m_dataSourceFactory = newStorage;
816 
817  setTransferChange(Tc_FileName);
818  return true;
819 }
820 
821 QHash<KUrl, QPair<bool, int> > Metalink::availableMirrors(const KUrl &file) const
822 {
823  QHash<KUrl, QPair<bool, int> > urls;
824 
825  if (m_dataSourceFactory.contains(file))
826  {
827  urls = m_dataSourceFactory[file]->mirrors();
828  }
829 
830  return urls;
831 }
832 
833 
834 void Metalink::setAvailableMirrors(const KUrl &file, const QHash<KUrl, QPair<bool, int> > &mirrors)
835 {
836  if (!m_dataSourceFactory.contains(file))
837  {
838  return;
839  }
840 
841  m_dataSourceFactory[file]->setMirrors(mirrors);
842 }
843 
844 void Metalink::slotUpdateCapabilities()
845 {
846  Capabilities oldCap = capabilities();
847  Capabilities newCap = 0;
848  foreach (DataSourceFactory *file, m_dataSourceFactory) {
849  if (file->doDownload()) {//FIXME when a download did not start yet it should be moveable!!//FIXME why not working, when only two connections?
850  if (newCap) {
851  newCap &= file->capabilities();
852  } else {
853  newCap = file->capabilities();
854  }
855  }
856  }
857 
858  if (newCap != oldCap) {
859  setCapabilities(newCap);
860  }
861 }
862 
863 #include "metalink.moc"
FileItem::File
Definition: filemodel.h:45
KGetMetalink::HandleMetalink::load
static bool load(const KUrl &destination, Metalink *metalink)
Loads destination into metalink.
Definition: metalinker.cpp:1232
Transfer::ChangesFlags
int ChangesFlags
Definition: transfer.h:100
DataSourceFactory::save
void save(const QDomElement &element)
Definition: datasourcefactory.cpp:1117
UrlChecker::NoError
Definition: urlchecker.h:61
Transfer::Tc_FileName
Definition: transfer.h:52
Transfer::m_dest
KUrl m_dest
Definition: transfer.h:357
Metalink::~Metalink
~Metalink()
Definition: metalink.cpp:57
TransferGroup
class TransferGroup:
Definition: transfergroup.h:46
Scheduler
Scheduler class: what handle all the jobs in kget.
Definition: scheduler.h:32
Job::Finished
The job is stopped, but this also indicates that it stopped because an error occurred.
Definition: job.h:47
Verifier::addPartialChecksums
void addPartialChecksums(const QString &type, KIO::filesize_t length, const QStringList &checksums)
Add partial checksums that can be used as repairinformation.
Definition: verifier.cpp:524
Download
Definition: download.h:23
KGetMetalink::Metalink::dynamic
bool dynamic
Definition: metalinker.h:323
KGetMetalink::Metalink::origin
KUrl origin
Definition: metalinker.h:326
Metalink::start
void start()
Definition: metalink.cpp:61
metalinksettings.h
Transfer::capabilities
Capabilities capabilities() const
Returns the capabilities this Transfer supports.
Definition: transfer.h:111
Transfer::m_downloadedSize
KIO::filesize_t m_downloadedSize
Definition: transfer.h:361
Job::Status
Status
The status property describes the current job status.
Definition: job.h:42
DataSourceFactory::size
KIO::filesize_t size() const
Definition: datasourcefactory.h:71
Transfer::LogLevel
LogLevel
Definition: transfer.h:81
Metalink::repair
bool repair(const KUrl &file=KUrl())
Tries to repair file.
Definition: metalink.cpp:536
Job::FinishedKeepAlive
The job exited from its Running state successfully.
Definition: job.h:48
DataSourceFactory
This class manages multiple DataSources and saves the received data to the file.
Definition: datasourcefactory.h:38
DataSourceFactory::start
void start()
Definition: datasourcefactory.cpp:193
DataSourceFactory::mirrors
QHash< KUrl, QPair< bool, int > > mirrors() const
Return all mirrors, where bool defines if the mirror is used, while in defines the number of paralell...
Definition: datasourcefactory.cpp:565
Job
Definition: job.h:35
FileSelectionDlg
Definition: fileselectiondlg.h:29
nepomukhandler.h
download.h
Metalink::availableMirrors
QHash< KUrl, QPair< bool, int > > availableMirrors(const KUrl &file) const
The mirrors that are available bool if it is used, int how many paralell connections are allowed to t...
Definition: metalink.cpp:821
urlchecker.h
KDialog
FileModel::fileIndexes
QModelIndexList fileIndexes(int column) const
Returns a list of pointers to all files of this model.
Definition: filemodel.cpp:475
KGetMetalink::Files::files
QList< File > files
Definition: metalinker.h:296
DataSourceFactory::repair
void repair()
Tries to repair a broken download, via completely redownloading it or only the borken parts...
Definition: datasourcefactory.cpp:889
DataSourceFactory::capabilities
Transfer::Capabilities capabilities() const
The capabilities the DataSourceFactory supports.
Definition: datasourcefactory.h:55
MetalinkSettings::mirrorsPerFile
static int mirrorsPerFile()
Get MirrorsPerFile.
Definition: metalinksettings.h:73
Verifier::status
VerificationStatus status() const
Definition: verifier.cpp:206
Metalink::Metalink
Metalink(TransferGroup *parent, TransferFactory *factory, Scheduler *scheduler, const KUrl &src, const KUrl &dest, const QDomElement *e=0)
Definition: metalink.cpp:43
Transfer::m_totalSize
KIO::filesize_t m_totalSize
Definition: transfer.h:360
Transfer::log
const QStringList log() const
Transfer history.
Transfer::Tc_Status
Definition: transfer.h:53
Metalink::files
virtual QList< KUrl > files() const
Definition: metalink.cpp:655
FileModel
This model represents the files that are being downloaded.
Definition: filemodel.h:101
Transfer::m_downloadSpeed
int m_downloadSpeed
Definition: transfer.h:364
Metalink::fileModel
FileModel * fileModel()
Definition: metalink.cpp:660
DataSourceFactory::setMaxMirrorsUsed
void setMaxMirrorsUsed(int maxMirrorsUsed)
Change the maximum number off mirrors that will be used for downloading, if the download started alre...
Definition: datasourcefactory.h:87
KGetMetalink::Pieces::hashes
QStringList hashes
Definition: metalinker.h:221
DataSourceFactory::downloadedSize
KIO::filesize_t downloadedSize() const
Definition: datasourcefactory.h:72
FileModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const
Definition: filemodel.cpp:506
Job::Running
Definition: job.h:43
DataSourceFactory::addMirror
void addMirror(const KUrl &url, bool used, int numParalellConnections=1)
Add a mirror that can be used for downloading.
Definition: datasourcefactory.cpp:378
Transfer::load
virtual void load(const QDomElement *element)
Loads the transfer's info from the QDomElement.
Definition: transfer.cpp:244
DataSourceFactory::setDoDownload
void setDoDownload(bool doDownload)
Set if the datasourcefactory should download the file or not, if set to false the download will be st...
Definition: datasourcefactory.cpp:350
Metalink::stop
void stop()
Definition: metalink.cpp:303
MetalinkSettings::connectionsPerUrl
static int connectionsPerUrl()
Get ConnectionsPerUrl.
Definition: metalinksettings.h:104
DataSourceFactory::verifier
Verifier * verifier()
Definition: datasourcefactory.cpp:1222
Metalink::setDirectory
virtual bool setDirectory(const KUrl &newDirectory)
Move the download to the new destination.
Definition: metalink.cpp:789
Transfer::save
virtual void save(const QDomElement &element)
Saves this transfer to the given QDomNode.
Definition: transfer.cpp:230
Transfer::DeleteTemporaryFiles
Definition: transfer.h:96
metalink.h
DataSourceFactory::load
void load(const QDomElement *e)
Definition: datasourcefactory.cpp:952
Metalink::remainingTime
int remainingTime() const
Reimplemented to return a time based on the average of the last three speeds.
Definition: metalink.cpp:404
fileselectiondlg.h
FileModel::setDirectory
void setDirectory(const KUrl &newDirectory)
Set the url to the directory the files are stored in, the filemodel stores its entries as relative pa...
Definition: filemodel.cpp:538
Transfer::factory
TransferFactory * factory() const
Definition: transfer.h:272
transfergroup.h
signature.h
verifier.h
Transfer::capabilitiesChanged
void capabilitiesChanged()
Emitted when the capabilities of the Transfer change.
transferdatasource.h
Metalink::load
void load(const QDomElement *e)
Loads the transfer's info from the QDomElement.
Definition: metalink.cpp:573
Job::Aborted
The job is stopped.
Definition: job.h:45
UrlChecker::checkSource
static UrlError checkSource(const KUrl &source, bool showNotification=false)
Convenience method of checkUrl.
Definition: urlchecker.cpp:139
Transfer::directory
virtual KUrl directory() const
Definition: transfer.h:159
Transfer::Tc_DownloadSpeed
Definition: transfer.h:56
Transfer::setTransferChange
virtual void setTransferChange(ChangesFlags change, bool postEvent=false)
Makes the TransferHandler associated with this transfer know that a change in this transfer has occur...
Definition: transfer.cpp:338
FileItem::ChecksumVerified
Definition: filemodel.h:48
Job::Stopped
The job is being executed.
Definition: job.h:44
DataSourceFactory::dest
KUrl dest() const
Definition: datasourcefactory.h:76
KGetMetalink::Pieces::type
QString type
Definition: metalinker.h:219
KGetMetalink::Metalink::files
Files files
Definition: metalinker.h:329
Verifier
Definition: verifier.h:68
DataSourceFactory::currentSpeed
ulong currentSpeed() const
Definition: datasourcefactory.h:73
Job::status
Status status() const
Definition: job.h:93
Transfer::dest
const KUrl & dest() const
Definition: transfer.h:149
KGetMetalink::Pieces
Definition: metalinker.h:206
FileModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Definition: filemodel.cpp:390
DataSourceFactory::setNewDestination
bool setNewDestination(const KUrl &newDest)
Definition: datasourcefactory.cpp:823
FileItem::Status
Definition: filemodel.h:46
KGetMetalink::Metalink::isValid
bool isValid() const
checks if the minimum requirements of a metalink are met
Definition: metalinker.cpp:687
kget.h
Signature::status
VerificationStatus status() const
Definition: signature.cpp:124
Verifier::addChecksums
void addChecksums(const QHash< QString, QString > &checksums)
Add multiple checksums that will later be used in the verification process.
Definition: verifier.cpp:519
Transfer::setStatus
void setStatus(Job::Status jobStatus, const QString &text=QString(), const QPixmap &pix=QPixmap())
Sets the Job status to jobStatus, the status text to text and the status pixmap to pix...
Definition: transfer.cpp:292
Transfer::Tc_TotalSize
Definition: transfer.h:54
FileItem::SignatureVerified
Definition: filemodel.h:49
Metalink::setAvailableMirrors
void setAvailableMirrors(const KUrl &file, const QHash< KUrl, QPair< bool, int > > &mirrors)
Set the mirrors, int the number of paralell connections to the mirror bool if the mirror should be us...
Definition: metalink.cpp:834
Signature
Class to verify signatures.
Definition: signature.h:38
Transfer::Tc_Percent
Definition: transfer.h:55
Metalink::verifier
virtual Verifier * verifier(const KUrl &file)
Definition: metalink.cpp:636
Signature::setAsciiDetatchedSignature
void setAsciiDetatchedSignature(const QString &signature)
Definition: signature.cpp:141
Transfer::Tc_DownloadedSize
Definition: transfer.h:63
Transfer::m_percent
int m_percent
Definition: transfer.h:363
Transfer::DeleteFiles
Definition: transfer.h:97
DataSourceFactory::doDownload
bool doDownload() const
Returns whether the datasourcefactory should download the file or not, true by default.
Definition: datasourcefactory.h:141
FileItem::Size
Definition: filemodel.h:47
KGetMetalink::Pieces::length
KIO::filesize_t length
Definition: metalinker.h:220
FileModel::getUrl
KUrl getUrl(const QModelIndex &index)
The url on the filesystem (no check if the file exists yet!) of index, it can be a folder or file...
Definition: filemodel.cpp:544
TransferFactory
TransferFactory.
Definition: transferfactory.h:52
Transfer::m_source
KUrl m_source
Definition: transfer.h:356
Transfer::setCapabilities
void setCapabilities(Capabilities capabilities)
Sets the capabilities and automatically emits capabilitiesChanged.
Definition: transfer.cpp:68
MetalinkSettings::simultanousFiles
static int simultanousFiles()
Get SimultanousFiles.
Definition: metalinksettings.h:42
DataSourceFactory::deinit
void deinit()
Deletes the created (downloadInitialized() is true) file if the download was not finished Does not de...
Definition: datasourcefactory.cpp:112
Transfer::setLog
void setLog(const QString &message, Transfer::LogLevel level=Log_Info)
Set Transfer history.
Definition: transfer.cpp:201
Metalink::deinit
void deinit(Transfer::DeleteOptions options)
Definition: metalink.cpp:282
DataSourceFactory::status
Job::Status status() const
Definition: datasourcefactory.h:152
Verifier::NotVerified
Definition: verifier.h:79
DataSourceFactory::stop
void stop()
Definition: datasourcefactory.cpp:327
DataSourceFactory::signature
Signature * signature()
Definition: datasourcefactory.cpp:1231
FileModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: filemodel.cpp:436
filemodel.h
Metalink::signature
virtual Signature * signature(const KUrl &file)
Definition: metalink.cpp:646
Transfer
Definition: transfer.h:36
Metalink::save
void save(const QDomElement &element)
Saves this transfer to the given QDomNode.
Definition: metalink.cpp:623
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:53:17 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kget

Skip menu "kget"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdenetwork API Reference

Skip menu "kdenetwork API Reference"
  • kget
  • kopete
  •   kopete
  •   libkopete
  • krdc
  • krfb

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal