• 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
  • ui
  • metalinkcreator
metalinker.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 * Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net> *
3 * Copyright (C) 2012 Aish Raj Dahal <dahalaishraj@gmail.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
19 ***************************************************************************/
20 
21 #include "metalinker.h"
22 
23 #include <QtCore/QFile>
24 #include <QtCore/QTextStream>
25 #include <QtXml/QDomElement>
26 
27 #include <kdeversion.h>
28 #include <KDebug>
29 #include <KLocale>
30 #include <KSystemTimeZone>
31 
32 #ifdef HAVE_NEPOMUK
33  #include <Nepomuk2/Variant>
34  #include <Nepomuk2/Vocabulary/NCO>
35  #include <Nepomuk2/Vocabulary/NIE>
36  #include <Nepomuk2/Vocabulary/NFO>
37  #include <Soprano/Vocabulary/NAO>
38 
39 using namespace Nepomuk2::Vocabulary;
40 using namespace Soprano::Vocabulary;
41 #endif //HAVE_NEPOMUK
42 
43 const QString KGetMetalink::Metalink::KGET_DESCRIPTION = QString(QString("KGet/") + "2." + QString::number(KDE_VERSION_MINOR) + '.' + QString::number(KDE_VERSION_RELEASE));
44 const uint KGetMetalink::Metalink::MAX_URL_PRIORITY = 999999;
45 const uint KGetMetalink::Metalink_v3::MAX_PREFERENCE = 100;//as defined in Metalink specification 3.0 2nd edition
46 
47 namespace KGetMetalink
48 {
49  QString addaptHashType(const QString &type, bool loaded);
50 }
51 
60 QString KGetMetalink::addaptHashType(const QString &type, bool loaded)
61 {
62  QString t = type;
63  if (loaded)
64  {
65  t.replace("sha-", "sha");
66  }
67  else
68  {
69  t.replace("sha", "sha-");
70  }
71 
72  return t;
73 }
74 
75 void KGetMetalink::DateConstruct::setData(const QDateTime &dateT, const QTime &timeZoneOff, bool negOff)
76 {
77  dateTime = dateT;
78  timeZoneOffset = timeZoneOff;
79  negativeOffset = negOff;
80 }
81 
82 void KGetMetalink::DateConstruct::setData(const QString &dateConstruct)
83 {
84  if (dateConstruct.isEmpty())
85  {
86  return;
87  }
88 
89  const QString exp = "yyyy-MM-ddThh:mm:ss";
90  const int length = exp.length();
91 
92  dateTime = QDateTime::fromString(dateConstruct.left(length), exp);
93  if (dateTime.isValid())
94  {
95  int index = dateConstruct.indexOf('+', length - 1);
96  if (index > -1)
97  {
98  timeZoneOffset = QTime::fromString(dateConstruct.mid(index + 1), "hh:mm");
99  }
100  else
101  {
102  index = dateConstruct.indexOf('-', length - 1);
103  if (index > -1)
104  {
105  negativeOffset = true;
106  timeZoneOffset = QTime::fromString(dateConstruct.mid(index + 1), "hh:mm");
107  }
108  }
109  }
110 }
111 
112 bool KGetMetalink::DateConstruct::isNull() const
113 {
114  return dateTime.isNull();
115 }
116 
117 bool KGetMetalink::DateConstruct::isValid() const
118 {
119  return dateTime.isValid();
120 }
121 
122 QString KGetMetalink::DateConstruct::toString() const
123 {
124  QString string;
125 
126  if (dateTime.isValid())
127  {
128  string += dateTime.toString(Qt::ISODate);
129  }
130 
131  if (timeZoneOffset.isValid())
132  {
133  string += (negativeOffset ? '-' : '+');
134  string += timeZoneOffset.toString("hh:mm");
135  }
136  else if (!string.isEmpty())
137  {
138  string += 'Z';
139  }
140 
141  return string;
142 }
143 
144 void KGetMetalink::DateConstruct::clear()
145 {
146  dateTime = QDateTime();
147  timeZoneOffset = QTime();
148 }
149 
150 void KGetMetalink::UrlText::clear()
151 {
152  name.clear();
153  url.clear();
154 }
155 
156 void KGetMetalink::CommonData::load(const QDomElement &e)
157 {
158  identity = e.firstChildElement("identity").text();
159  version = e.firstChildElement("version").text();
160  description = e.firstChildElement("description").text();
161  logo = KUrl(e.firstChildElement("logo").text());
162  copyright = e.firstChildElement("copyright").text();
163 
164  const QDomElement publisherElem = e.firstChildElement("publisher");
165  publisher.name = publisherElem.attribute("name");
166  publisher.url = KUrl(publisherElem.attribute("url"));
167 
168  for (QDomElement elemRes = e.firstChildElement("language"); !elemRes.isNull(); elemRes = elemRes.nextSiblingElement("language")) {
169  languages << elemRes.text();
170  }
171 
172  for (QDomElement elemRes = e.firstChildElement("os"); !elemRes.isNull(); elemRes = elemRes.nextSiblingElement("os")) {
173  oses << elemRes.text();
174  }
175 }
176 
177 void KGetMetalink::CommonData::save(QDomElement &e) const
178 {
179  QDomDocument doc = e.ownerDocument();
180 
181  if (!copyright.isEmpty())
182  {
183  QDomElement elem = doc.createElement("copyright");
184  QDomText text = doc.createTextNode(copyright);
185  elem.appendChild(text);
186  e.appendChild(elem);
187  }
188  if (!description.isEmpty())
189  {
190  QDomElement elem = doc.createElement("description");
191  QDomText text = doc.createTextNode(description);
192  elem.appendChild(text);
193  e.appendChild(elem);
194  }
195  if (!identity.isEmpty())
196  {
197  QDomElement elem = doc.createElement("identity");
198  QDomText text = doc.createTextNode(identity);
199  elem.appendChild(text);
200  e.appendChild(elem);
201  }
202  if (!logo.isEmpty())
203  {
204  QDomElement elem = doc.createElement("logo");
205  QDomText text = doc.createTextNode(logo.url());
206  elem.appendChild(text);
207  e.appendChild(elem);
208  }
209  if (!publisher.isEmpty())
210  {
211  QDomElement elem = doc.createElement("publisher");
212  elem.setAttribute("url", publisher.url.url());
213  elem.setAttribute("name", publisher.name);
214 
215  e.appendChild(elem);
216  }
217  if (!version.isEmpty())
218  {
219  QDomElement elem = doc.createElement("version");
220  QDomText text = doc.createTextNode(version);
221  elem.appendChild(text);
222  e.appendChild(elem);
223  }
224 
225  foreach (const QString &language, languages) {
226  QDomElement elem = doc.createElement("language");
227  QDomText text = doc.createTextNode(language);
228  elem.appendChild(text);
229  e.appendChild(elem);
230  }
231 
232  foreach (const QString &os, oses) {
233  QDomElement elem = doc.createElement("os");
234  QDomText text = doc.createTextNode(os);
235  elem.appendChild(text);
236  e.appendChild(elem);
237  }
238 }
239 
240 void KGetMetalink::CommonData::clear()
241 {
242  identity.clear();
243  version.clear();
244  description.clear();
245  oses.clear();
246  logo.clear();
247  languages.clear();
248  publisher.clear();
249  copyright.clear();
250 }
251 
252 #ifdef HAVE_NEPOMUK
253 QList<QPair<QUrl, Nepomuk2::Variant> > KGetMetalink::CommonData::properties() const
254 {
255  //TODO what to do with identity?
256  QList<QPair<QUrl, Nepomuk2::Variant> > data;
257 
258  HandleMetalink::addProperty(&data, NIE::version(), version);
259  HandleMetalink::addProperty(&data, NIE::description(), description);
260 
261  QList<Nepomuk2::Resource> osResources;
262  foreach (const QString &os, oses) {
263  Nepomuk2::Resource osRes(os, NFO::OperatingSystem());
264  osRes.setProperty(NIE::title(), os);
265  osResources << osRes;
266  }
267  if (!osResources.isEmpty()) {
268  data << qMakePair(NAO::isRelated(), Nepomuk2::Variant(osResources));
269  }
270 
271  if (!logo.isEmpty()) {
272  Nepomuk2::Resource logoRes(logo, NFO::RemoteDataObject());
273  logoRes.addType(NAO::Symbol());
274  data << qMakePair(NAO::hasSymbol(), Nepomuk2::Variant(logoRes));
275  }
276 
277  QList<Nepomuk2::Variant> langVariants;
278  foreach (const QString &language, languages) {
279  langVariants << language;
280  }
281  if (langVariants.count()) {
282  data << qMakePair(NIE::language(), Nepomuk2::Variant(langVariants));
283  }
284 
285  if (!publisher.name.isEmpty()) {
286  Nepomuk2::Resource res(publisher.name, NCO::OrganizationContact());
287  res.setLabel(publisher.name);
288  res.addProperty(NCO::fullname(), publisher.name);
289  if (!publisher.url.isEmpty()) {
290  Nepomuk2::Resource website(publisher.url, NFO::Website());
291  website.addProperty(NIE::url(), publisher.url);
292  res.addProperty(NCO::websiteUrl(), website);
293  }
294  data << qMakePair(NCO::publisher(), Nepomuk2::Variant(res));
295  }
296 
297  HandleMetalink::addProperty(&data, NIE::copyright(), copyright);
298 
299  return data;
300 }
301 #endif //HAVE_NEPOMUK
302 
303 
304 bool KGetMetalink::Metaurl::operator<(const KGetMetalink::Metaurl &other) const
305 {
306  return (this->priority > other.priority) || (this->priority == 0);
307 }
308 
309 void KGetMetalink::Metaurl::load(const QDomElement &e)
310 {
311  type = e.attribute("mediatype").toLower();
312  priority = e.attribute("priority").toUInt();
313  if (priority > Metalink::MAX_URL_PRIORITY) {
314  priority = Metalink::MAX_URL_PRIORITY;
315  }
316  name = e.attribute("name");
317  url = KUrl(e.text());
318 }
319 
320 void KGetMetalink::Metaurl::save(QDomElement &e) const
321 {
322  QDomDocument doc = e.ownerDocument();
323  QDomElement metaurl = doc.createElement("metaurl");
324  if (priority)
325  {
326  metaurl.setAttribute("priority", priority);
327  }
328  if (!name.isEmpty())
329  {
330  metaurl.setAttribute("name", name);
331  }
332  metaurl.setAttribute("mediatype", type);
333 
334  QDomText text = doc.createTextNode(url.url());
335  metaurl.appendChild(text);
336 
337  e.appendChild(metaurl);
338 }
339 
340 bool KGetMetalink::Metaurl::isValid()
341 {
342  return url.isValid() && url.hasHost() && !url.protocol().isEmpty() && !type.isEmpty();
343 }
344 
345 void KGetMetalink::Metaurl::clear()
346 {
347  type.clear();
348  priority = 0;
349  name.clear();
350  url.clear();
351 }
352 
353 bool KGetMetalink::Url::operator<(const KGetMetalink::Url &other) const
354 {
355  bool smaller = (this->priority > other.priority) || ((this->priority == 0) && (other.priority != 0));
356 
357  if (!smaller && (this->priority == other.priority)) {
358  QString countryCode = KGlobal::locale()->country();
359  if (!countryCode.isEmpty()) {
360  smaller = (other.location.toLower() == countryCode.toLower());
361  }
362  }
363  return smaller;
364 }
365 
366 void KGetMetalink::Url::load(const QDomElement &e)
367 {
368  location = e.attribute("location").toLower();
369  priority = e.attribute("priority").toUInt();
370  if (priority > Metalink::MAX_URL_PRIORITY) {
371  priority = Metalink::MAX_URL_PRIORITY;
372  }
373  url = KUrl(e.text());
374 }
375 
376 void KGetMetalink::Url::save(QDomElement &e) const
377 {
378  QDomDocument doc = e.ownerDocument();
379  QDomElement elem = doc.createElement("url");
380  if (priority)
381  {
382  elem.setAttribute("priority", priority);
383  }
384  if (!location.isEmpty())
385  {
386  elem.setAttribute("location", location);
387  }
388 
389  QDomText text = doc.createTextNode(url.url());
390  elem.appendChild(text);
391 
392  e.appendChild(elem);
393 }
394 
395 bool KGetMetalink::Url::isValid()
396 {
397  return url.isValid() && url.hasHost() && !url.protocol().isEmpty();
398 }
399 
400 void KGetMetalink::Url::clear()
401 {
402  priority = 0;
403  location.clear();
404  url.clear();
405 }
406 
407 void KGetMetalink::Resources::load(const QDomElement &e)
408 {
409  for (QDomElement elem = e.firstChildElement("url"); !elem.isNull(); elem = elem.nextSiblingElement("url"))
410  {
411  Url url;
412  url.load(elem);
413  if (url.isValid())
414  {
415  urls.append(url);
416  }
417  }
418 
419  for (QDomElement elem = e.firstChildElement("metaurl"); !elem.isNull(); elem = elem.nextSiblingElement("metaurl"))
420  {
421  Metaurl metaurl;
422  metaurl.load(elem);
423  if (metaurl.isValid())
424  {
425  metaurls.append(metaurl);
426  }
427  }
428 }
429 
430 void KGetMetalink::Resources::save(QDomElement &e) const
431 {
432  foreach (const Metaurl &metaurl, metaurls)
433  {
434  metaurl.save(e);
435  }
436 
437  foreach (const Url &url, urls)
438  {
439  url.save(e);
440  }
441 }
442 
443 void KGetMetalink::Resources::clear()
444 {
445  urls.clear();
446  metaurls.clear();
447 }
448 
449 void KGetMetalink::Pieces::load(const QDomElement &e)
450 {
451  type = addaptHashType(e.attribute("type"), true);
452  length = e.attribute("length").toULongLong();
453 
454  QDomNodeList hashesList = e.elementsByTagName("hash");
455 
456  for (int i = 0; i < hashesList.count(); ++i)
457  {
458  QDomElement element = hashesList.at(i).toElement();
459  hashes.append(element.text());
460  }
461 }
462 
463 void KGetMetalink::Pieces::save(QDomElement &e) const
464 {
465  QDomDocument doc = e.ownerDocument();
466  QDomElement pieces = doc.createElement("pieces");
467  pieces.setAttribute("type", addaptHashType(type, false));
468  pieces.setAttribute("length", length);
469 
470  for (int i = 0; i < hashes.size(); ++i)
471  {
472  QDomElement hash = doc.createElement("hash");
473  QDomText text = doc.createTextNode(hashes.at(i));
474  hash.appendChild(text);
475  pieces.appendChild(hash);
476  }
477 
478  e.appendChild(pieces);
479 }
480 
481 void KGetMetalink::Pieces::clear()
482 {
483  type.clear();
484  length = 0;
485  hashes.clear();
486 }
487 
488 void KGetMetalink::Verification::load(const QDomElement &e)
489 {
490  for (QDomElement elem = e.firstChildElement("hash"); !elem.isNull(); elem = elem.nextSiblingElement("hash")) {
491  QString type = elem.attribute("type");
492  const QString hash = elem.text();
493  if (!type.isEmpty() && !hash.isEmpty()) {
494  type = addaptHashType(type, true);
495  hashes[type] = hash;
496  }
497  }
498 
499  for (QDomElement elem = e.firstChildElement("pieces"); !elem.isNull(); elem = elem.nextSiblingElement("pieces")) {
500  Pieces piecesItem;
501  piecesItem.load(elem);
502  pieces.append(piecesItem);
503  }
504 
505  for (QDomElement elem = e.firstChildElement("signature"); !elem.isNull(); elem = elem.nextSiblingElement("signature")) {
506  QString type = elem.attribute("mediatype");
507  if (type == "application/pgp-signature") {//FIXME with 4.5 make it handle signatures by default with mime-type
508  type = "pgp";
509  }
510  const QString siganture = elem.text();
511  if (!type.isEmpty() && !siganture.isEmpty()) {
512  signatures[type] = siganture;
513  }
514  }
515 }
516 
517 void KGetMetalink::Verification::save(QDomElement &e) const
518 {
519  QDomDocument doc = e.ownerDocument();
520 
521  QHash<QString, QString>::const_iterator it;
522  QHash<QString, QString>::const_iterator itEnd = hashes.constEnd();
523  for (it = hashes.constBegin(); it != itEnd; ++it) {
524  QDomElement hash = doc.createElement("hash");
525  hash.setAttribute("type", addaptHashType(it.key(), false));
526  QDomText text = doc.createTextNode(it.value());
527  hash.appendChild(text);
528  e.appendChild(hash);
529  }
530 
531  foreach (const Pieces &item, pieces) {
532  item.save(e);
533  }
534 
535  itEnd = signatures.constEnd();
536  for (it = signatures.constBegin(); it != itEnd; ++it) {
537  QString type = it.key();
538  if (type == "pgp") {//FIXME with 4.5 make it handle signatures by default with mime-type
539  type = "application/pgp-signature";
540  }
541  QDomElement hash = doc.createElement("signature");
542  hash.setAttribute("mediatype", type);
543  QDomText text = doc.createTextNode(it.value());
544  hash.appendChild(text);
545  e.appendChild(hash);
546  }
547 }
548 
549 void KGetMetalink::Verification::clear()
550 {
551  hashes.clear();
552  pieces.clear();
553 }
554 
555 bool KGetMetalink::File::isValid() const
556 {
557  return isValidNameAttribute() && resources.isValid();
558 }
559 
560 void KGetMetalink::File::load(const QDomElement &e)
561 {
562  data.load(e);
563 
564  name = QUrl::fromPercentEncoding(e.attribute("name").toAscii());
565  size = e.firstChildElement("size").text().toULongLong();
566 
567  verification.load(e);
568  resources.load(e);
569 }
570 
571 void KGetMetalink::File::save(QDomElement &e) const
572 {
573  if (isValid())
574  {
575  QDomDocument doc = e.ownerDocument();
576  QDomElement file = doc.createElement("file");
577  file.setAttribute("name", name);
578 
579  if (size)
580  {
581  QDomElement elem = doc.createElement("size");
582  QDomText text = doc.createTextNode(QString::number(size));
583  elem.appendChild(text);
584  file.appendChild(elem);
585  }
586 
587  data.save(file);
588  resources.save(file);
589  verification.save(file);
590 
591  e.appendChild(file);
592  }
593 }
594 
595 void KGetMetalink::File::clear()
596 {
597  name.clear();
598  verification.clear();
599  size = 0;
600  data.clear();
601  resources.clear();
602 }
603 
604 
605 bool KGetMetalink::File::isValidNameAttribute() const
606 {
607  if (name.isEmpty()) {
608  kError(5001) << "Name attribute of Metalink::File is empty.";
609  return false;
610  }
611 
612  if (name.endsWith('/')) {
613  kError(5001) << "Name attribute of Metalink::File does not contain a file name:" << name;
614  return false;
615  }
616 
617  const QStringList components = name.split('/');
618  if (name.startsWith('/') || components.contains("..") || components.contains(".")) {
619  kError(5001) << "Name attribute of Metalink::File contains directory traversal directives:" << name;
620  return false;
621  }
622 
623  return true;
624 }
625 
626 #ifdef HAVE_NEPOMUK
627 QList<QPair<QUrl, Nepomuk2::Variant> > KGetMetalink::File::properties() const
628 {
629  return data.properties();
630 }
631 #endif //HAVE_NEPOMUK
632 
633 bool KGetMetalink::Files::isValid() const
634 {
635  if (files.isEmpty()) {
636  return false;
637  }
638 
639  QStringList fileNames;
640  foreach (const File &file, files) {
641  fileNames << file.name;
642  if (!file.isValid()) {
643  return false;
644  }
645  }
646 
647  //The value of name must be unique for each file
648  while (!fileNames.isEmpty()) {
649  const QString fileName = fileNames.takeFirst();
650  if (fileNames.contains(fileName)) {
651  kError(5001) << "Metalink::File name" << fileName << "exists multiple times.";
652  return false;
653  }
654  }
655 
656  return true;
657 }
658 
659 void KGetMetalink::Files::load(const QDomElement &e)
660 {
661  for (QDomElement elem = e.firstChildElement("file"); !elem.isNull(); elem = elem.nextSiblingElement("file"))
662  {
663  File file;
664  file.load(elem);
665  files.append(file);
666  }
667 }
668 
669 void KGetMetalink::Files::save(QDomElement &e) const
670 {
671  if (e.isNull())
672  {
673  return;
674  }
675 
676  foreach (const File &file, files)
677  {
678  file.save(e);
679  }
680 }
681 
682 void KGetMetalink::Files::clear()
683 {
684  files.clear();
685 }
686 
687 bool KGetMetalink::Metalink::isValid() const
688 {
689  return files.isValid();
690 }
691 
692 // #ifdef HAVE_NEPOMUK
693 // QHash<QUrl, Nepomuk::Variant> KGetMetalink::Files::properties() const
694 // {
695 // return data.properties();
696 // }
697 // #endif //HAVE_NEPOMUK
698 
699 void KGetMetalink::Metalink::load(const QDomElement &e)
700 {
701  QDomDocument doc = e.ownerDocument();
702  const QDomElement metalink = doc.firstChildElement("metalink");
703 
704  xmlns = metalink.attribute("xmlns");
705  generator = metalink.firstChildElement("generator").text();
706  updated.setData(metalink.firstChildElement("updated").text());
707  published.setData(metalink.firstChildElement("published").text());
708  updated.setData(metalink.firstChildElement("updated").text());
709  const QDomElement originElem = metalink.firstChildElement("origin");
710  origin = KUrl(metalink.firstChildElement("origin").text());
711  if (originElem.hasAttribute("dynamic")) {
712  bool worked = false;
713  dynamic = originElem.attribute("dynamic").toInt(&worked);
714  if (!worked) {
715  dynamic = (originElem.attribute("dynamic") == "true");
716  }
717  }
718 
719  files.load(e);
720 }
721 
722 QDomDocument KGetMetalink::Metalink::save() const
723 {
724  QDomDocument doc;
725  QDomProcessingInstruction header = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
726  doc.appendChild(header);
727 
728  QDomElement metalink = doc.createElement("metalink");
729  metalink.setAttribute("xmlns", "urn:ietf:params:xml:ns:metalink"); //the xmlns value is ignored, instead the data format described in the specification is always used
730 
731  QDomElement elem = doc.createElement("generator");
732  QDomText text = doc.createTextNode(Metalink::KGET_DESCRIPTION); //the set generator is ignored, instead when saving KGET is always used
733  elem.appendChild(text);
734  metalink.appendChild(elem);
735 
736  if (!origin.isEmpty()) {
737  QDomElement elem = doc.createElement("origin");
738  QDomText text = doc.createTextNode(origin.url());
739  elem.appendChild(text);
740  if (dynamic) {
741  elem.setAttribute("dynamic", "true");
742  }
743  metalink.appendChild(elem);
744  }
745  if (published.isValid()) {
746  QDomElement elem = doc.createElement("published");
747  QDomText text = doc.createTextNode(published.toString());
748  elem.appendChild(text);
749  metalink.appendChild(elem);
750  }
751  if (updated.isValid()) {
752  QDomElement elem = doc.createElement("updated");
753  QDomText text = doc.createTextNode(updated.toString());
754  elem.appendChild(text);
755  metalink.appendChild(elem);
756  }
757 
758  files.save(metalink);
759 
760  doc.appendChild(metalink);
761 
762  return doc;
763 }
764 
765 void KGetMetalink::Metalink::clear()
766 {
767  dynamic = false;
768  xmlns.clear();
769  published.clear();
770  origin.clear();
771  generator.clear();
772  updated.clear();
773  files.clear();
774 }
775 
776 KGetMetalink::Metalink_v3::Metalink_v3()
777 {
778 }
779 
780 KGetMetalink::Metalink KGetMetalink::Metalink_v3::metalink()
781 {
782  return m_metalink;
783 }
784 
785 void KGetMetalink::Metalink_v3::setMetalink(const KGetMetalink::Metalink &metalink)
786 {
787  m_metalink = metalink;
788 }
789 
790 void KGetMetalink::Metalink_v3::load(const QDomElement &e)
791 {
792  QDomDocument doc = e.ownerDocument();
793  const QDomElement metalinkDom = doc.firstChildElement("metalink");
794 
795  m_metalink.dynamic = (metalinkDom.attribute("type") == "dynamic");
796  m_metalink.origin = KUrl(metalinkDom.attribute("origin"));
797  m_metalink.generator = metalinkDom.attribute("generator");
798  m_metalink.published = parseDateConstruct(metalinkDom.attribute("pubdate"));
799  m_metalink.updated = parseDateConstruct(metalinkDom.attribute("refreshdate"));
800 
801  parseFiles(metalinkDom);
802 }
803 
804 void KGetMetalink::Metalink_v3::parseFiles(const QDomElement &e)
805 {
806  //here we assume that the CommonData set in metalink is for every file in the metalink
807  CommonData data;
808  data = parseCommonData(e);
809 
810  const QDomElement filesElem = e.firstChildElement("files");
811  CommonData filesData = parseCommonData(filesElem);
812 
813  inheritCommonData(data, &filesData);
814 
815  for (QDomElement elem = filesElem.firstChildElement("file"); !elem.isNull(); elem = elem.nextSiblingElement("file")) {
816  File file;
817  file.name = QUrl::fromPercentEncoding(elem.attribute("name").toAscii());
818  file.size = elem.firstChildElement("size").text().toULongLong();
819 
820  file.data = parseCommonData(elem);
821  inheritCommonData(filesData, &file.data);
822 
823  file.resources = parseResources(elem);
824 
825  //load the verification information
826  QDomElement veriE = elem.firstChildElement("verification");
827 
828  for (QDomElement elemVer = veriE.firstChildElement("hash"); !elemVer.isNull(); elemVer = elemVer.nextSiblingElement("hash")) {
829  QString type = elemVer.attribute("type");
830  QString hash = elemVer.text();
831  if (!type.isEmpty() && !hash.isEmpty()) {
832  type = addaptHashType(type, true);
833  file.verification.hashes[type] = hash;
834  }
835  }
836 
837  for (QDomElement elemVer = veriE.firstChildElement("pieces"); !elemVer.isNull(); elemVer = elemVer.nextSiblingElement("pieces")) {
838  Pieces piecesItem;
839  piecesItem.load(elemVer);
840  file.verification.pieces.append(piecesItem);
841  }
842 
843  for (QDomElement elemVer = veriE.firstChildElement("signature"); !elemVer.isNull(); elemVer = elemVer.nextSiblingElement("signature")) {
844  const QString type = elemVer.attribute("type");
845  const QString signature = elemVer.text();
846  if (!type.isEmpty() && !signature.isEmpty()) {
847  file.verification.signatures[type] = signature;
848  }
849  }
850 
851  m_metalink.files.files.append(file);
852  }
853 }
854 
855 KGetMetalink::CommonData KGetMetalink::Metalink_v3::parseCommonData(const QDomElement &e)
856 {
857  CommonData data;
858 
859  data.load(e);
860 
861  const QDomElement publisherElem = e.firstChildElement("publisher");
862  data.publisher.name = publisherElem.firstChildElement("name").text();
863  data.publisher.url = KUrl(publisherElem.firstChildElement("url").text());
864 
865  return data;
866 }
867 
868 void KGetMetalink::Metalink_v3::inheritCommonData(const KGetMetalink::CommonData &ancestor, KGetMetalink::CommonData *inheritor)
869 {
870  if (!inheritor) {
871  return;
872  }
873 
874  //ensure that inheritance works
875  if (inheritor->identity.isEmpty()) {
876  inheritor->identity = ancestor.identity;
877  }
878  if (inheritor->version.isEmpty()) {
879  inheritor->version = ancestor.version;
880  }
881  if (inheritor->description.isEmpty()) {
882  inheritor->description = ancestor.description;
883  }
884  if (inheritor->oses.isEmpty()) {
885  inheritor->oses = ancestor.oses;
886  }
887  if (inheritor->logo.isEmpty()) {
888  inheritor->logo = ancestor.logo;
889  }
890  if (inheritor->languages.isEmpty()) {
891  inheritor->languages = ancestor.languages;
892  }
893  if (inheritor->copyright.isEmpty()) {
894  inheritor->copyright = ancestor.copyright;
895  }
896  if (inheritor->publisher.isEmpty()) {
897  inheritor->publisher = ancestor.publisher;
898  }
899 }
900 
901 KGetMetalink::Resources KGetMetalink::Metalink_v3::parseResources(const QDomElement &e)
902 {
903  Resources resources;
904 
905  QDomElement res = e.firstChildElement("resources");
906  for (QDomElement elemRes = res.firstChildElement("url"); !elemRes.isNull(); elemRes = elemRes.nextSiblingElement("url")) {
907  const QString location = elemRes.attribute("location").toLower();
908 
909  uint preference = elemRes.attribute("preference").toUInt();
910  //the maximum preference we use is MAX_PREFERENCE
911  if (preference > MAX_PREFERENCE) {
912  preference = MAX_PREFERENCE;
913  }
914  const int priority = MAX_PREFERENCE - preference + 1;//convert old preference to new priority
915 
916  const KUrl link = KUrl(elemRes.text());
917  QString type;
918 
919  if (link.fileName().endsWith(QLatin1String(".torrent"))) {
920  type = "torrent";
921  }
922 
923  if (type.isEmpty()) {
924  Url url;
925  if (preference) {
926  url.priority = priority;
927  }
928  url.location = location;
929  url.url = link;
930  if (url.isValid()) {
931  resources.urls.append(url);
932  }
933  } else {
934  //it might be a metaurl
935  Metaurl metaurl;
936  if (preference) {
937  metaurl.priority = priority;
938  }
939  metaurl.url = link;
940  metaurl.type = type;
941  if (metaurl.isValid()) {
942  resources.metaurls.append(metaurl);
943  }
944  }
945  }
946 
947  return resources;
948 }
949 
950 KGetMetalink::DateConstruct KGetMetalink::Metalink_v3::parseDateConstruct(const QString &data)
951 {
952  DateConstruct dateConstruct;
953 
954  if (data.isEmpty()){
955  return dateConstruct;
956  }
957 
958  kDebug(5001) << "Parsing" << data;
959 
960  QString temp = data;
961  QDateTime dateTime;
962  QTime timeZoneOffset;
963 
964  //Date according to RFC 822, the year with four characters preferred
965  //e.g.: "Mon, 15 May 2006 00:00:01 GMT", "Fri, 01 Apr 2009 00:00:01 +1030"
966 
967  //find the date
968  const QString weekdayExp = "ddd, ";
969  const bool weekdayIncluded = (temp.indexOf(',') == 3);
970  int startPosition = (weekdayIncluded ? weekdayExp.length() : 0);
971  const QString dayMonthExp = "dd MMM ";
972  const QString yearExp = "yy";
973 
974  QString exp = dayMonthExp + yearExp + yearExp;
975  int length = exp.length();
976 
977  QLocale locale = QLocale::c();
978  QDate date = locale.toDate(temp.mid(startPosition, length), exp);
979  if (!date.isValid()) {
980  exp = dayMonthExp + yearExp;
981  length = exp.length();
982  date = locale.toDate(temp.mid(startPosition, length), exp);
983  if (!date.isValid()) {
984  return dateConstruct;
985  }
986  }
987 
988  //find the time
989  dateTime.setDate(date);
990  temp = temp.mid(startPosition);
991  temp = temp.mid(length + 1);//also remove the space
992 
993  const QString hourExp = "hh";
994  const QString minuteExp = "mm";
995  const QString secondExp = "ss";
996 
997  exp = hourExp + ':' + minuteExp + ':' + secondExp;
998  length = exp.length();
999  QTime time = QTime::fromString(temp.left(length), exp);
1000  if (!time.isValid()) {
1001  exp = hourExp + ':' + minuteExp;
1002  length = exp.length();
1003  time = QTime::fromString(temp.left(length), exp);
1004  if (!time.isValid()) {
1005  return dateConstruct;
1006  }
1007  }
1008  dateTime.setTime(time);
1009 
1010  //find the offset
1011  temp = temp.mid(length + 1);//also remove the space
1012  bool negativeOffset = false;
1013 
1014  if (temp.length() == 3) { //e.g. GMT
1015  KTimeZone timeZone = KSystemTimeZones::readZone(temp);
1016  if (timeZone.isValid()) {
1017  int offset = timeZone.currentOffset();
1018  negativeOffset = (offset < 0);
1019  timeZoneOffset = QTime(0, 0, 0);
1020  timeZoneOffset = timeZoneOffset.addSecs(qAbs(offset));
1021  }
1022  } else if (temp.length() == 5) { //e.g. +1030
1023  negativeOffset = (temp[0] == '-');
1024  timeZoneOffset = QTime::fromString(temp.mid(1,4), "hhmm");
1025  }
1026 
1027  dateConstruct.setData(dateTime, timeZoneOffset, negativeOffset);
1028 
1029  return dateConstruct;
1030 }
1031 
1032 QDomDocument KGetMetalink::Metalink_v3::save() const
1033 {
1034  QDomDocument doc;
1035  QDomProcessingInstruction header = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
1036  doc.appendChild(header);
1037 
1038  QDomElement metalink = doc.createElement("metalink");
1039  metalink.setAttribute("xmlns", "http://www.metalinker.org/");
1040  metalink.setAttribute("version", "3.0");
1041  metalink.setAttribute("type", (m_metalink.dynamic ? "dynamic" : "static"));
1042  metalink.setAttribute("generator", Metalink::KGET_DESCRIPTION); //the set generator is ignored, instead when saving KGET is always used
1043 
1044  if (m_metalink.published.isValid()) {
1045  metalink.setAttribute("pubdate", dateConstructToString(m_metalink.published));
1046  }
1047  if (m_metalink.updated.isValid()) {
1048  metalink.setAttribute("refreshdate", dateConstructToString(m_metalink.updated));
1049  }
1050  if (!m_metalink.origin.isEmpty()) {
1051  metalink.setAttribute("origin", m_metalink.origin.url());
1052  }
1053 
1054  saveFiles(metalink);
1055 
1056  doc.appendChild(metalink);
1057 
1058  return doc;
1059 }
1060 
1061 void KGetMetalink::Metalink_v3::saveFiles(QDomElement &e) const
1062 {
1063  QDomDocument doc = e.ownerDocument();
1064  QDomElement filesElem = doc.createElement("files");
1065 
1066  foreach (const File &file, m_metalink.files.files) {
1067  QDomElement elem = doc.createElement("file");
1068  elem.setAttribute("name", file.name);
1069 
1070  QDomElement size = doc.createElement("size");
1071  QDomText text = doc.createTextNode(QString::number(file.size));
1072  size.appendChild(text);
1073  elem.appendChild(size);
1074 
1075  saveCommonData(file.data, elem);
1076  saveResources(file.resources, elem);
1077  saveVerification(file.verification, elem);
1078 
1079  filesElem.appendChild(elem);
1080  }
1081 
1082  e.appendChild(filesElem);
1083 }
1084 
1085 void KGetMetalink::Metalink_v3::saveResources(const Resources &resources, QDomElement &e) const
1086 {
1087  QDomDocument doc = e.ownerDocument();
1088  QDomElement res = doc.createElement("resources");
1089 
1090  foreach (const Url &url, resources.urls) {
1091  QDomElement elem = doc.createElement("url");
1092  const uint priority = url.priority;
1093  if (priority) {
1094  int preference = MAX_PREFERENCE - priority + 1;
1095  if (preference <= 0) {
1096  preference = 1;//HACK if priority is larger MAX_PREFERENCE makes it 1
1097  }
1098  elem.setAttribute("preference", preference);
1099  }
1100  if (!url.location.isEmpty()) {
1101  elem.setAttribute("location", url.location);
1102  }
1103 
1104  QDomText text = doc.createTextNode(url.url.url());
1105  elem.appendChild(text);
1106 
1107  res.appendChild(elem);
1108  }
1109 
1110  foreach (const Metaurl &metaurl, resources.metaurls) {
1111  if (metaurl.type == "torrent") {
1112  QDomElement elem = doc.createElement("url");
1113  elem.setAttribute("type", "bittorrent");
1114  const uint priority = metaurl.priority;
1115  if (priority) {
1116  int preference = MAX_PREFERENCE - priority + 1;
1117  if (preference <= 0) {
1118  preference = 1;//HACK if priority is larger MAX_PREFERENCE makes it 1
1119  }
1120  elem.setAttribute("preference", preference);
1121  }
1122 
1123  QDomText text = doc.createTextNode(metaurl.url.url());
1124  elem.appendChild(text);
1125 
1126  res.appendChild(elem);
1127  }
1128  }
1129 
1130  e.appendChild(res);
1131 }
1132 
1133 void KGetMetalink::Metalink_v3::saveVerification(const KGetMetalink::Verification &verification, QDomElement &e) const
1134 {
1135  QDomDocument doc = e.ownerDocument();
1136  QDomElement veri = doc.createElement("verification");
1137 
1138  QHash<QString, QString>::const_iterator it;
1139  QHash<QString, QString>::const_iterator itEnd = verification.hashes.constEnd();
1140  for (it = verification.hashes.constBegin(); it != itEnd; ++it) {
1141  QDomElement elem = doc.createElement("hash");
1142  elem.setAttribute("type", it.key());
1143  QDomText text = doc.createTextNode(it.value());
1144  elem.appendChild(text);
1145 
1146  veri.appendChild(elem);
1147  }
1148 
1149  foreach (const Pieces &pieces, verification.pieces) {
1150  QDomElement elem = doc.createElement("pieces");
1151  elem.setAttribute("type", pieces.type);
1152  elem.setAttribute("length", QString::number(pieces.length));
1153 
1154  for (int i = 0; i < pieces.hashes.count(); ++i) {
1155  QDomElement hash = doc.createElement("hash");
1156  hash.setAttribute("piece", i);
1157  QDomText text = doc.createTextNode(pieces.hashes.at(i));
1158  hash.appendChild(text);
1159 
1160  elem.appendChild(hash);
1161  }
1162  veri.appendChild(elem);
1163  }
1164 
1165  itEnd = verification.signatures.constEnd();
1166  for (it = verification.signatures.constBegin(); it != itEnd; ++it) {
1167  QDomElement elem = doc.createElement("signature");
1168  elem.setAttribute("type", it.key());
1169  QDomText text = doc.createTextNode(it.value());
1170  elem.appendChild(text);
1171 
1172  veri.appendChild(elem);
1173  }
1174 
1175  e.appendChild(veri);
1176 }
1177 
1178 void KGetMetalink::Metalink_v3::saveCommonData(const KGetMetalink::CommonData &data, QDomElement &e) const
1179 {
1180  QDomDocument doc = e.ownerDocument();
1181 
1182  CommonData commonData = data;
1183 
1184  if (!commonData.publisher.isEmpty()) {
1185  QDomElement elem = doc.createElement("publisher");
1186  QDomElement elemName = doc.createElement("name");
1187  QDomElement elemUrl = doc.createElement("url");
1188 
1189  QDomText text = doc.createTextNode(commonData.publisher.name);
1190  elemName.appendChild(text);
1191  elem.appendChild(elemName);
1192 
1193  text = doc.createTextNode(commonData.publisher.url.url());
1194  elemUrl.appendChild(text);
1195  elem.appendChild(elemUrl);
1196 
1197  e.appendChild(elem);
1198 
1199  commonData.publisher.clear();
1200  }
1201 
1202  if (commonData.oses.count() > 1) {//only one OS can be set in 3.0
1203  commonData.oses.clear();
1204  }
1205 
1206  commonData.save(e);
1207 }
1208 
1209 QString KGetMetalink::Metalink_v3::dateConstructToString(const KGetMetalink::DateConstruct &date) const
1210 {
1211  QString dateString;
1212  if (!date.isValid()) {
1213  return dateString;
1214  }
1215 
1216  QLocale locale = QLocale::c();
1217 
1218  //"Fri, 01 Apr 2009 00:00:01 +1030"
1219  dateString += locale.toString(date.dateTime, "ddd, dd MMM yyyy hh:mm:ss ");
1220 
1221  if (date.timeZoneOffset.isValid()) {
1222  dateString += (date.negativeOffset ? '-' : '+');
1223  dateString += date.timeZoneOffset.toString("hhmm");
1224  } else {
1225  dateString += "+0000";
1226  }
1227 
1228  return dateString;
1229 }
1230 
1231 
1232 bool KGetMetalink::HandleMetalink::load(const KUrl &destination, KGetMetalink::Metalink *metalink)
1233 {
1234  QFile file(destination.pathOrUrl());
1235  if (!file.open(QIODevice::ReadOnly))
1236  {
1237  return false;
1238  }
1239 
1240  QDomDocument doc;
1241  if (!doc.setContent(&file))
1242  {
1243  file.close();
1244  return false;
1245  }
1246  file.close();
1247 
1248  QDomElement root = doc.documentElement();
1249  if (root.attribute("xmlns") == "urn:ietf:params:xml:ns:metalink")
1250  {
1251  metalink->load(root);
1252  return true;
1253  }
1254  else if ((root.attribute("xmlns") == "http://www.metalinker.org/") || (root.attribute("version") == "3.0"))
1255  {
1256  Metalink_v3 metalink_v3;
1257  metalink_v3.load(root);
1258  *metalink = metalink_v3.metalink();
1259  return true;
1260  }
1261 
1262  return false;
1263 }
1264 
1265 bool KGetMetalink::HandleMetalink::load(const QByteArray &data, KGetMetalink::Metalink *metalink)
1266 {
1267  if (data.isNull())
1268  {
1269  return false;
1270  }
1271 
1272  QDomDocument doc;
1273  if (!doc.setContent(data))
1274  {
1275  return false;
1276  }
1277 
1278  metalink->clear();
1279  QDomElement root = doc.documentElement();
1280  if (root.attribute("xmlns") == "urn:ietf:params:xml:ns:metalink")
1281  {
1282  metalink->load(root);
1283  return true;
1284  }
1285  else if ((root.attribute("xmlns") == "http://www.metalinker.org/") || (root.attribute("version") == "3.0"))
1286  {
1287  Metalink_v3 metalink_v3;
1288  metalink_v3.load(root);
1289  *metalink = metalink_v3.metalink();
1290  return true;
1291  }
1292 
1293  return false;
1294 }
1295 
1296 bool KGetMetalink::HandleMetalink::save(const KUrl &destination, KGetMetalink::Metalink *metalink)
1297 {
1298  QFile file(destination.pathOrUrl());
1299  if (!file.open(QIODevice::WriteOnly)) {
1300  return false;
1301  }
1302 
1303  QDomDocument doc;
1304  QString fileName = destination.fileName();
1305  if (fileName.endsWith(QLatin1String("meta4"))) {
1306  doc = metalink->save();
1307  } else if (fileName.endsWith(QLatin1String("metalink"))) {
1308  Metalink_v3 metalink_v3;
1309  metalink_v3.setMetalink(*metalink);
1310  doc = metalink_v3.save();
1311  } else {
1312  file.close();
1313  return false;
1314  }
1315 
1316  QTextStream stream(&file);
1317  doc.save(stream, 2);
1318  file.close();
1319 
1320  return true;
1321 }
1322 
1323 #ifdef HAVE_NEPOMUK
1324 void KGetMetalink::HandleMetalink::addProperty(QList<QPair<QUrl, Nepomuk2::Variant> > *data, const QByteArray &uriBa, const QString &value)
1325 {
1326  if (!uriBa.isEmpty()) {
1327  addProperty(data, QUrl::fromEncoded(uriBa, QUrl::StrictMode), value);
1328  }
1329 }
1330 
1331 void KGetMetalink::HandleMetalink::addProperty(QList<QPair<QUrl, Nepomuk2::Variant> > *data, const QUrl &uri, const QString &value)
1332 {
1333  if (data && !uri.isEmpty() && !value.isEmpty()) {
1334  (*data) << qMakePair(uri, Nepomuk2::Variant(value));
1335  }
1336 }
1337 #endif //HAVE_NEPOMUK
1338 
1339 
1340 KGetMetalink::MetalinkHttpParser::~MetalinkHttpParser()
1341 {
1342 
1343 }
1344 
1345 QString* KGetMetalink::MetalinkHttpParser::getEtag()
1346 {
1347  return &m_EtagValue;
1348 }
1349 
1350 void KGetMetalink::MetalinkHttpParser::checkMetalinkHttp()
1351 {
1352  if (!m_Url.isValid()) {
1353  kDebug() << "Url not valid";
1354  return;
1355  }
1356 
1357  KIO::TransferJob *job;
1358  job = KIO::get(m_Url, KIO::NoReload, KIO::HideProgressInfo);
1359  job->addMetaData("PropagateHttpHeader", "true");
1360  job->setRedirectionHandlingEnabled(false);
1361  connect(job, SIGNAL(result(KJob*)), this, SLOT(slotHeaderResult(KJob*))); // Finished
1362  connect(job, SIGNAL(redirection(KIO::Job*,KUrl)), this, SLOT(slotRedirection(KIO::Job*,KUrl))); // Redirection
1363  connect(job,SIGNAL(mimetype(KIO::Job*,QString)),this,SLOT(detectMime(KIO::Job*,QString))); // Mime detection.
1364  kDebug() << " Verifying Metalink/HTTP Status" ;
1365  m_loop.exec();
1366 }
1367 
1368 void KGetMetalink::MetalinkHttpParser::detectMime(KIO::Job *job, const QString &type)
1369 {
1370  kDebug() << "Mime Type: " << type ;
1371  job->kill();
1372  m_loop.exit();
1373 }
1374 
1375 void KGetMetalink::MetalinkHttpParser::slotHeaderResult(KJob* kjob)
1376 {
1377  KIO::Job* job = qobject_cast<KIO::Job*>(kjob);
1378  const QString httpHeaders = job ? job->queryMetaData("HTTP-Headers") : QString();
1379  parseHeaders(httpHeaders);
1380  setMetalinkHSatus();
1381 
1382  // Handle the redirection... (Comment out if not desired)
1383  if (m_redirectionUrl.isValid()) {
1384  m_Url = m_redirectionUrl;
1385  m_redirectionUrl = KUrl();
1386  checkMetalinkHttp();
1387  }
1388 
1389  if (m_loop.isRunning())
1390  m_loop.exit();
1391 }
1392 
1393 void KGetMetalink::MetalinkHttpParser::slotRedirection(KIO::Job *job, const KUrl & url)
1394 {
1395  Q_UNUSED(job)
1396  m_redirectionUrl = url;
1397 }
1398 
1399 bool KGetMetalink::MetalinkHttpParser::isMetalinkHttp()
1400 {
1401  if (m_MetalinkHSatus) {
1402  kDebug() << "Metalink Http detected" ;
1403  }
1404  else {
1405  kDebug() << "No Metalink HTTP response found" ;
1406  }
1407  return m_MetalinkHSatus;
1408 }
1409 
1410 void KGetMetalink::MetalinkHttpParser::parseHeaders(const QString &httpHeader)
1411 {
1412  QString trimedHeader = httpHeader.mid(httpHeader.indexOf('\n') + 1).trimmed();
1413 
1414  foreach(QString line, trimedHeader.split('\n')) {
1415  int colon = line.indexOf(':');
1416  QString headerName = line.left(colon).trimmed();
1417  QString headerValue = line.mid(colon + 1).trimmed();
1418  m_headerInfo.insertMulti(headerName, headerValue);
1419  }
1420 
1421  m_EtagValue = m_headerInfo.value("ETag");
1422 }
1423 
1424 void KGetMetalink::MetalinkHttpParser::setMetalinkHSatus()
1425 {
1426  bool linkStatus, digestStatus;
1427  linkStatus = digestStatus = false;
1428  if (m_headerInfo.contains("link")) {
1429  QList<QString> linkValues = m_headerInfo.values("link");
1430 
1431  foreach(QString linkVal, linkValues) {
1432  if (linkVal.contains("rel=duplicate")) {
1433  linkStatus = true;
1434  break;
1435  }
1436  }
1437  }
1438 
1439  if (m_headerInfo.contains("digest")) {
1440  QList<QString> digestValues = m_headerInfo.values("digest");
1441 
1442  foreach(QString digestVal, digestValues) {
1443  if (digestVal.contains("sha-256", Qt::CaseInsensitive)) {
1444  digestStatus = true;
1445  break;
1446  }
1447  }
1448  }
1449 
1450  if ((linkStatus) && (digestStatus)) {
1451  m_MetalinkHSatus = true;
1452  }
1453 
1454 }
1455 
1456 KUrl KGetMetalink::MetalinkHttpParser::getUrl()
1457 {
1458  return m_Url;
1459 }
1460 
1461 QMultiMap<QString, QString>* KGetMetalink::MetalinkHttpParser::getHeaderInfo()
1462 {
1463  return & m_headerInfo;
1464 }
1465 
1466 KGetMetalink::HttpLinkHeader::HttpLinkHeader(const QString &headerLine)
1467  : pref(false)
1468 {
1469  parseHeaderLine(headerLine);
1470 }
1471 
1472 bool KGetMetalink::HttpLinkHeader::operator<(const HttpLinkHeader &other) const
1473 {
1474  return depth < other.depth;
1475 }
1476 
1477 void KGetMetalink::HttpLinkHeader::parseHeaderLine(const QString &line)
1478 {
1479  url = line.mid(line.indexOf("<") + 1,line.indexOf(">") -1).trimmed();
1480  const QList<QString> attribList = line.split(";");
1481 
1482  foreach (const QString str, attribList) {
1483  const QString attribId = str.mid(0,str.indexOf("=")).trimmed();
1484  const QString attribValue = str.mid(str.indexOf("=")+1).trimmed();
1485 
1486  if (attribId == "rel") {
1487  reltype = attribValue;
1488  }
1489  else if (attribId == "depth") {
1490  depth = attribValue.toInt();
1491  }
1492  else if (attribId == "geo") {
1493  geo = attribValue;
1494  }
1495  else if (attribId == "pref") {
1496  pref = true;
1497  }
1498  else if (attribId == "pri") {
1499  priority = attribValue.toUInt();
1500  }
1501  else if (attribId == "type") {
1502  type = attribValue;
1503  }
1504  else if (attribId == "name") {
1505  name = attribValue;
1506  }
1507  }
1508 }
1509 
1510 #include "metalinker.moc"
KGetMetalink::Metaurl::isValid
bool isValid()
Definition: metalinker.cpp:340
KGetMetalink::Files::load
void load(const QDomElement &e)
Definition: metalinker.cpp:659
KGetMetalink::CommonData::publisher
UrlText publisher
Definition: metalinker.h:116
KGetMetalink::addaptHashType
QString addaptHashType(const QString &type, bool loaded)
Adapts type to the way the hash is internally stored.
Definition: metalinker.cpp:60
KGetMetalink::HandleMetalink::load
static bool load(const KUrl &destination, Metalink *metalink)
Loads destination into metalink.
Definition: metalinker.cpp:1232
KGetMetalink::Metaurl
Definition: metalinker.h:120
KGetMetalink::CommonData::languages
QStringList languages
Definition: metalinker.h:115
KGetMetalink::HttpLinkHeader::operator<
bool operator<(const HttpLinkHeader &) const
Definition: metalinker.cpp:1472
KGetMetalink::Url::clear
void clear()
Definition: metalinker.cpp:400
KGetMetalink::MetalinkHttpParser
Definition: metalinker.h:419
KGetMetalink::File::resources
Resources resources
Definition: metalinker.h:272
KGetMetalink::DateConstruct::setData
void setData(const QDateTime &dateTime, const QTime &timeZoneOffset=QTime(), bool negativeOffset=false)
Definition: metalinker.cpp:75
KGetMetalink::CommonData::logo
KUrl logo
Definition: metalinker.h:114
KGetMetalink::DateConstruct::negativeOffset
bool negativeOffset
Definition: metalinker.h:70
KGetMetalink::Metalink::KGET_DESCRIPTION
static const QString KGET_DESCRIPTION
Definition: metalinker.h:331
KGetMetalink::Url::load
void load(const QDomElement &e)
Definition: metalinker.cpp:366
KGetMetalink::CommonData::save
void save(QDomElement &e) const
Definition: metalinker.cpp:177
KGetMetalink::MetalinkHttpParser::getEtag
QString * getEtag()
Definition: metalinker.cpp:1345
KGetMetalink::MetalinkHttpParser::getHeaderInfo
QMultiMap< QString, QString > * getHeaderInfo()
Definition: metalinker.cpp:1461
KGetMetalink::Url
Definition: metalinker.h:156
KGetMetalink::Resources::save
void save(QDomElement &e) const
Definition: metalinker.cpp:430
KGetMetalink::HttpLinkHeader::HttpLinkHeader
HttpLinkHeader(const QString &headerLine)
Definition: metalinker.cpp:1466
KGetMetalink::File::save
void save(QDomElement &e) const
Definition: metalinker.cpp:571
KGetMetalink::Verification::signatures
QHash< QString, QString > signatures
Definition: metalinker.h:236
KGetMetalink::Url::operator<
bool operator<(const Url &other) const
"smaller" urls are less important than larger, larger urls should be preffered
Definition: metalinker.cpp:353
KGetMetalink::CommonData::identity
QString identity
Definition: metalinker.h:110
KGetMetalink::Verification::load
void load(const QDomElement &e)
Definition: metalinker.cpp:488
KGetMetalink::Metalink_v3::load
void load(const QDomElement &e)
Definition: metalinker.cpp:790
KGetMetalink::Pieces::load
void load(const QDomElement &e)
Definition: metalinker.cpp:449
KGetMetalink::File
Definition: metalinker.h:239
KGetMetalink::UrlText::clear
void clear()
Definition: metalinker.cpp:150
KGetMetalink::Metalink_v3::setMetalink
void setMetalink(const Metalink &metalink)
Definition: metalinker.cpp:785
KGetMetalink::Verification::save
void save(QDomElement &e) const
Definition: metalinker.cpp:517
KGetMetalink::Url::priority
uint priority
the priority of the urls, 1 is highest priority, 999999 lowest default is 0 as in not set and thus is...
Definition: metalinker.h:180
KGetMetalink::Pieces::save
void save(QDomElement &e) const
Definition: metalinker.cpp:463
KGetMetalink::File::load
void load(const QDomElement &e)
Definition: metalinker.cpp:560
KGetMetalink::File::isValidNameAttribute
bool isValidNameAttribute() const
Controls if the name attribute is valid, i.e.
Definition: metalinker.cpp:605
KGetMetalink::CommonData::load
void load(const QDomElement &e)
Definition: metalinker.cpp:156
KGetMetalink::DateConstruct::isNull
bool isNull() const
Definition: metalinker.cpp:112
KGetMetalink::Metalink::save
QDomDocument save() const
Save the metalink.
Definition: metalinker.cpp:722
KGetMetalink::Url::location
QString location
the location of the server eg.
Definition: metalinker.h:185
KGetMetalink::Resources::clear
void clear()
Definition: metalinker.cpp:443
KGetMetalink::UrlText::isEmpty
bool isEmpty() const
Definition: metalinker.h:81
KGetMetalink::CommonData::clear
void clear()
Definition: metalinker.cpp:240
KGetMetalink::HandleMetalink::save
static bool save(const KUrl &destination, Metalink *metalink)
Saves metalink to destination.
Definition: metalinker.cpp:1296
KGetMetalink::Files::clear
void clear()
Return all Nepomuk-properties that can be extracted of Files only Files is being looked at...
Definition: metalinker.cpp:682
KGetMetalink::File::clear
void clear()
Definition: metalinker.cpp:595
KGetMetalink::Verification::clear
void clear()
Definition: metalinker.cpp:549
metalinker.h
KGetMetalink::Resources::load
void load(const QDomElement &e)
Definition: metalinker.cpp:407
KGetMetalink::Metaurl::operator<
bool operator<(const Metaurl &other) const
"smaller" urls are less important than larger, larger urls should be preffered
Definition: metalinker.cpp:304
KGetMetalink::Url::isValid
bool isValid()
Definition: metalinker.cpp:395
KGetMetalink::Metalink
Definition: metalinker.h:299
KGetMetalink::Resources::urls
QList< Url > urls
Definition: metalinker.h:202
KGetMetalink::Metaurl::save
void save(QDomElement &e) const
Definition: metalinker.cpp:320
KGetMetalink::Pieces::clear
void clear()
Definition: metalinker.cpp:481
KGetMetalink::HttpLinkHeader::parseHeaderLine
void parseHeaderLine(const QString &)
Loads information from a header value into metalink header structure.
Definition: metalinker.cpp:1477
KGetMetalink::Metalink_v3::save
QDomDocument save() const
Save the metalink.
Definition: metalinker.cpp:1032
KGetMetalink::Metalink::MAX_URL_PRIORITY
static const uint MAX_URL_PRIORITY
Definition: metalinker.h:332
KGetMetalink::CommonData
Files, File and Metadata contain this Metadata not as member and only for compatibility.
Definition: metalinker.h:93
KGetMetalink::Metaurl::priority
uint priority
the priority of the urls, 1 is highest priority, 999999 lowest default is 0 as in not set and thus is...
Definition: metalinker.h:146
KGetMetalink::Metalink::clear
void clear()
Definition: metalinker.cpp:765
KGetMetalink::Url::save
void save(QDomElement &e) const
Definition: metalinker.cpp:376
KGetMetalink::CommonData::copyright
QString copyright
Definition: metalinker.h:117
KGetMetalink::CommonData::oses
QStringList oses
Definition: metalinker.h:113
KGetMetalink::DateConstruct::toString
QString toString() const
Definition: metalinker.cpp:122
KGetMetalink::Pieces
Definition: metalinker.h:206
KGetMetalink::HttpLinkHeader::depth
int depth
Definition: metalinker.h:485
KGetMetalink::MetalinkHttpParser::~MetalinkHttpParser
~MetalinkHttpParser()
Definition: metalinker.cpp:1340
KGetMetalink::File::name
QString name
Definition: metalinker.h:268
KGetMetalink::CommonData::version
QString version
Definition: metalinker.h:111
KGetMetalink::Verification::hashes
QHash< QString, QString > hashes
Definition: metalinker.h:234
KGetMetalink::DateConstruct::clear
void clear()
Definition: metalinker.cpp:144
KGetMetalink::Files::save
void save(QDomElement &e) const
Definition: metalinker.cpp:669
KGetMetalink::Metalink_v3::metalink
Metalink metalink()
Definition: metalinker.cpp:780
KGetMetalink::Metalink::isValid
bool isValid() const
checks if the minimum requirements of a metalink are met
Definition: metalinker.cpp:687
KGetMetalink::HttpLinkHeader
Definition: metalinker.h:478
KGetMetalink::DateConstruct::isValid
bool isValid() const
Definition: metalinker.cpp:117
KGetMetalink::Metalink_v3
Metalink version 3.0 2nd ed Used only for loading and saving, uses itself Metalink internally...
Definition: metalinker.h:340
KGetMetalink::DateConstruct
Definition: metalinker.h:50
KGetMetalink::MetalinkHttpParser::getUrl
KUrl getUrl()
Definition: metalinker.cpp:1456
KGetMetalink::DateConstruct::dateTime
QDateTime dateTime
Definition: metalinker.h:68
KGetMetalink::Resources
Definition: metalinker.h:190
KGetMetalink::File::verification
Verification verification
Definition: metalinker.h:269
KGetMetalink::Verification::pieces
QList< Pieces > pieces
Definition: metalinker.h:235
KGetMetalink::CommonData::description
QString description
Definition: metalinker.h:112
KGetMetalink::Metaurl::load
void load(const QDomElement &e)
Definition: metalinker.cpp:309
KGetMetalink::Files::isValid
bool isValid() const
Definition: metalinker.cpp:633
KGetMetalink::File::isValid
bool isValid() const
Definition: metalinker.cpp:555
KGetMetalink::Metaurl::clear
void clear()
Definition: metalinker.cpp:345
KGetMetalink::Metalink_v3::Metalink_v3
Metalink_v3()
Definition: metalinker.cpp:776
KGetMetalink::DateConstruct::timeZoneOffset
QTime timeZoneOffset
Definition: metalinker.h:69
KGetMetalink::Metalink::load
void load(const QDomElement &e)
Definition: metalinker.cpp:699
KGetMetalink::Verification
Definition: metalinker.h:224
KJob
KGetMetalink::File::size
KIO::filesize_t size
Definition: metalinker.h:270
KGetMetalink::File::data
CommonData data
Definition: metalinker.h:271
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