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

kget

  • sources
  • kde-4.14
  • kdenetwork
  • kget
  • transfer-plugins
  • metalink
metalinkxml.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  Copyright (C) 2012 Aish Raj Dahal <dahalaishraj@gmail.com>
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 */
13 
14 #include "metalinkxml.h"
15 #include "fileselectiondlg.h"
16 #include "metalinksettings.h"
17 
18 #include "core/kget.h"
19 #include "core/transfergroup.h"
20 #include "core/download.h"
21 #include "core/transferdatasource.h"
22 #include "core/filemodel.h"
23 #include "core/urlchecker.h"
24 #include "core/verifier.h"
25 #include "core/signature.h"
26 
27 #ifdef HAVE_NEPOMUK
28  #include "core/nepomukhandler.h"
29  #include <Nepomuk2/Variant>
30 #endif //HAVE_NEPOMUK
31 
32 #include <KIconLoader>
33 #include <KIO/DeleteJob>
34 #include <KIO/NetAccess>
35 #include <KIO/RenameDialog>
36 #include <KLocale>
37 #include <KMessageBox>
38 #include <KDebug>
39 #include <KDialog>
40 #include <KStandardDirs>
41 
42 #include <QtCore/QFile>
43 #include <QtXml/QDomElement>
44 
45 MetalinkXml::MetalinkXml(TransferGroup * parent, TransferFactory * factory,
46  Scheduler * scheduler, const KUrl & source, const KUrl & dest,
47  const QDomElement * e)
48  : AbstractMetalink(parent, factory, scheduler, source, dest, e)
49 
50 {
51 }
52 
53 MetalinkXml::~MetalinkXml()
54 {
55 }
56 
57 void MetalinkXml::start()
58 {
59  kDebug(5001) << "metalinkxml::start";
60 
61  if (!m_ready)
62  {
63  if (m_localMetalinkLocation.isValid() && metalinkInit()) {
64  startMetalink();
65  } else {
66  downloadMetalink();
67  }
68  }
69  else
70  {
71  startMetalink();
72  }
73 }
74 
75 void MetalinkXml::downloadMetalink()
76 {
77  m_metalinkJustDownloaded = true;
78 
79  setStatus(Job::Stopped, i18n("Downloading Metalink File...."), SmallIcon("document-save"));
80  setTransferChange(Tc_Status, true);
81  Download *download = new Download(m_source, QString(KStandardDirs::locateLocal("appdata", "metalinks/") + m_source.fileName()));
82  connect(download, SIGNAL(finishedSuccessfully(KUrl,QByteArray)), SLOT(metalinkInit(KUrl,QByteArray)));
83 }
84 
85 bool MetalinkXml::metalinkInit(const KUrl &src, const QByteArray &data)
86 {
87  kDebug(5001);
88 
89  if (!src.isEmpty()) {
90  m_localMetalinkLocation = src;
91  }
92 
93  //use the downloaded metalink-file data directly if possible
94  if (!data.isEmpty()) {
95  KGetMetalink::HandleMetalink::load(data, &m_metalink);
96  }
97 
98  //try to parse the locally stored metalink-file
99  if (!m_metalink.isValid() && m_localMetalinkLocation.isValid()) {
100  KGetMetalink::HandleMetalink::load(m_localMetalinkLocation.toLocalFile(), &m_metalink);
101  }
102 
103  if (!m_metalink.isValid()) {
104  kError(5001) << "Unknown error when trying to load the .metalink-file. Metalink is not valid.";
105  setStatus(Job::Aborted);
106  setTransferChange(Tc_Status, true);
107  return false;
108  }
109 
110  //offers a dialog to download the newest version of a dynamic metalink
111  if ((m_source.isLocalFile() || !m_metalinkJustDownloaded) &&
112  m_metalink.dynamic && (UrlChecker::checkSource(m_metalink.origin) == UrlChecker::NoError)) {
113  if (KMessageBox::questionYesNo(0, i18n("A newer version of this Metalink might exist, do you want to download it?"),
114  i18n("Redownload Metalink")) == KMessageBox::Yes) {
115  m_localMetalinkLocation.clear();
116  m_source = m_metalink.origin;
117  downloadMetalink();
118  return false;
119  }
120  }
121 
122  QList<KGetMetalink::File>::const_iterator it;
123  QList<KGetMetalink::File>::const_iterator itEnd = m_metalink.files.files.constEnd();
124  m_totalSize = 0;
125  KIO::fileoffset_t segSize = 500 * 1024;//TODO use config here!
126  const KUrl tempDest = KUrl(m_dest.directory());
127  KUrl dest;
128  for (it = m_metalink.files.files.constBegin(); it != itEnd ; ++it)
129  {
130  dest = tempDest;
131  dest.addPath((*it).name);
132 
133  QList<KGetMetalink::Url> urlList = (*it).resources.urls;
134  //sort the urls according to their priority (highest first)
135  qSort(urlList.begin(), urlList.end(), qGreater<KGetMetalink::Url>());
136 
137  KIO::filesize_t fileSize = (*it).size;
138  m_totalSize += fileSize;
139 
140  //create a DataSourceFactory for each separate file
141  DataSourceFactory *dataFactory = new DataSourceFactory(this, dest, fileSize, segSize);
142  dataFactory->setMaxMirrorsUsed(MetalinkSettings::mirrorsPerFile());
143 
144 #ifdef HAVE_NEPOMUK
145  nepomukHandler()->setProperties((*it).properties(), QList<KUrl>() << dest);
146 #endif //HAVE_NEPOMUK
147 
148 //TODO compare available file size (<size>) with the sizes of the server while downloading?
149 
150  connect(dataFactory, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities()));
151  connect(dataFactory, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags)));
152  connect(dataFactory->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool)));
153  connect(dataFactory->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified()));
154  connect(dataFactory, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel)));
155 
156  //add the DataSources
157  for (int i = 0; i < urlList.size(); ++i)
158  {
159  const KUrl url = urlList[i].url;
160  if (url.isValid())
161  {
162  dataFactory->addMirror(url, MetalinkSettings::connectionsPerUrl());
163  }
164  }
165  //no datasource has been created, so remove the datasource factory
166  if (dataFactory->mirrors().isEmpty())
167  {
168  delete dataFactory;
169  }
170  else
171  {
172  dataFactory->verifier()->addChecksums((*it).verification.hashes);
173 
174  foreach (const KGetMetalink::Pieces &pieces, (*it).verification.pieces) {
175  dataFactory->verifier()->addPartialChecksums(pieces.type, pieces.length, pieces.hashes);
176  }
177 
178  const QHash <QString, QString> signatures = (*it).verification.signatures;
179  QHash<QString, QString>::const_iterator it;
180  QHash<QString, QString>::const_iterator itEnd = signatures.constEnd();
181  for (it = signatures.constBegin(); it != itEnd; ++it) {
182  if (it.key().toLower() == "pgp") {
183  dataFactory->signature()->setAsciiDetatchedSignature(*it);
184  }
185  }
186 
187  m_dataSourceFactory[dataFactory->dest()] = dataFactory;
188  }
189  }
190 
191  if ((m_metalink.files.files.size() == 1) && m_dataSourceFactory.size())
192  {
193  m_dest = dest;
194  }
195 
196  if (!m_dataSourceFactory.size()) {
197  //TODO make this via log in the future + do not display the KMessageBox
198  kWarning(5001) << "Download of" << m_source << "failed, no working URLs were found.";
199  KMessageBox::error(0, i18n("Download failed, no working URLs were found."), i18n("Error"));
200  setStatus(Job::Aborted);
201  setTransferChange(Tc_Status, true);
202  return false;
203  }
204 
205  m_ready = !m_dataSourceFactory.isEmpty();
206  slotUpdateCapabilities();
207 
208  //the metalink-file has just been downloaded, so ask the user to choose the files that
209  // should be downloaded
210  /* TODO this portion seems not to be working. Need to ask boom1992 */
211  if (m_metalinkJustDownloaded) {
212  KDialog *dialog = new FileSelectionDlg(fileModel());
213  dialog->setAttribute(Qt::WA_DeleteOnClose);
214  connect(dialog, SIGNAL(finished(int)), this, SLOT(fileDlgFinished(int)));
215 
216  dialog->show();
217  }
218 
219  return true;
220 }
221 
222 void MetalinkXml::startMetalink()
223 {
224  if (m_ready)
225  {
226  foreach (DataSourceFactory *factory, m_dataSourceFactory)
227  {
228  //specified number of files is downloaded simultanously
229  if (m_currentFiles < MetalinkSettings::simultanousFiles())
230  {
231  const int status = factory->status();
232  //only start factories that should be downloaded
233  if (factory->doDownload() &&
234  (status != Job::Finished) &&
235  (status != Job::FinishedKeepAlive) &&
236  (status != Job::Running))
237  {
238  ++m_currentFiles;
239  factory->start();
240  }
241  }
242  else
243  {
244  break;
245  }
246  }
247  }
248 }
249 
250 void MetalinkXml::deinit(Transfer::DeleteOptions options)
251 {
252  foreach (DataSourceFactory *factory, m_dataSourceFactory) {
253  if (options & Transfer::DeleteFiles) {
254  factory->deinit();
255  }
256  }//TODO: Ask the user if he/she wants to delete the *.part-file? To discuss (boom1992)
257 
258  //FIXME does that mean, that the metalink file is always removed, even if
259  //downloaded by the user?
260  if ((options & Transfer::DeleteTemporaryFiles) && m_localMetalinkLocation.isLocalFile())
261  {
262  KIO::Job *del = KIO::del(m_localMetalinkLocation, KIO::HideProgressInfo);
263  KIO::NetAccess::synchronousRun(del, 0);
264  }
265 
266 #ifdef HAVE_NEPOMUK
267  nepomukHandler()->deinit();
268 #endif //HAVE_NEPOMUK
269 }
270 
271 void MetalinkXml::load(const QDomElement *element)
272 {
273  Transfer::load(element);
274 
275  if (!element)
276  {
277  return;
278  }
279 
280  const QDomElement e = *element;
281  m_localMetalinkLocation = KUrl(e.attribute("LocalMetalinkLocation"));
282  QDomNodeList factories = e.firstChildElement("factories").elementsByTagName("factory");
283 
284  //no stored information found, stop right here
285  if (!factories.count())
286  {
287  return;
288  }
289 
290  while (factories.count())
291  {
292  QDomDocument doc;
293  QDomElement factory = doc.createElement("factories");
294  factory.appendChild(factories.item(0).toElement());
295  doc.appendChild(factory);
296 
297  DataSourceFactory *file = new DataSourceFactory(this);
298  file->load(&factory);
299  connect(file, SIGNAL(capabilitiesChanged()), this, SLOT(slotUpdateCapabilities()));
300  connect(file, SIGNAL(dataSourceFactoryChange(Transfer::ChangesFlags)), this, SLOT(slotDataSourceFactoryChange(Transfer::ChangesFlags)));
301  m_dataSourceFactory[file->dest()] = file;
302  connect(file->verifier(), SIGNAL(verified(bool)), this, SLOT(slotVerified(bool)));
303  connect(file->signature(), SIGNAL(verified(int)), this, SLOT(slotSignatureVerified()));
304  connect(file, SIGNAL(log(QString,Transfer::LogLevel)), this, SLOT(setLog(QString,Transfer::LogLevel)));
305 
306  //start the DataSourceFactories that were Started when KGet was closed
307  if (file->status() == Job::Running) {
308  if (m_currentFiles < MetalinkSettings::simultanousFiles()) {
309  ++m_currentFiles;
310  file->start();
311  } else {
312  //enough simultanous files already, so increase the number and set file to stop --> that will decrease the number again
313  file->stop();
314  }
315  }
316  }
317  m_ready = !m_dataSourceFactory.isEmpty();
318  slotUpdateCapabilities();
319 }
320 
321 void MetalinkXml::save(const QDomElement &element)
322 {
323  Transfer::save(element);
324 
325  QDomElement e = element;
326  e.setAttribute("LocalMetalinkLocation", m_localMetalinkLocation.url());
327 
328  foreach (DataSourceFactory *factory, m_dataSourceFactory)
329  {
330  factory->save(e);
331  }
332 }
333 
334 #include "metalinkxml.moc"
AbstractMetalink::m_ready
bool m_ready
Definition: abstractmetalink.h:104
AbstractMetalink::fileDlgFinished
void fileDlgFinished(int result)
Definition: abstractmetalink.cpp:433
QDomElement::elementsByTagName
QDomNodeList elementsByTagName(const QString &tagname) const
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
metalinkxml.h
UrlChecker::NoError
Definition: urlchecker.h:61
Transfer::m_dest
KUrl m_dest
Definition: transfer.h:357
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
QHash::key
const Key key(const T &value) const
KGetMetalink::Metalink::dynamic
bool dynamic
Definition: metalinker.h:323
KGetMetalink::Metalink::origin
KUrl origin
Definition: metalinker.h:326
metalinksettings.h
AbstractMetalink::m_currentFiles
int m_currentFiles
Definition: abstractmetalink.h:102
QDomNode::appendChild
QDomNode appendChild(const QDomNode &newChild)
Transfer::LogLevel
LogLevel
Definition: transfer.h:81
QByteArray
QDomElement::attribute
QString attribute(const QString &name, const QString &defValue) const
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
QDomNodeList
QHash::size
int size() const
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
FileSelectionDlg
Definition: fileselectiondlg.h:29
AbstractMetalink::slotUpdateCapabilities
void slotUpdateCapabilities()
Definition: abstractmetalink.cpp:404
QByteArray::isEmpty
bool isEmpty() const
MetalinkXml::~MetalinkXml
~MetalinkXml()
Definition: metalinkxml.cpp:53
nepomukhandler.h
download.h
urlchecker.h
KDialog
KGetMetalink::Files::files
QList< File > files
Definition: metalinker.h:296
QList::size
int size() const
MetalinkSettings::mirrorsPerFile
static int mirrorsPerFile()
Get MirrorsPerFile.
Definition: metalinksettings.h:73
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
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
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
QHash::constEnd
const_iterator constEnd() const
MetalinkXml::load
void load(const QDomElement *e)
Loads the transfer's info from the QDomElement.
Definition: metalinkxml.cpp:271
QHash< QString, QString >
MetalinkSettings::connectionsPerUrl
static int connectionsPerUrl()
Get ConnectionsPerUrl.
Definition: metalinksettings.h:104
QDomElement::setAttribute
void setAttribute(const QString &name, const QString &value)
DataSourceFactory::verifier
Verifier * verifier()
Definition: datasourcefactory.cpp:1222
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
DataSourceFactory::load
void load(const QDomElement *e)
Definition: datasourcefactory.cpp:952
MetalinkXml::MetalinkXml
MetalinkXml(TransferGroup *parent, TransferFactory *factory, Scheduler *scheduler, const KUrl &src, const KUrl &dest, const QDomElement *e=0)
Definition: metalinkxml.cpp:45
fileselectiondlg.h
Transfer::factory
TransferFactory * factory() const
Definition: transfer.h:272
transfergroup.h
MetalinkXml::downloadMetalink
void downloadMetalink()
Definition: metalinkxml.cpp:75
QString
QList
signature.h
AbstractMetalink::slotDataSourceFactoryChange
void slotDataSourceFactoryChange(Transfer::ChangesFlags change)
Definition: abstractmetalink.cpp:55
AbstractMetalink::slotSignatureVerified
virtual void slotSignatureVerified()
Definition: abstractmetalink.cpp:229
MetalinkXml::metalinkInit
bool metalinkInit(const KUrl &url=KUrl(), const QByteArray &data=QByteArray())
Definition: metalinkxml.cpp:85
verifier.h
Transfer::capabilitiesChanged
void capabilitiesChanged()
Emitted when the capabilities of the Transfer change.
MetalinkXml::deinit
void deinit(Transfer::DeleteOptions options)
Definition: metalinkxml.cpp:250
QList::end
iterator end()
transferdatasource.h
Job::Aborted
The job is stopped.
Definition: job.h:45
QDomDocument
UrlChecker::checkSource
static UrlError checkSource(const KUrl &source, bool showNotification=false)
Convenience method of checkUrl.
Definition: urlchecker.cpp:139
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
AbstractMetalink
Definition: abstractmetalink.h:22
Job::Stopped
The job is being executed.
Definition: job.h:44
AbstractMetalink::m_dataSourceFactory
QHash< KUrl, DataSourceFactory * > m_dataSourceFactory
Definition: abstractmetalink.h:103
QHash::constBegin
const_iterator constBegin() const
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
MetalinkXml::save
void save(const QDomElement &element)
Saves this transfer to the given QDomNode.
Definition: metalinkxml.cpp:321
Job::status
Status status() const
Definition: job.h:93
MetalinkXml::startMetalink
void startMetalink()
Starts the type of metalink download.
Definition: metalinkxml.cpp:222
Transfer::dest
const KUrl & dest() const
Definition: transfer.h:149
QHash::isEmpty
bool isEmpty() const
KGetMetalink::Pieces
Definition: metalinker.h:206
QDomNode::firstChildElement
QDomElement firstChildElement(const QString &tagName) const
MetalinkXml::start
void start()
Definition: metalinkxml.cpp:57
KGetMetalink::Metalink::isValid
bool isValid() const
checks if the minimum requirements of a metalink are met
Definition: metalinker.cpp:687
kget.h
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
AbstractMetalink::slotVerified
void slotVerified(bool isVerified)
Definition: abstractmetalink.cpp:198
Signature::setAsciiDetatchedSignature
void setAsciiDetatchedSignature(const QString &signature)
Definition: signature.cpp:141
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
QDomDocument::createElement
QDomElement createElement(const QString &tagName)
KGetMetalink::Pieces::length
KIO::filesize_t length
Definition: metalinker.h:220
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
TransferFactory
TransferFactory.
Definition: transferfactory.h:52
Transfer::m_source
KUrl m_source
Definition: transfer.h:356
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
QDomElement
Transfer::setLog
void setLog(const QString &message, Transfer::LogLevel level=Log_Info)
Set Transfer history.
Definition: transfer.cpp:201
AbstractMetalink::fileModel
FileModel * fileModel()
Definition: abstractmetalink.cpp:313
DataSourceFactory::status
Job::Status status() const
Definition: datasourcefactory.h:152
QList::begin
iterator begin()
DataSourceFactory::stop
void stop()
Definition: datasourcefactory.cpp:327
DataSourceFactory::signature
Signature * signature()
Definition: datasourcefactory.cpp:1231
filemodel.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:28:43 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