MythTV  master
rssparse.cpp
Go to the documentation of this file.
1 #include <QFile>
2 #include <QDataStream>
3 #include <QDomDocument>
4 #include <QDomImplementation>
5 #include <QHash>
6 #include <QLocale>
7 #include <QUrl>
8 #include <QFileInfo>
9 #include <QRegExp>
10 
11 #include "rssparse.h"
12 #include "mythcontext.h"
13 #include "mythdirs.h"
14 #include "mythdate.h"
15 #include "programinfo.h" // for format_season_and_episode()
16 #include "mythsorthelper.h"
17 
18 ResultItem::ResultItem(const QString& title, const QString& sortTitle,
19  const QString& subtitle, const QString& sortSubtitle,
20  const QString& desc, const QString& URL,
21  const QString& thumbnail, const QString& mediaURL,
22  const QString& author, const QDateTime& date,
23  const QString& time, const QString& rating,
24  const off_t& filesize, const QString& player,
25  const QStringList& playerargs, const QString& download,
26  const QStringList& downloadargs, const uint& width,
27  const uint& height, const QString& language,
28  const bool& downloadable, const QStringList& countries,
29  const uint& season, const uint& episode,
30  const bool& customhtml)
31 {
32  m_title = title;
33  m_sorttitle = sortTitle;
34  m_subtitle = subtitle;
35  m_sortsubtitle = sortSubtitle;
36  m_desc = desc;
37  m_url = URL;
38  m_thumbnail = thumbnail;
39  m_mediaURL = mediaURL;
40  m_author = author;
41  if (!date.isNull())
42  m_date = date;
43  else
44  m_date = QDateTime();
45  m_time = time;
46  m_rating = rating;
47  m_filesize = filesize;
48  m_player = player;
49  m_playerargs = playerargs;
50  m_download = download;
51  m_downloadargs = downloadargs;
52  m_width = width;
53  m_height = height;
54  m_language = language;
55  m_downloadable = downloadable;
57  m_season = season;
58  m_episode = episode;
59  m_customhtml = customhtml;
60 
62 }
63 
65 {
66  std::shared_ptr<MythSortHelper>sh = getMythSortHelper();
67 
68  if (m_sorttitle.isEmpty() and not m_title.isEmpty())
69  m_sorttitle = sh->doTitle(m_title);
70  if (m_sortsubtitle.isEmpty() and not m_subtitle.isEmpty())
71  m_sortsubtitle = sh->doTitle(m_subtitle);
72 }
73 
74 void ResultItem::toMap(InfoMap &metadataMap)
75 {
76  metadataMap["title"] = m_title;
77  metadataMap["sorttitle"] = m_sorttitle;
78  metadataMap["subtitle"] = m_subtitle;
79  metadataMap["sortsubtitle"] = m_sortsubtitle;
80  metadataMap["description"] = m_desc;
81  metadataMap["url"] = m_url;
82  metadataMap["thumbnail"] = m_thumbnail;
83  metadataMap["mediaurl"] = m_mediaURL;
84  metadataMap["author"] = m_author;
85 
86  if (m_date.isNull())
87  metadataMap["date"] = QString();
88  else
89  metadataMap["date"] = MythDate::toString(m_date, MythDate::kDateFull);
90 
91  if (m_time.toInt() == 0)
92  metadataMap["length"] = QString();
93  else
94  {
95  QTime time(0,0,0,0);
96  int secs = m_time.toInt();
97  QTime fin = time.addSecs(secs);
98  QString format;
99  if (secs >= 3600)
100  format = "H:mm:ss";
101  else if (secs >= 600)
102  format = "mm:ss";
103  else if (secs >= 60)
104  format = "m:ss";
105  else
106  format = ":ss";
107  metadataMap["length"] = fin.toString(format);
108  }
109 
110  if (m_rating == nullptr || m_rating.isNull())
111  metadataMap["rating"] = QString();
112  else
113  metadataMap["rating"] = m_rating;
114 
115  if (m_filesize == -1)
116  metadataMap["filesize"] = QString();
117  else if (m_filesize == 0 && !m_downloadable)
118  metadataMap["filesize"] = QObject::tr("Web Only");
119  else if (m_filesize == 0 && m_downloadable)
120  metadataMap["filesize"] = QObject::tr("Downloadable");
121  else
122  metadataMap["filesize"] = QString::number(m_filesize);
123 
124  QString tmpSize = QString("%1 ")
125  .arg(m_filesize / 1024.0 / 1024.0, 0,'f',2);
126  tmpSize += QObject::tr("MB", "Megabytes");
127  if (m_filesize == -1)
128  metadataMap["filesize_str"] = QString();
129  else if (m_filesize == 0 && !m_downloadable)
130  metadataMap["filesize_str"] = QObject::tr("Web Only");
131  else if (m_filesize == 0 && m_downloadable)
132  metadataMap["filesize_str"] = QObject::tr("Downloadable");
133  else
134  metadataMap["filesize"] = tmpSize;
135 
136  metadataMap["player"] = m_player;
137  metadataMap["playerargs"] = m_playerargs.join(", ");
138  metadataMap["downloader"] = m_download;
139  metadataMap["downloadargs"] = m_downloadargs.join(", ");
140  if (m_width == 0)
141  metadataMap["width"] = QString();
142  else
143  metadataMap["width"] = QString::number(m_width);
144  if (m_height == 0)
145  metadataMap["height"] = QString();
146  else
147  metadataMap["height"] = QString::number(m_height);
148  if (m_width == 0 || m_height == 0)
149  metadataMap["resolution"] = QString();
150  else
151  metadataMap["resolution"] = QString("%1x%2").arg(m_width).arg(m_height);
152  metadataMap["language"] = m_language;
153  metadataMap["countries"] = m_countries.join(", ");
154 
155 
156  if (m_season > 0 || m_episode > 0)
157  {
158  metadataMap["season"] = format_season_and_episode(m_season, 1);
159  metadataMap["episode"] = format_season_and_episode(m_episode, 1);
160  metadataMap["s##e##"] = metadataMap["s00e00"] = QString("s%1e%2")
163  metadataMap["##x##"] = metadataMap["00x00"] = QString("%1x%2")
166  }
167  else
168  {
169  metadataMap["season"] = QString();
170  metadataMap["episode"] = QString();
171  metadataMap["s##e##"] = metadataMap["s00e00"] = QString();
172  metadataMap["##x##"] = metadataMap["00x00"] = QString();
173  }
174 }
175 
176 namespace
177 {
178  QList<QDomNode> GetDirectChildrenNS(const QDomElement& elem,
179  const QString& ns, const QString& name)
180  {
181  QList<QDomNode> result;
182  QDomNodeList unf = elem.elementsByTagNameNS(ns, name);
183  for (int i = 0, size = unf.size(); i < size; ++i)
184  if (unf.at(i).parentNode() == elem)
185  result << unf.at(i);
186  return result;
187  }
188 }
189 
191 {
193  {
194  QString m_url;
195  QString m_rating;
196  QString m_ratingScheme;
197  QString m_title;
198  QString m_description;
199  QString m_keywords;
200  QString m_copyrightUrl;
203  int m_ratingCount {0};
204  int m_ratingMin {0};
205  int m_ratingMax {0};
206  int m_views {0};
207  int m_favs {0};
208  QString m_tags;
209  QList<MRSSThumbnail> m_thumbnails;
210  QList<MRSSCredit> m_credits;
211  QList<MRSSComment> m_comments;
212  QList<MRSSPeerLink> m_peerLinks;
213  QList<MRSSScene> m_scenes;
214 
215  ArbitraryLocatedData() = default;
216 
221  {
222  if (!child.m_url.isEmpty())
223  m_url = child.m_url;
224  if (!child.m_rating.isEmpty())
225  m_rating = child.m_rating;
226  if (!child.m_ratingScheme.isEmpty())
228  if (!child.m_title.isEmpty())
229  m_title = child.m_title;
230  if (!child.m_description.isEmpty())
232  if (!child.m_keywords.isEmpty())
233  m_keywords = child.m_keywords;
234  if (!child.m_copyrightUrl.isEmpty())
236  if (!child.m_copyrightText.isEmpty())
238  if (child.m_ratingAverage != 0)
240  if (child.m_ratingCount != 0)
242  if (child.m_ratingMin != 0)
243  m_ratingMin = child.m_ratingMin;
244  if (child.m_ratingMax != 0)
245  m_ratingMax = child.m_ratingMax;
246  if (child.m_views != 0)
247  m_views = child.m_views;
248  if (child.m_favs != 0)
249  m_favs = child.m_favs;
250  if (!child.m_tags.isEmpty())
251  m_tags = child.m_tags;
252 
253  m_thumbnails += child.m_thumbnails;
254  m_credits += child.m_credits;
255  m_comments += child.m_comments;
256  m_peerLinks += child.m_peerLinks;
257  m_scenes += child.m_scenes;
258  return *this;
259  }
260  };
261 
262 
263 public:
264  MRSSParser() = default;
265 
266  QList<MRSSEntry> operator() (const QDomElement& item)
267  {
268  QList<MRSSEntry> result;
269 
270  QDomNodeList groups = item.elementsByTagNameNS(Parse::kMediaRSS,
271  "group");
272 
273  for (int i = 0; i < groups.size(); ++i)
274  result += CollectChildren(groups.at(i).toElement());
275 
276  result += CollectChildren(item);
277 
278  return result;
279  }
280 
281 private:
282 
283  static QList<MRSSEntry> CollectChildren(const QDomElement& holder)
284  {
285  QList<MRSSEntry> result;
286  QDomNodeList entries = holder.elementsByTagNameNS(Parse::kMediaRSS,
287  "content");
288 
289  for (int i = 0; i < entries.size(); ++i)
290  {
291  MRSSEntry entry;
292 
293  QDomElement en = entries.at(i).toElement();
295 
296  if (en.hasAttribute("url"))
297  entry.URL = en.attribute("url");
298  else
299  entry.URL = d.m_url;
300 
301  entry.Size = en.attribute("fileSize").toInt();
302  entry.Type = en.attribute("type");
303  entry.Medium = en.attribute("medium");
304  entry.IsDefault = (en.attribute("isDefault") == "true");
305  entry.Expression = en.attribute("expression");
306  if (entry.Expression.isEmpty())
307  entry.Expression = "full";
308  entry.Bitrate = en.attribute("bitrate").toInt();
309  entry.Framerate = en.attribute("framerate").toDouble();
310  entry.SamplingRate = en.attribute("samplingrate").toDouble();
311  entry.Channels = en.attribute("channels").toInt();
312  if (!en.attribute("duration").isNull())
313  entry.Duration = en.attribute("duration").toInt();
314  else
315  entry.Duration = 0;
316  if (!en.attribute("width").isNull())
317  entry.Width = en.attribute("width").toInt();
318  else
319  entry.Width = 0;
320  if (!en.attribute("height").isNull())
321  entry.Height = en.attribute("height").toInt();
322  else
323  entry.Height = 0;
324  if (!en.attribute("lang").isNull())
325  entry.Lang = en.attribute("lang");
326  else
327  entry.Lang = QString();
328 
329  if (!en.attribute("rating").isNull())
330  entry.Rating = d.m_rating;
331  else
332  entry.Rating = QString();
333  entry.RatingScheme = d.m_ratingScheme;
334  entry.Title = d.m_title;
335  entry.Description = d.m_description;
336  entry.Keywords = d.m_keywords;
337  entry.CopyrightURL = d.m_copyrightUrl;
338  entry.CopyrightText = d.m_copyrightText;
339  if (d.m_ratingAverage != 0)
340  entry.RatingAverage = d.m_ratingAverage;
341  else
342  entry.RatingAverage = 0;
343  entry.RatingCount = d.m_ratingCount;
344  entry.RatingMin = d.m_ratingMin;
345  entry.RatingMax = d.m_ratingMax;
346  entry.Views = d.m_views;
347  entry.Favs = d.m_favs;
348  entry.Tags = d.m_tags;
349  entry.Thumbnails = d.m_thumbnails;
350  entry.Credits = d.m_credits;
351  entry.Comments = d.m_comments;
352  entry.PeerLinks = d.m_peerLinks;
353  entry.Scenes = d.m_scenes;
354 
355  result << entry;
356  }
357  return result;
358  }
359 
360  static ArbitraryLocatedData GetArbitraryLocatedDataFor(const QDomElement& holder)
361  {
362  ArbitraryLocatedData result;
363 
364  QList<QDomElement> parents;
365  QDomElement parent = holder;
366  while (!parent.isNull())
367  {
368  parents.prepend(parent);
369  parent = parent.parentNode().toElement();
370  }
371 
372  for (const auto& p : qAsConst(parents))
373  result += CollectArbitraryLocatedData(p);
374 
375  return result;
376  }
377 
378  static QString GetURL(const QDomElement& element)
379  {
380  QList<QDomNode> elems = GetDirectChildrenNS(element, Parse::kMediaRSS,
381  "player");
382  if (elems.empty())
383  return QString();
384 
385  return elems.at(0).toElement().attribute("url");
386  }
387 
388  static QString GetTitle(const QDomElement& element)
389  {
390  QList<QDomNode> elems = GetDirectChildrenNS(element, Parse::kMediaRSS,
391  "title");
392 
393  if (elems.empty())
394  return QString();
395 
396  QDomElement telem = elems.at(0).toElement();
397  return Parse::UnescapeHTML(telem.text());
398  }
399 
400  static QString GetDescription(const QDomElement& element)
401  {
402  QList<QDomNode> elems = GetDirectChildrenNS(element, Parse::kMediaRSS,
403  "description");
404 
405  if (elems.empty())
406  return QString();
407 
408  QDomElement telem = elems.at(0).toElement();
409  return Parse::UnescapeHTML(telem.text());
410  }
411 
412  static QString GetKeywords(const QDomElement& element)
413  {
414  QList<QDomNode> elems = GetDirectChildrenNS(element, Parse::kMediaRSS,
415  "keywords");
416 
417  if (elems.empty())
418  return QString();
419 
420  QDomElement telem = elems.at(0).toElement();
421  return telem.text();
422  }
423 
424  static int GetInt(const QDomElement& elem, const QString& attrname)
425  {
426  if (elem.hasAttribute(attrname))
427  {
428  bool ok = false;
429  int result = elem.attribute(attrname).toInt(&ok);
430  if (ok)
431  return result;
432  }
433  return int();
434  }
435 
436  static QList<MRSSThumbnail> GetThumbnails(const QDomElement& element)
437  {
438  QList<MRSSThumbnail> result;
439  QList<QDomNode> thumbs = GetDirectChildrenNS(element, Parse::kMediaRSS,
440  "thumbnail");
441  for (const auto& dom : qAsConst(thumbs))
442  {
443  QDomElement thumbNode = dom.toElement();
444  int widthOpt = GetInt(thumbNode, "width");
445  int width = widthOpt ? widthOpt : 0;
446  int heightOpt = GetInt(thumbNode, "height");
447  int height = heightOpt ? heightOpt : 0;
448  MRSSThumbnail thumb =
449  {
450  thumbNode.attribute("url"),
451  width,
452  height,
453  thumbNode.attribute("time")
454  };
455  result << thumb;
456  }
457  return result;
458  }
459 
460  static QList<MRSSCredit> GetCredits(const QDomElement& element)
461  {
462  QList<MRSSCredit> result;
463  QList<QDomNode> credits = GetDirectChildrenNS(element, Parse::kMediaRSS,
464  "credit");
465 
466  for (const auto& dom : qAsConst(credits))
467  {
468  QDomElement creditNode = dom.toElement();
469  if (!creditNode.hasAttribute("role"))
470  continue;
471  MRSSCredit credit =
472  {
473  creditNode.attribute("role"),
474  creditNode.text()
475  };
476  result << credit;
477  }
478  return result;
479  }
480 
481  static QList<MRSSComment> GetComments(const QDomElement& element)
482  {
483  QList<MRSSComment> result;
484  QList<QDomNode> commParents = GetDirectChildrenNS(element, Parse::kMediaRSS,
485  "comments");
486 
487  if (!commParents.empty())
488  {
489  QDomNodeList comments = commParents.at(0).toElement()
490  .elementsByTagNameNS(Parse::kMediaRSS,
491  "comment");
492  for (int i = 0; i < comments.size(); ++i)
493  {
494  MRSSComment comment =
495  {
496  QObject::tr("Comments"),
497  comments.at(i).toElement().text()
498  };
499  result << comment;
500  }
501  }
502 
503  QList<QDomNode> respParents = GetDirectChildrenNS(element, Parse::kMediaRSS,
504  "responses");
505 
506  if (!respParents.empty())
507  {
508  QDomNodeList responses = respParents.at(0).toElement()
509  .elementsByTagNameNS(Parse::kMediaRSS,
510  "response");
511  for (int i = 0; i < responses.size(); ++i)
512  {
513  MRSSComment comment =
514  {
515  QObject::tr("Responses"),
516  responses.at(i).toElement().text()
517  };
518  result << comment;
519  }
520  }
521 
522  QList<QDomNode> backParents = GetDirectChildrenNS(element, Parse::kMediaRSS,
523  "backLinks");
524 
525  if (!backParents.empty())
526  {
527  QDomNodeList backlinks = backParents.at(0).toElement()
528  .elementsByTagNameNS(Parse::kMediaRSS,
529  "backLink");
530  for (int i = 0; i < backlinks.size(); ++i)
531  {
532  MRSSComment comment =
533  {
534  QObject::tr("Backlinks"),
535  backlinks.at(i).toElement().text()
536  };
537  result << comment;
538  }
539  }
540  return result;
541  }
542 
543  static QList<MRSSPeerLink> GetPeerLinks(const QDomElement& element)
544  {
545  QList<MRSSPeerLink> result;
546  QList<QDomNode> links = GetDirectChildrenNS(element, Parse::kMediaRSS,
547  "peerLink");
548 
549  for (const auto& dom : qAsConst(links))
550  {
551  QDomElement linkNode = dom.toElement();
552  MRSSPeerLink pl =
553  {
554  linkNode.attribute("type"),
555  linkNode.attribute("href")
556  };
557  result << pl;
558  }
559  return result;
560  }
561 
562  static QList<MRSSScene> GetScenes(const QDomElement& element)
563  {
564  QList<MRSSScene> result;
565  QList<QDomNode> scenesNode = GetDirectChildrenNS(element, Parse::kMediaRSS,
566  "scenes");
567 
568  if (!scenesNode.empty())
569  {
570  QDomNodeList scenesNodes = scenesNode.at(0).toElement()
571  .elementsByTagNameNS(Parse::kMediaRSS, "scene");
572 
573  for (int i = 0; i < scenesNodes.size(); ++i)
574  {
575  QDomElement sceneNode = scenesNodes.at(i).toElement();
576  MRSSScene scene =
577  {
578  sceneNode.firstChildElement("sceneTitle").text(),
579  sceneNode.firstChildElement("sceneDescription").text(),
580  sceneNode.firstChildElement("sceneStartTime").text(),
581  sceneNode.firstChildElement("sceneEndTime").text()
582  };
583  result << scene;
584  }
585  }
586  return result;
587  }
588 
589  static ArbitraryLocatedData CollectArbitraryLocatedData(const QDomElement& element)
590  {
591 
592  QString rating;
593  QString rscheme;
594  {
595  QList<QDomNode> elems = GetDirectChildrenNS(element, Parse::kMediaRSS,
596  "rating");
597 
598  if (!elems.empty())
599  {
600  QDomElement relem = elems.at(0).toElement();
601  rating = relem.text();
602  if (relem.hasAttribute("scheme"))
603  rscheme = relem.attribute("scheme");
604  else
605  rscheme = "urn:simple";
606  }
607  }
608 
609  QString curl;
610  QString ctext;
611  {
612  QList<QDomNode> elems = GetDirectChildrenNS(element, Parse::kMediaRSS,
613  "copyright");
614 
615  if (!elems.empty())
616  {
617  QDomElement celem = elems.at(0).toElement();
618  ctext = celem.text();
619  if (celem.hasAttribute("url"))
620  curl = celem.attribute("url");
621  }
622  }
623 
624  int raverage = 0;
625  int rcount = 0;
626  int rmin = 0;
627  int rmax = 0;
628  int views = 0;
629  int favs = 0;
630  QString tags;
631  {
632  QList<QDomNode> comms = GetDirectChildrenNS(element, Parse::kMediaRSS,
633  "community");
634  if (!comms.empty())
635  {
636  QDomElement comm = comms.at(0).toElement();
637  QDomNodeList stars = comm.elementsByTagNameNS(Parse::kMediaRSS,
638  "starRating");
639  if (stars.size())
640  {
641  QDomElement ratingDom = stars.at(0).toElement();
642  raverage = GetInt(ratingDom, "average");
643  rcount = GetInt(ratingDom, "count");
644  rmin = GetInt(ratingDom, "min");
645  rmax = GetInt(ratingDom, "max");
646  }
647 
648  QDomNodeList stats = comm.elementsByTagNameNS(Parse::kMediaRSS,
649  "statistics");
650  if (stats.size())
651  {
652  QDomElement stat = stats.at(0).toElement();
653  views = GetInt(stat, "views");
654  favs = GetInt(stat, "favorites");
655  }
656 
657  QDomNodeList tagsNode = comm.elementsByTagNameNS(Parse::kMediaRSS,
658  "tags");
659  if (tagsNode.size())
660  {
661  QDomElement tag = tagsNode.at(0).toElement();
662  tags = tag.text();
663  }
664  }
665  }
666 
667  ArbitraryLocatedData result;
668  result.m_url = GetURL(element);
669  result.m_rating = rating;
670  result.m_ratingScheme = rscheme;
671  result.m_title = GetTitle(element);
672  result.m_description = GetDescription(element);
673  result.m_keywords = GetKeywords(element);
674  result.m_copyrightUrl = curl;
675  result.m_copyrightText = ctext;
676  result.m_ratingAverage = raverage;
677  result.m_ratingCount = rcount;
678  result.m_ratingMin = rmin;
679  result.m_ratingMax = rmax;
680  result.m_views = views;
681  result.m_favs = favs;
682  result.m_tags = tags;
683  result.m_thumbnails = GetThumbnails(element);
684  result.m_credits = GetCredits(element);
685  result.m_comments = GetComments(element);
686  result.m_peerLinks = GetPeerLinks(element);
687  result.m_scenes = GetScenes(element);
688 
689  return result;
690  }
691 };
692 
693 
694 //========================================================================================
695 // Search Construction, Destruction
696 //========================================================================================
697 
698 const QString Parse::kDC = "http://purl.org/dc/elements/1.1/";
699 const QString Parse::kWFW = "http://wellformedweb.org/CommentAPI/";
700 const QString Parse::kAtom = "http://www.w3.org/2005/Atom";
701 const QString Parse::kRDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
702 const QString Parse::kSlash = "http://purl.org/rss/1.0/modules/slash/";
703 const QString Parse::kEnc = "http://purl.oclc.org/net/rss_2.0/enc#";
704 const QString Parse::kITunes = "http://www.itunes.com/dtds/podcast-1.0.dtd";
705 const QString Parse::kGeoRSSSimple = "http://www.georss.org/georss";
706 const QString Parse::kGeoRSSW3 = "http://www.w3.org/2003/01/geo/wgs84_pos#";
707 const QString Parse::kMediaRSS = "http://search.yahoo.com/mrss/";
708 const QString Parse::kMythRSS = "http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format";
709 
710 ResultItem::resultList Parse::parseRSS(const QDomDocument& domDoc) const
711 {
713 
714  QString document = domDoc.toString();
715  LOG(VB_GENERAL, LOG_DEBUG, "Will Be Parsing: " + document);
716 
717  QDomElement root = domDoc.documentElement();
718  QDomElement channel = root.firstChildElement("channel");
719  while (!channel.isNull())
720  {
721  QDomElement item = channel.firstChildElement("item");
722  while (!item.isNull())
723  {
724  vList.append(ParseItem(item));
725  item = item.nextSiblingElement("item");
726  }
727  channel = channel.nextSiblingElement("channel");
728  }
729 
730  return vList;
731 }
732 
733 ResultItem* Parse::ParseItem(const QDomElement& item) const
734 {
735  QString title("");
736  QString subtitle("");
737  QString description("");
738  QString url("");
739  QString author("");
740  QString duration("");
741  QString rating("");
742  QString thumbnail("");
743  QString mediaURL("");
744  QString player("");
745  QString language("");
746  QString download("");
747  off_t filesize = 0;
748  uint width = 0;
749  uint height = 0;
750  uint season = 0;
751  uint episode = 0;
752  QDateTime date;
753  QStringList playerargs;
754  QStringList downloadargs;
755  QStringList countries;
756  bool downloadable = true;
757  bool customhtml = false;
758 
759  // Get the title of the article/video
760  title = item.firstChildElement("title").text();
762  if (title.isEmpty())
763  title = "";
764 
765  // Get the subtitle of this item.
766  QDomNodeList subt = item.elementsByTagNameNS(kMythRSS, "subtitle");
767  if (subt.size())
768  {
769  subtitle = subt.at(0).toElement().text();
770  }
771 
772  // Parse the description of the article/video
773  QDomElement descriptiontemp = item.firstChildElement("description");
774  if (!descriptiontemp.isNull())
775  description = descriptiontemp.text();
776  if (description.isEmpty())
777  {
778  QDomNodeList nodes = item.elementsByTagNameNS(kITunes, "summary");
779  if (nodes.size())
780  description = nodes.at(0).toElement().text();
781  }
782  // Unescape and remove HTML tags from the description.
783  if (description.isEmpty())
784  description = "";
785  else
786  description = UnescapeHTML(description);
787 
788  // Get the link (web playable)
789  url = item.firstChildElement("link").text();
790 
791  // Parse the item author
792  QDomElement authortemp = item.firstChildElement("author");
793  if (!authortemp.isNull())
794  author = authortemp.text();
795  if (author.isEmpty())
796  author = GetAuthor(item);
797 
798  // Turn the RFC-822 pubdate into a QDateTime
799  date = RFC822TimeToQDateTime(item.firstChildElement("pubDate").text());
800  if (!date.isValid() || date.isNull())
801  date = GetDCDateTime(item);
802  if (!date.isValid() || date.isNull())
803  date = MythDate::current();
804 
805  // Parse the insane iTunes duration (HH:MM:SS or H:MM:SS or MM:SS or M:SS or SS)
806  QDomNodeList dur = item.elementsByTagNameNS(kITunes, "duration");
807  if (dur.size())
808  {
809  QString itunestime = dur.at(0).toElement().text();
810  QString dateformat;
811 
812  if (itunestime.count() == 8)
813  dateformat = "hh:mm:ss";
814  else if (itunestime.count() == 7)
815  dateformat = "h:mm:ss";
816  else if (itunestime.count() == 5)
817  dateformat = "mm:ss";
818  else if (itunestime.count() == 4)
819  dateformat = "m:ss";
820  else if (itunestime.count() == 2)
821  dateformat = "ss";
822  else
823  duration = "0";
824 
825  if (!dateformat.isNull())
826  {
827  QTime itime = QTime::fromString(itunestime, dateformat);
828  if (itime.isValid())
829  {
830  int seconds = itime.second() + (itime.minute() * 60) + (itime.hour() * 3600);
831  duration = QString::number(seconds);
832  }
833  }
834  }
835 
836  // Get the rating
837  QDomElement ratingtemp = item.firstChildElement("rating");
838  if (!ratingtemp.isNull())
839  rating = ratingtemp.text();
840 
841  // Get the external player binary
842  QDomElement playertemp = item.firstChildElement("player");
843  if (!playertemp.isNull())
844  player = playertemp.text();
845 
846  // Get the arguments to pass to the external player
847  QDomElement playerargstemp = item.firstChildElement("playerargs");
848  if (!playerargstemp.isNull())
849  playerargs = playerargstemp.text().split(" ");
850 
851  // Get the external downloader binary/script
852  QDomElement downloadtemp = item.firstChildElement("download");
853  if (!downloadtemp.isNull())
854  download = downloadtemp.text();
855 
856  // Get the arguments to pass to the external downloader
857  QDomElement downloadargstemp = item.firstChildElement("downloadargs");
858  if (!downloadargstemp.isNull())
859  downloadargs = downloadargstemp.text().split(" ");
860 
861  // Get the countries in which this item is playable
862  QDomNodeList cties = item.elementsByTagNameNS(kMythRSS, "country");
863  if (cties.size())
864  {
865  int i = 0;
866  while (i < cties.size())
867  {
868  countries.append(cties.at(i).toElement().text());
869  i++;
870  }
871  }
872 
873  // Get the season number of this item.
874  QDomNodeList seas = item.elementsByTagNameNS(kMythRSS, "season");
875  if (seas.size())
876  {
877  season = seas.at(0).toElement().text().toUInt();
878  }
879 
880  // Get the Episode number of this item.
881  QDomNodeList ep = item.elementsByTagNameNS(kMythRSS, "episode");
882  if (ep.size())
883  {
884  episode = ep.at(0).toElement().text().toUInt();
885  }
886 
887  // Does this grabber return custom HTML?
888  QDomNodeList html = item.elementsByTagNameNS(kMythRSS, "customhtml");
889  if (html.size())
890  {
891  QString htmlstring = html.at(0).toElement().text();
892  if (htmlstring.contains("true", Qt::CaseInsensitive) || htmlstring == "1" ||
893  htmlstring.contains("yes", Qt::CaseInsensitive))
894  customhtml = true;
895  }
896 
897  QList<MRSSEntry> enclosures = GetMediaRSS(item);
898 
899  if (!enclosures.empty())
900  {
901  MRSSEntry media = enclosures.takeAt(0);
902 
903  QList<MRSSThumbnail> thumbs = media.Thumbnails;
904  if (!thumbs.empty())
905  {
906  MRSSThumbnail thumb = thumbs.takeAt(0);
907  thumbnail = thumb.URL;
908  }
909 
910  mediaURL = media.URL;
911 
912  width = media.Width;
913  height = media.Height;
914  language = media.Lang;
915 
916  if (duration.isEmpty())
917  duration = QString::number(media.Duration);
918 
919  if (filesize == 0)
920  filesize = media.Size;
921 
922  if (rating.isEmpty())
923  rating = QString::number(media.RatingAverage);
924  }
925  if (mediaURL.isEmpty())
926  {
927  QList<Enclosure> stdEnc = GetEnclosures(item);
928 
929  if (!stdEnc.empty())
930  {
931  Enclosure e = stdEnc.takeAt(0);
932 
933  mediaURL = e.URL;
934 
935  if (filesize == 0)
936  filesize = e.Length;
937  }
938  }
939 
940  if (mediaURL.isNull() || mediaURL == url)
941  downloadable = false;
942 
943  std::shared_ptr<MythSortHelper>sh = getMythSortHelper();
944  return(new ResultItem(title, sh->doTitle(title),
945  subtitle, sh->doTitle(subtitle), description,
946  url, thumbnail, mediaURL, author, date, duration,
947  rating, filesize, player, playerargs,
948  download, downloadargs, width, height,
949  language, downloadable, countries, season,
950  episode, customhtml));
951 }
952 
953 QString Parse::GetLink(const QDomElement& parent)
954 {
955  QString result;
956  QDomElement link = parent.firstChildElement("link");
957  while(!link.isNull())
958  {
959  if (!link.hasAttribute("rel") || link.attribute("rel") == "alternate")
960  {
961  if (!link.hasAttribute("href"))
962  result = link.text();
963  else
964  result = link.attribute("href");
965  break;
966  }
967  link = link.nextSiblingElement("link");
968  }
969  return result;
970 }
971 
972 QString Parse::GetAuthor(const QDomElement& parent)
973 {
974  QString result("");
975  QDomNodeList nodes = parent.elementsByTagNameNS(kITunes,
976  "author");
977  if (nodes.size())
978  {
979  result = nodes.at(0).toElement().text();
980  return result;
981  }
982 
983  nodes = parent.elementsByTagNameNS(kDC,
984  "creator");
985  if (nodes.size())
986  {
987  result = nodes.at(0).toElement().text();
988  return result;
989  }
990 
991  return result;
992 }
993 
994 QString Parse::GetCommentsRSS(const QDomElement& parent)
995 {
996  QString result;
997  QDomNodeList nodes = parent.elementsByTagNameNS(kWFW,
998  "commentRss");
999  if (nodes.size())
1000  result = nodes.at(0).toElement().text();
1001  return result;
1002 }
1003 
1004 QString Parse::GetCommentsLink(const QDomElement& parent)
1005 {
1006  QString result;
1007  QDomNodeList nodes = parent.elementsByTagNameNS("", "comments");
1008  if (nodes.size())
1009  result = nodes.at(0).toElement().text();
1010  return result;
1011 }
1012 
1013 QDateTime Parse::GetDCDateTime(const QDomElement& parent)
1014 {
1015  QDomNodeList dates = parent.elementsByTagNameNS(kDC, "date");
1016  if (!dates.size())
1017  return QDateTime();
1018  return FromRFC3339(dates.at(0).toElement().text());
1019 }
1020 
1021 QDateTime Parse::RFC822TimeToQDateTime(const QString& t) const
1022 {
1023  if (t.size() < 20)
1024  return QDateTime();
1025 
1026  QString time = t.simplified();
1027  short int hoursShift = 0;
1028  short int minutesShift = 0;
1029 
1030  QStringList tmp = time.split(' ');
1031  if (tmp.isEmpty())
1032  return QDateTime();
1033  if (tmp.at(0).contains(QRegularExpression(R"(\D)")))
1034  tmp.removeFirst();
1035  if (tmp.size() != 5)
1036  return QDateTime();
1037  QString tmpTimezone = tmp.takeAt(tmp.size() -1);
1038  if (tmpTimezone.size() == 5)
1039  {
1040  bool ok = false;
1041  int tz = tmpTimezone.toInt(&ok);
1042  if(ok)
1043  {
1044  hoursShift = tz / 100;
1045  minutesShift = tz % 100;
1046  }
1047  }
1048  else
1049  hoursShift = m_timezoneOffsets.value(tmpTimezone, 0);
1050 
1051  if (tmp.at(0).size() == 1)
1052  tmp[0].prepend("0");
1053  tmp [1].truncate(3);
1054 
1055  time = tmp.join(" ");
1056 
1057  QDateTime result;
1058  if (tmp.at(2).size() == 4)
1059  result = QLocale::c().toDateTime(time, "dd MMM yyyy hh:mm:ss");
1060  else
1061  result = QLocale::c().toDateTime(time, "dd MMM yy hh:mm:ss");
1062  if (result.isNull() || !result.isValid())
1063  return QDateTime();
1064  result = result.addSecs(hoursShift * 3600 * (-1) + minutesShift *60 * (-1));
1065  result.setTimeSpec(Qt::UTC);
1066  return result;
1067 }
1068 
1069 QDateTime Parse::FromRFC3339(const QString& t)
1070 {
1071  if (t.size() < 19)
1072  return QDateTime();
1073  QDateTime result = MythDate::fromString(t.left(19).toUpper());
1074  QRegExp fractionalSeconds("(\\.)(\\d+)");
1075  if (fractionalSeconds.indexIn(t) > -1)
1076  {
1077  bool ok = false;
1078  int fractional = fractionalSeconds.cap(2).toInt(&ok);
1079  if (ok)
1080  {
1081  if (fractional < 100)
1082  fractional *= 10;
1083  if (fractional <10)
1084  fractional *= 100;
1085  result = result.addMSecs(fractional);
1086  }
1087  }
1088  QRegExp timeZone(R"((\+|\-)(\d\d)(:)(\d\d)$)");
1089  if (timeZone.indexIn(t) > -1)
1090  {
1091  short int multiplier = -1;
1092  if (timeZone.cap(1) == "-")
1093  multiplier = 1;
1094  int hoursShift = timeZone.cap(2).toInt();
1095  int minutesShift = timeZone.cap(4).toInt();
1096  result = result.addSecs(hoursShift * 3600 * multiplier + minutesShift * 60 * multiplier);
1097  }
1098  result.setTimeSpec(Qt::UTC);
1099  return result;
1100 }
1101 
1102 QList<Enclosure> Parse::GetEnclosures(const QDomElement& entry)
1103 {
1104  QList<Enclosure> result;
1105  QDomNodeList links = entry.elementsByTagName("enclosure");
1106  for (int i = 0; i < links.size(); ++i)
1107  {
1108  QDomElement link = links.at(i).toElement();
1109 
1110  Enclosure e =
1111  {
1112  link.attribute("url"),
1113  link.attribute("type"),
1114  link.attribute("length", "-1").toLongLong(),
1115  link.attribute("hreflang")
1116  };
1117 
1118  result << e;
1119  }
1120  return result;
1121 }
1122 
1123 QList<MRSSEntry> Parse::GetMediaRSS(const QDomElement& item)
1124 {
1125  return MRSSParser() (item);
1126 }
1127 
1128 QString Parse::UnescapeHTML(const QString& escaped)
1129 {
1130  QString result = escaped;
1131  result.replace("&amp;", "&");
1132  result.replace("&lt;", "<");
1133  result.replace("&gt;", ">");
1134  result.replace("&apos;", "\'");
1135  result.replace("&rsquo;", "\'");
1136  result.replace("&#x2019;", "\'");
1137  result.replace("&quot;", "\"");
1138  result.replace("&#8230;",QChar(8230));
1139  result.replace("&#233;",QChar(233));
1140  result.replace("&mdash;", QChar(8212));
1141  result.replace("&nbsp;", " ");
1142  result.replace("&#160;", QChar(160));
1143  result.replace("&#225;", QChar(225));
1144  result.replace("&#8216;", QChar(8216));
1145  result.replace("&#8217;", QChar(8217));
1146  result.replace("&#039;", "\'");
1147  result.replace("&ndash;", QChar(8211));
1148  result.replace("&auml;", QChar(0x00e4));
1149  result.replace("&ouml;", QChar(0x00f6));
1150  result.replace("&uuml;", QChar(0x00fc));
1151  result.replace("&Auml;", QChar(0x00c4));
1152  result.replace("&Ouml;", QChar(0x00d6));
1153  result.replace("&Uuml;", QChar(0x00dc));
1154  result.replace("&szlig;", QChar(0x00df));
1155  result.replace("&euro;", "€");
1156  result.replace("&#8230;", "...");
1157  result.replace("&#x00AE;", QChar(0x00ae));
1158  result.replace("&#x201C;", QChar(0x201c));
1159  result.replace("&#x201D;", QChar(0x201d));
1160  result.replace("<p>", "\n");
1161 
1162  QRegularExpression stripHTML {"<.*?>"};
1163  result.remove(stripHTML);
1164 
1165  return result;
1166 }
MRSSEntry::Expression
QString Expression
Definition: rssparse.h:78
Parse::RFC822TimeToQDateTime
QDateTime RFC822TimeToQDateTime(const QString &parent) const
Definition: rssparse.cpp:1021
MRSSParser::GetURL
static QString GetURL(const QDomElement &element)
Definition: rssparse.cpp:378
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
channel
QDomElement channel
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:501
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:80
ResultItem::ensureSortFields
void ensureSortFields(void)
Definition: rssparse.cpp:64
ResultItem::m_url
QString m_url
Definition: rssparse.h:166
root
QDomElement root
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:656
Parse::kRDF
static const QString kRDF
Definition: rssparse.h:219
Parse::kGeoRSSW3
static const QString kGeoRSSW3
Definition: rssparse.h:224
mythburn.dateformat
string dateformat
Definition: mythburn.py:170
getMythSortHelper
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
Definition: mythsorthelper.cpp:132
MRSSParser::ArbitraryLocatedData::m_rating
QString m_rating
Definition: rssparse.cpp:195
ResultItem::m_countries
QStringList m_countries
Definition: rssparse.h:182
ResultItem::m_episode
uint m_episode
Definition: rssparse.h:184
ResultItem::m_sorttitle
QString m_sorttitle
Definition: rssparse.h:162
MRSSEntry::RatingCount
int RatingCount
Definition: rssparse.h:96
MRSSParser::ArbitraryLocatedData::m_ratingMin
int m_ratingMin
Definition: rssparse.cpp:204
MRSSParser::CollectChildren
static QList< MRSSEntry > CollectChildren(const QDomElement &holder)
Definition: rssparse.cpp:283
MRSSEntry::Comments
QList< MRSSComment > Comments
Definition: rssparse.h:104
ResultItem::m_height
uint m_height
Definition: rssparse.h:179
MRSSEntry::Views
int Views
Definition: rssparse.h:99
MRSSEntry::Scenes
QList< MRSSScene > Scenes
Definition: rssparse.h:106
title
QString title
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:636
MRSSEntry::RatingScheme
QString RatingScheme
Definition: rssparse.h:89
Parse::kAtom
static const QString kAtom
Definition: rssparse.h:218
Parse::UnescapeHTML
static QString UnescapeHTML(const QString &escaped)
Definition: rssparse.cpp:1128
ResultItem::m_time
QString m_time
Definition: rssparse.h:171
ResultItem::m_customhtml
bool m_customhtml
Definition: rssparse.h:185
ResultItem::m_download
QString m_download
Definition: rssparse.h:176
ResultItem::ResultItem
ResultItem()=default
ResultItem::m_thumbnail
QString m_thumbnail
Definition: rssparse.h:167
MRSSParser::ArbitraryLocatedData::m_ratingAverage
int m_ratingAverage
Definition: rssparse.cpp:202
MRSSParser::ArbitraryLocatedData::m_scenes
QList< MRSSScene > m_scenes
Definition: rssparse.cpp:213
Parse::m_timezoneOffsets
QMap< QString, int > m_timezoneOffsets
Definition: rssparse.h:213
format_season_and_episode
MPUBLIC QString format_season_and_episode(int seasEp, int digits)
Definition: programinfo.cpp:6094
rssparse.h
MRSSParser::ArbitraryLocatedData::m_ratingCount
int m_ratingCount
Definition: rssparse.cpp:203
Parse::kMythRSS
static const QString kMythRSS
Definition: rssparse.h:226
Parse::GetMediaRSS
static QList< MRSSEntry > GetMediaRSS(const QDomElement &item)
Definition: rssparse.cpp:1123
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ResultItem::m_downloadargs
QStringList m_downloadargs
Definition: rssparse.h:177
mythdirs.h
MRSSScene
Definition: rssparse.h:64
mythsorthelper.h
MRSSEntry::Medium
QString Medium
Definition: rssparse.h:76
MRSSEntry::Favs
int Favs
Definition: rssparse.h:100
MRSSParser::ArbitraryLocatedData::m_url
QString m_url
Definition: rssparse.cpp:194
ResultItem::m_title
QString m_title
Definition: rssparse.h:161
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MRSSEntry::Lang
QString Lang
Definition: rssparse.h:86
MRSSParser::ArbitraryLocatedData::m_title
QString m_title
Definition: rssparse.cpp:197
MRSSEntry::URL
QString URL
Definition: rssparse.h:73
MRSSParser::GetArbitraryLocatedDataFor
static ArbitraryLocatedData GetArbitraryLocatedDataFor(const QDomElement &holder)
Definition: rssparse.cpp:360
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
ResultItem::m_date
QDateTime m_date
Definition: rssparse.h:170
ResultItem::m_player
QString m_player
Definition: rssparse.h:174
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MRSSEntry::RatingMax
int RatingMax
Definition: rssparse.h:98
Parse::kSlash
static const QString kSlash
Definition: rssparse.h:220
MRSSParser::GetTitle
static QString GetTitle(const QDomElement &element)
Definition: rssparse.cpp:388
ResultItem::m_desc
QString m_desc
Definition: rssparse.h:165
Parse::kDC
static const QString kDC
Definition: rssparse.h:216
MRSSEntry::Tags
QString Tags
Definition: rssparse.h:101
mythdate.h
programinfo.h
MRSSEntry::Size
qint64 Size
Definition: rssparse.h:74
Parse::ParseItem
ResultItem * ParseItem(const QDomElement &item) const
Definition: rssparse.cpp:733
MRSSParser::ArbitraryLocatedData::m_keywords
QString m_keywords
Definition: rssparse.cpp:199
hardwareprofile.config.p
p
Definition: config.py:33
hardwareprofile.i18n.t
t
Definition: i18n.py:36
MRSSParser::operator()
QList< MRSSEntry > operator()(const QDomElement &item)
Definition: rssparse.cpp:266
MRSSParser::GetPeerLinks
static QList< MRSSPeerLink > GetPeerLinks(const QDomElement &element)
Definition: rssparse.cpp:543
MRSSEntry::RatingMin
int RatingMin
Definition: rssparse.h:97
MRSSEntry::SamplingRate
double SamplingRate
Definition: rssparse.h:81
Parse::kEnc
static const QString kEnc
Definition: rssparse.h:221
ResultItem::m_downloadable
bool m_downloadable
Definition: rssparse.h:181
MRSSEntry::Rating
QString Rating
Definition: rssparse.h:88
hardwareprofile.scan.rating
def rating(profile, smoonURL, gate)
Definition: scan.py:39
MRSSEntry
Definition: rssparse.h:72
MRSSParser::GetInt
static int GetInt(const QDomElement &elem, const QString &attrname)
Definition: rssparse.cpp:424
MRSSEntry::IsDefault
bool IsDefault
Definition: rssparse.h:77
MRSSEntry::CopyrightURL
QString CopyrightURL
Definition: rssparse.h:93
MRSSEntry::RatingAverage
int RatingAverage
Definition: rssparse.h:95
ResultItem::m_author
QString m_author
Definition: rssparse.h:169
MRSSParser::ArbitraryLocatedData::m_copyrightUrl
QString m_copyrightUrl
Definition: rssparse.cpp:200
MRSSThumbnail::URL
QString URL
Definition: rssparse.h:39
MRSSParser::GetThumbnails
static QList< MRSSThumbnail > GetThumbnails(const QDomElement &element)
Definition: rssparse.cpp:436
ResultItem::m_filesize
off_t m_filesize
Definition: rssparse.h:173
MRSSEntry::CopyrightText
QString CopyrightText
Definition: rssparse.h:94
Parse::GetDCDateTime
static QDateTime GetDCDateTime(const QDomElement &parent)
Definition: rssparse.cpp:1013
MRSSParser::ArbitraryLocatedData::m_peerLinks
QList< MRSSPeerLink > m_peerLinks
Definition: rssparse.cpp:212
ResultItem::m_width
uint m_width
Definition: rssparse.h:178
Parse::kITunes
static const QString kITunes
Definition: rssparse.h:222
ResultItem::m_subtitle
QString m_subtitle
Definition: rssparse.h:163
ResultItem::toMap
void toMap(InfoMap &metadataMap)
Definition: rssparse.cpp:74
Parse::kMediaRSS
static const QString kMediaRSS
Definition: rssparse.h:225
MRSSEntry::Credits
QList< MRSSCredit > Credits
Definition: rssparse.h:103
Enclosure
Describes an enclosure associated with an item.
Definition: rssparse.h:30
uint
unsigned int uint
Definition: compat.h:140
MRSSParser::ArbitraryLocatedData::m_favs
int m_favs
Definition: rssparse.cpp:207
MRSSParser::ArbitraryLocatedData::m_credits
QList< MRSSCredit > m_credits
Definition: rssparse.cpp:210
MRSSEntry::Title
QString Title
Definition: rssparse.h:90
MRSSCredit
Definition: rssparse.h:46
MRSSParser::GetCredits
static QList< MRSSCredit > GetCredits(const QDomElement &element)
Definition: rssparse.cpp:460
MRSSEntry::Type
QString Type
Definition: rssparse.h:75
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
off_t
#define off_t
Definition: mythiowrapper.cpp:238
MRSSParser::ArbitraryLocatedData::m_ratingMax
int m_ratingMax
Definition: rssparse.cpp:205
Parse::GetCommentsLink
static QString GetCommentsLink(const QDomElement &parent)
Definition: rssparse.cpp:1004
Parse::kWFW
static const QString kWFW
Definition: rssparse.h:217
MRSSEntry::PeerLinks
QList< MRSSPeerLink > PeerLinks
Definition: rssparse.h:105
MRSSEntry::Thumbnails
QList< MRSSThumbnail > Thumbnails
Definition: rssparse.h:102
MRSSParser::GetComments
static QList< MRSSComment > GetComments(const QDomElement &element)
Definition: rssparse.cpp:481
MRSSParser::GetDescription
static QString GetDescription(const QDomElement &element)
Definition: rssparse.cpp:400
MRSSParser::ArbitraryLocatedData::m_tags
QString m_tags
Definition: rssparse.cpp:208
MRSSEntry::Height
int Height
Definition: rssparse.h:85
MRSSEntry::Channels
int Channels
Definition: rssparse.h:82
MRSSParser::ArbitraryLocatedData::ArbitraryLocatedData
ArbitraryLocatedData()=default
MRSSEntry::Bitrate
int Bitrate
Definition: rssparse.h:79
MRSSThumbnail
Definition: rssparse.h:38
countries
QDomElement countries
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:785
Parse::GetAuthor
static QString GetAuthor(const QDomElement &parent)
Definition: rssparse.cpp:972
MRSSParser::GetScenes
static QList< MRSSScene > GetScenes(const QDomElement &element)
Definition: rssparse.cpp:562
MRSSParser::ArbitraryLocatedData::m_comments
QList< MRSSComment > m_comments
Definition: rssparse.cpp:211
ResultItem
Definition: rssparse.h:110
Parse::kGeoRSSSimple
static const QString kGeoRSSSimple
Definition: rssparse.h:223
ResultItem::m_sortsubtitle
QString m_sortsubtitle
Definition: rssparse.h:164
MRSSParser
Definition: rssparse.cpp:191
Parse::parseRSS
ResultItem::resultList parseRSS(const QDomDocument &domDoc) const
Definition: rssparse.cpp:710
MRSSParser::ArbitraryLocatedData
Definition: rssparse.cpp:193
MRSSParser::CollectArbitraryLocatedData
static ArbitraryLocatedData CollectArbitraryLocatedData(const QDomElement &element)
Definition: rssparse.cpp:589
ResultItem::m_rating
QString m_rating
Definition: rssparse.h:172
MRSSParser::ArbitraryLocatedData::m_description
QString m_description
Definition: rssparse.cpp:198
mythcontext.h
Parse::FromRFC3339
static QDateTime FromRFC3339(const QString &t)
Definition: rssparse.cpp:1069
MRSSEntry::Width
int Width
Definition: rssparse.h:84
MRSSParser::ArbitraryLocatedData::m_views
int m_views
Definition: rssparse.cpp:206
ResultItem::resultList
QList< ResultItem * > resultList
Definition: rssparse.h:114
MythDate::kDateFull
@ kDateFull
Default local time.
Definition: mythdate.h:16
ResultItem::m_playerargs
QStringList m_playerargs
Definition: rssparse.h:175
ResultItem::m_season
uint m_season
Definition: rssparse.h:183
MRSSParser::ArbitraryLocatedData::m_ratingScheme
QString m_ratingScheme
Definition: rssparse.cpp:196
MRSSEntry::Keywords
QString Keywords
Definition: rssparse.h:92
ResultItem::m_language
QString m_language
Definition: rssparse.h:180
Parse::GetLink
static QString GetLink(const QDomElement &parent)
Definition: rssparse.cpp:953
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
MRSSComment
Definition: rssparse.h:52
Parse::GetCommentsRSS
static QString GetCommentsRSS(const QDomElement &parent)
Definition: rssparse.cpp:994
MRSSParser::ArbitraryLocatedData::operator+=
ArbitraryLocatedData & operator+=(const ArbitraryLocatedData &child)
Updates *this's fields according to the child.
Definition: rssparse.cpp:220
MRSSParser::ArbitraryLocatedData::m_thumbnails
QList< MRSSThumbnail > m_thumbnails
Definition: rssparse.cpp:209
MRSSParser::GetKeywords
static QString GetKeywords(const QDomElement &element)
Definition: rssparse.cpp:412
MRSSEntry::Framerate
double Framerate
Definition: rssparse.h:80
MRSSParser::MRSSParser
MRSSParser()=default
Parse::MRSSParser
friend class MRSSParser
Definition: rssparse.h:191
MRSSEntry::Description
QString Description
Definition: rssparse.h:91
MRSSEntry::Duration
int Duration
Definition: rssparse.h:83
ResultItem::m_mediaURL
QString m_mediaURL
Definition: rssparse.h:168
Parse::GetEnclosures
static QList< Enclosure > GetEnclosures(const QDomElement &entry)
Definition: rssparse.cpp:1102
MRSSParser::ArbitraryLocatedData::m_copyrightText
QString m_copyrightText
Definition: rssparse.cpp:201