MythTV  master
metadatacommon.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include <utility>
3 
4 // Qt headers
5 #include <QCoreApplication>
6 #include <QLocale>
7 #include <QMetaType>
8 
9 #include "libmyth/programinfo.h"
10 #include "libmyth/rssparse.h"
12 #include "libmythbase/mythlocale.h"
15 
16 #include "metadatacommon.h"
17 
18 static int x0 = qRegisterMetaType< RefCountHandler<MetadataLookup> >();
19 
20 // full constructor
23  LookupType subtype,
24  QVariant data,
25  LookupStep step,
26  bool automatic,
27  bool handleimages,
28  bool allowoverwrites,
29  bool allowgeneric,
30  bool preferdvdorder,
31  QString host,
32  QString filename,
33  const QString &title,
34  QString network,
35  QString status,
36  QStringList categories,
37  const float userrating,
38  uint ratingcount,
39  QString language,
40  QString subtitle,
41  QString tagline,
42  QString description,
43  uint season,
44  uint episode,
45  uint chanid,
46  QString channum,
47  QString chansign,
48  QString channame,
49  QString chanplaybackfilters,
50  QString recgroup,
51  QString playgroup,
52  QString seriesid,
53  QString programid,
54  QString storagegroup,
55  QDateTime startts,
56  QDateTime endts,
57  QDateTime recstartts,
58  QDateTime recendts,
59  uint programflags,
60  uint audioproperties,
61  uint videoproperties,
62  uint subtitletype,
63  QString certification,
64  QStringList countries,
65  const float popularity,
66  const uint budget,
67  const uint revenue,
68  QString album,
69  uint tracknum,
70  QString system,
71  const uint year,
72  const QDate releasedate,
73  QDateTime lastupdated,
74  std::chrono::minutes runtime,
75  std::chrono::seconds runtimesecs,
76  QString inetref,
77  QString collectionref,
78  QString tmsref,
79  QString imdb,
80  PeopleMap people,
81  QStringList studios,
82  QString homepage,
83  QString trailerURL,
84  ArtworkMap artwork,
85  DownloadMap downloads) :
86  ReferenceCounter("MetadataLookup"),
87 
88  m_type(type),
89  m_subtype(subtype),
90  m_data(std::move(data)),
91  m_step(step),
92  m_automatic(automatic),
93  m_handleImages(handleimages),
94  m_allowOverwrites(allowoverwrites),
95  m_allowGeneric(allowgeneric),
96  m_dvdOrder(preferdvdorder),
97  m_host(std::move(host)),
98  m_filename(std::move(filename)),
99  m_title(title),
100  m_network(std::move(network)),
101  m_status(std::move(status)),
102  m_categories(std::move(categories)),
103  m_userRating(userrating),
104  m_ratingCount(ratingcount),
105  m_language(std::move(language)),
106  m_subtitle(std::move(subtitle)),
107  m_tagline(std::move(tagline)),
108  m_description(std::move(description)),
109  m_season(season),
110  m_episode(episode),
111  m_chanId(chanid),
112  m_chanNum(std::move(channum)),
113  m_chanSign(std::move(chansign)),
114  m_chanName(std::move(channame)),
115  m_chanPlaybackFilters(std::move(chanplaybackfilters)),
116  m_recGroup(std::move(recgroup)),
117  m_playGroup(std::move(playgroup)),
118  m_seriesId(std::move(seriesid)),
119  m_programid(std::move(programid)),
120  m_storageGroup(std::move(storagegroup)),
121  m_startTs(std::move(startts)),
122  m_endTs(std::move(endts)),
123  m_recStartTs(std::move(recstartts)),
124  m_recEndTs(std::move(recendts)),
125  m_programFlags(programflags),
126  m_audioProperties(audioproperties),
127  m_videoProperties(videoproperties),
128  m_subtitleType(subtitletype),
129  m_certification(std::move(certification)),
130  m_countries(std::move(countries)),
131  m_popularity(popularity),
132  m_budget(budget),
133  m_revenue(revenue),
134  m_album(std::move(album)),
135  m_trackNum(tracknum),
136  m_system(std::move(system)),
137  m_year(year),
138  m_releaseDate(releasedate),
139  m_lastUpdated(std::move(lastupdated)),
140  m_runtime(runtime),
141  m_runtimeSecs(runtimesecs),
142  m_inetRef(std::move(inetref)),
143  m_collectionRef(std::move(collectionref)),
144  m_tmsRef(std::move(tmsref)),
145  m_imdb(std::move(imdb)),
146  m_people(std::move(people)),
147  m_studios(std::move(studios)),
148  m_homepage(std::move(homepage)),
149  m_trailerURL(std::move(trailerURL)),
150  m_artwork(std::move(artwork)),
151  m_downloads(std::move(downloads))
152 {
153  QString manRecSuffix = QString(" (%1)").arg(QObject::tr("Manual Record"));
154  m_baseTitle = title;
155  m_baseTitle.replace(manRecSuffix,"");
156 }
157 
158 // ProgramInfo-style constructor
161  LookupType subtype,
162  QVariant data,
163  LookupStep step,
164  bool automatic,
165  bool handleimages,
166  bool allowoverwrites,
167  bool allowgeneric,
168  bool preferdvdorder,
169  QString host,
170  QString filename,
171  const QString &title,
172  QStringList categories,
173  const float userrating,
174  QString subtitle,
175  QString description,
176  uint chanid,
177  QString channum,
178  QString chansign,
179  QString channame,
180  QString chanplaybackfilters,
181  QString recgroup,
182  QString playgroup,
183  QString seriesid,
184  QString programid,
185  QString storagegroup,
186  QDateTime startts,
187  QDateTime endts,
188  QDateTime recstartts,
189  QDateTime recendts,
190  uint programflags,
191  uint audioproperties,
192  uint videoproperties,
193  uint subtitletype,
194  const uint year,
195  const QDate releasedate,
196  QDateTime lastupdated,
197  std::chrono::minutes runtime,
198  std::chrono::seconds runtimesecs) :
199  ReferenceCounter("MetadataLookup"),
200 
201  m_type(type),
202  m_subtype(subtype),
203  m_data(std::move(data)),
204  m_step(step),
205  m_automatic(automatic),
206  m_handleImages(handleimages),
207  m_allowOverwrites(allowoverwrites),
208  m_allowGeneric(allowgeneric),
209  m_dvdOrder(preferdvdorder),
210  m_host(std::move(host)),
211  m_filename(std::move(filename)),
212  m_title(title),
213  m_categories(std::move(categories)),
214  m_userRating(userrating),
215  m_subtitle(std::move(subtitle)),
216  m_description(std::move(description)),
217  m_chanId(chanid),
218  m_chanNum(std::move(channum)),
219  m_chanSign(std::move(chansign)),
220  m_chanName(std::move(channame)),
221  m_chanPlaybackFilters(std::move(chanplaybackfilters)),
222  m_recGroup(std::move(recgroup)),
223  m_playGroup(std::move(playgroup)),
224  m_seriesId(std::move(seriesid)),
225  m_programid(std::move(programid)),
226  m_storageGroup(std::move(storagegroup)),
227  m_startTs(std::move(startts)),
228  m_endTs(std::move(endts)),
229  m_recStartTs(std::move(recstartts)),
230  m_recEndTs(std::move(recendts)),
231  m_programFlags(programflags),
232  m_audioProperties(audioproperties),
233  m_videoProperties(videoproperties),
234  m_subtitleType(subtitletype),
235  m_year(year),
236  m_releaseDate(releasedate),
237  m_lastUpdated(std::move(lastupdated)),
238  m_runtime(runtime),
239  m_runtimeSecs(runtimesecs)
240 {
241  QString manRecSuffix = QString(" (%1)").arg(QObject::tr("Manual Record"));
242  m_baseTitle = title;
243  m_baseTitle.replace(manRecSuffix,"");
244 }
245 
246 // XBMC NFO-style constructor
249  LookupType subtype,
250  QVariant data,
251  LookupStep step,
252  bool automatic,
253  bool handleimages,
254  bool allowoverwrites,
255  bool allowgeneric,
256  bool preferdvdorder,
257  QString host,
258  QString filename,
259  const QString &title,
260  QStringList categories,
261  const float userrating,
262  QString subtitle,
263  QString tagline,
264  QString description,
265  uint season,
266  uint episode,
267  QString certification,
268  const uint year,
269  const QDate releasedate,
270  std::chrono::minutes runtime,
271  std::chrono::seconds runtimesecs,
272  QString inetref,
273  PeopleMap people,
274  QString trailerURL,
275  ArtworkMap artwork,
276  DownloadMap downloads) :
277  ReferenceCounter("MetadataLookup"),
278 
279  m_type(type),
280  m_subtype(subtype),
281  m_data(std::move(data)),
282  m_step(step),
283  m_automatic(automatic),
284  m_handleImages(handleimages),
285  m_allowOverwrites(allowoverwrites),
286  m_allowGeneric(allowgeneric),
287  m_dvdOrder(preferdvdorder),
288  m_host(std::move(host)),
289  m_filename(std::move(filename)),
290  m_title(title),
291  m_categories(std::move(categories)),
292  m_userRating(userrating),
293  m_subtitle(std::move(subtitle)),
294  m_tagline(std::move(tagline)),
295  m_description(std::move(description)),
296  m_season(season),
297  m_episode(episode),
298  m_certification(std::move(certification)),
299  m_year(year),
300  m_releaseDate(releasedate),
301  m_runtime(runtime),
302  m_runtimeSecs(runtimesecs),
303  m_inetRef(std::move(inetref)),
304  m_people(std::move(people)),
305  m_trailerURL(std::move(trailerURL)),
306  m_artwork(std::move(artwork)),
307  m_downloads(std::move(downloads))
308 {
309  QString manRecSuffix = QString(" (%1)").arg(QObject::tr("Manual Record"));
310  m_baseTitle = title;
311  m_baseTitle.replace(manRecSuffix,"");
312 }
313 
314 QList<PersonInfo> MetadataLookup::GetPeople(PeopleType type) const
315 {
316  QList<PersonInfo> ret;
317  // QMultiMap::values() returns items in reverse order which we need to
318  // correct by iterating back over the list
319  // See http://qt-project.org/doc/qt-4.8/qmultimap.html#details
320  // Specifically "The items that share the same key are available from "
321  // "most recently to least recently inserted."
322  QListIterator<PersonInfo> it(m_people.values(type));
323  it.toBack();
324  while (it.hasPrevious())
325  ret.append(it.previous());
326 
327  return ret;
328 }
329 
331 {
332  ArtworkList ret;
333 
334  // QMultiMap::values() returns items in reverse order which we need to
335  // correct by iterating back over the list
336  // See http://qt-project.org/doc/qt-4.8/qmultimap.html#details
337  // Specifically "The items that share the same key are available from "
338  // "most recently to least recently inserted."
339  QListIterator<ArtworkInfo> it(m_artwork.values(type));
340  it.toBack();
341  while (it.hasPrevious())
342  ret.append(it.previous());
343 
344  return ret;
345 }
346 
347 void MetadataLookup::toMap(InfoMap &metadataMap)
348 {
349  metadataMap["filename"] = m_filename;
350  metadataMap["title"] = m_title;
351  metadataMap["network"] = m_network;
352  metadataMap["status"] = m_status;
353  metadataMap["category"] = m_categories.join(", ");
354  metadataMap["userrating"] = QString::number(m_userRating);
355  metadataMap["ratingcount"] = QString::number(m_ratingCount);
356  metadataMap["language"] = m_language;
357  metadataMap["subtitle"] = m_subtitle;
358  metadataMap["tagline"] = m_tagline;
359  metadataMap["description0"] = metadataMap["description"] = m_description;
360  metadataMap["season"] = QString::number(m_season);
361  metadataMap["episode"] = QString::number(m_episode);
362  metadataMap["chanid"] = QString::number(m_chanId);
363  metadataMap["channum"] = m_chanNum;
364  metadataMap["callsign"] = m_chanSign;
365  metadataMap["channame"] = m_chanName;
366  metadataMap["playbackfilters"] = m_chanPlaybackFilters;
367  metadataMap["recgroup"] = m_recGroup;
368  metadataMap["playgroup"] = m_playGroup;
369  metadataMap["seriesid"] = m_seriesId;
370  metadataMap["programid"] = m_programid;
371  metadataMap["storagegroup"] = m_storageGroup;
372  metadataMap["startts"] = MythDate::toString(m_startTs, MythDate::kDateFull);
373  metadataMap["endts"] = MythDate::toString(m_endTs, MythDate::kDateFull);
374  metadataMap["recstartts"] = MythDate::toString(m_recStartTs, MythDate::kDateFull);
375  metadataMap["recendts"] = MythDate::toString(m_recEndTs, MythDate::kDateFull);
376  metadataMap["certification"] = m_certification;
377  metadataMap["countries"] = m_countries.join(", ");
378  metadataMap["popularity"] = QString::number(m_popularity);
379  metadataMap["budget"] = QString::number(m_budget);
380  metadataMap["revenue"] = QString::number(m_revenue);
381  metadataMap["album"] = m_album;
382  metadataMap["tracknum"] = QString::number(m_trackNum);
383  metadataMap["system"] = m_system;
384  metadataMap["year"] = QString::number(m_year);
385 
386  metadataMap["releasedate"] = MythDate::toString(
388  metadataMap["lastupdated"] = MythDate::toString(m_lastUpdated, MythDate::kDateFull);
389 
390  metadataMap["runtime"] = QCoreApplication::translate("(Common)",
391  "%n minute(s)",
392  "",
393  m_runtime.count());
394 
395 
396  metadataMap["runtimesecs"] = QCoreApplication::translate("(Common)",
397  "%n second(s)",
398  "",
399  m_runtimeSecs.count());
400  metadataMap["inetref"] = m_inetRef;
401  metadataMap["collectionref"] = m_collectionRef;
402  metadataMap["tmsref"] = m_tmsRef;
403  metadataMap["imdb"] = m_imdb;
404  metadataMap["studios"] = m_studios.join(", ");
405  metadataMap["homepage"] = m_homepage;
406  metadataMap["trailer"] = m_trailerURL;
407 }
408 
410 {
411  auto runtimesecs =
412  std::chrono::seconds(pginfo->GetRecordingStartTime()
413  .secsTo(pginfo->GetRecordingEndTime()));
414  auto runtime = duration_cast<std::chrono::minutes>(runtimesecs);
415 
417  QVariant::fromValue(pginfo), kLookupData, false, false, false, false, false,
418  pginfo->GetHostname(),pginfo->GetBasename(),pginfo->GetTitle(),
419  QStringList() << pginfo->GetCategory(), pginfo->GetStars() * 10,
420  pginfo->GetSubtitle(), pginfo->GetDescription(), pginfo->GetChanID(),
421  pginfo->GetChanNum(), pginfo->GetChannelSchedulingID(),
422  pginfo->GetChannelName(), pginfo->GetChannelPlaybackFilters(),
423  pginfo->GetRecordingGroup(), pginfo->GetPlaybackGroup(),
424  pginfo->GetSeriesID(), pginfo->GetProgramID(), pginfo->GetStorageGroup(),
425  pginfo->GetScheduledStartTime(), pginfo->GetScheduledEndTime(),
426  pginfo->GetRecordingStartTime(), pginfo->GetRecordingEndTime(),
427  pginfo->GetProgramFlags(), pginfo->GetAudioProperties(),
428  pginfo->GetVideoProperties(), pginfo->GetSubtitleType(),
429  pginfo->GetYearOfInitialRelease(), pginfo->GetOriginalAirDate(),
430  pginfo->GetLastModifiedTime(), runtime, runtimesecs);
431 
432  ret->SetSeason(pginfo->GetSeason());
433  ret->SetEpisode(pginfo->GetEpisode());
434  ret->SetInetref(pginfo->GetInetRef());
435 
436  return ret;
437 }
438 
440 {
441  QDomDocument doc("MythMetadataXML");
442 
443  QDomElement root = doc.createElement("metadata");
444  doc.appendChild(root);
445 
446  for (const auto & item : qAsConst(list))
447  CreateMetadataXMLItem(item, root, doc);
448 
449  return doc;
450 }
451 
452 QDomDocument CreateMetadataXML(MetadataLookup *lookup)
453 {
454  QDomDocument doc("MythMetadataXML");
455 
456  QDomElement root = doc.createElement("metadata");
457  doc.appendChild(root);
458 
459  CreateMetadataXMLItem(lookup, root, doc);
460 
461  return doc;
462 }
463 
464 QDomDocument CreateMetadataXML(ProgramInfo *pginfo)
465 {
466  QDomDocument doc("MythMetadataXML");
467 
468  MetadataLookup *lookup = LookupFromProgramInfo(pginfo);
469  if (lookup)
470  doc = CreateMetadataXML(lookup);
471 
472  lookup->DecrRef();
473  lookup = nullptr;
474 
475  return doc;
476 }
477 
479  QDomElement placetoadd,
480  QDomDocument docroot)
481 {
482  if (!lookup)
483  return;
484 
485  QDomElement item = docroot.createElement("item");
486  placetoadd.appendChild(item);
487  QString RFC822("ddd, d MMMM yyyy hh:mm:ss");
488 
489  // Language
490  if (!lookup->GetLanguage().isEmpty())
491  {
492  QDomElement language = docroot.createElement("language");
493  item.appendChild(language);
494  language.appendChild(docroot.createTextNode(lookup->GetLanguage()));
495  }
496  // Title
497  if (!lookup->GetTitle().isEmpty())
498  {
499  QDomElement title = docroot.createElement("title");
500  item.appendChild(title);
501  title.appendChild(docroot.createTextNode(lookup->GetTitle()));
502  }
503  // Subtitle
504  if (!lookup->GetSubtitle().isEmpty())
505  {
506  QDomElement subtitle = docroot.createElement("subtitle");
507  item.appendChild(subtitle);
508  subtitle.appendChild(docroot.createTextNode(lookup->GetSubtitle()));
509  }
510  // Network
511  if (!lookup->GetNetwork().isEmpty())
512  {
513  QDomElement network = docroot.createElement("network");
514  item.appendChild(network);
515  network.appendChild(docroot.createTextNode(lookup->GetNetwork()));
516  }
517  // Status
518  if (!lookup->GetStatus().isEmpty())
519  {
520  QDomElement status = docroot.createElement("status");
521  item.appendChild(status);
522  status.appendChild(docroot.createTextNode(lookup->GetStatus()));
523  }
524  // Season
525  if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
526  {
527  QDomElement season = docroot.createElement("season");
528  item.appendChild(season);
529  season.appendChild(docroot.createTextNode(
530  QString::number(lookup->GetSeason())));
531  }
532  // Episode
533  if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
534  {
535  QDomElement episode = docroot.createElement("episode");
536  item.appendChild(episode);
537  episode.appendChild(docroot.createTextNode(
538  QString::number(lookup->GetEpisode())));
539  }
540  // Tagline
541  if (!lookup->GetTagline().isEmpty())
542  {
543  QDomElement tagline = docroot.createElement("tagline");
544  item.appendChild(tagline);
545  tagline.appendChild(docroot.createTextNode(lookup->GetTagline()));
546  }
547  // Plot
548  if (!lookup->GetDescription().isEmpty())
549  {
550  QDomElement desc = docroot.createElement("description");
551  item.appendChild(desc);
552  desc.appendChild(docroot.createTextNode(lookup->GetDescription()));
553  }
554  // Album Name
555  if (!lookup->GetAlbumTitle().isEmpty())
556  {
557  QDomElement albumname = docroot.createElement("albumname");
558  item.appendChild(albumname);
559  albumname.appendChild(docroot.createTextNode(lookup->GetAlbumTitle()));
560  }
561  // Inetref
562  if (!lookup->GetInetref().isEmpty())
563  {
564  QDomElement inetref = docroot.createElement("inetref");
565  item.appendChild(inetref);
566  inetref.appendChild(docroot.createTextNode(lookup->GetInetref()));
567  }
568  // Collectionref
569  if (!lookup->GetCollectionref().isEmpty())
570  {
571  QDomElement collectionref = docroot.createElement("collectionref");
572  item.appendChild(collectionref);
573  collectionref.appendChild(docroot.createTextNode(lookup->GetCollectionref()));
574  }
575  // TMSref/SeriesID
576  if (!lookup->GetTMSref().isEmpty())
577  {
578  QDomElement tmsref = docroot.createElement("tmsref");
579  item.appendChild(tmsref);
580  tmsref.appendChild(docroot.createTextNode(lookup->GetTMSref()));
581  }
582  // IMDB
583  if (!lookup->GetIMDB().isEmpty())
584  {
585  QDomElement imdb = docroot.createElement("imdb");
586  item.appendChild(imdb);
587  imdb.appendChild(docroot.createTextNode(lookup->GetIMDB()));
588  }
589  // Home Page
590  if (!lookup->GetHomepage().isEmpty())
591  {
592  QDomElement homepage = docroot.createElement("homepage");
593  item.appendChild(homepage);
594  homepage.appendChild(docroot.createTextNode(lookup->GetHomepage()));
595  }
596  // Trailer
597  if (!lookup->GetTrailerURL().isEmpty())
598  {
599  QDomElement trailer = docroot.createElement("trailer");
600  item.appendChild(trailer);
601  trailer.appendChild(docroot.createTextNode(lookup->GetTrailerURL()));
602  }
603  // Chan ID
604  if (lookup->GetChanId() > 0)
605  {
606  QDomElement chanid = docroot.createElement("chanid");
607  item.appendChild(chanid);
608  chanid.appendChild(docroot.createTextNode(
609  QString::number(lookup->GetChanId())));
610  }
611  // Channel Number
612  if (!lookup->GetChanNum().isEmpty())
613  {
614  QDomElement channum = docroot.createElement("channum");
615  item.appendChild(channum);
616  channum.appendChild(docroot.createTextNode(lookup->GetChanNum()));
617  }
618  // Callsign
619  if (!lookup->GetChanSign().isEmpty())
620  {
621  QDomElement callsign = docroot.createElement("chansign");
622  item.appendChild(callsign);
623  callsign.appendChild(docroot.createTextNode(lookup->GetChanSign()));
624  }
625  // Channel Name
626  if (!lookup->GetChanName().isEmpty())
627  {
628  QDomElement channame = docroot.createElement("channame");
629  item.appendChild(channame);
630  channame.appendChild(docroot.createTextNode(lookup->GetChanName()));
631  }
632  // Playback Filters
633  if (!lookup->GetChanPlaybackFilters().isEmpty())
634  {
635  QDomElement filters = docroot.createElement("filters");
636  item.appendChild(filters);
637  filters.appendChild(docroot.createTextNode(
638  lookup->GetChanPlaybackFilters()));
639  }
640  // Recording Group
641  if (!lookup->GetRecGroup().isEmpty())
642  {
643  QDomElement recgroup = docroot.createElement("recgroup");
644  item.appendChild(recgroup);
645  recgroup.appendChild(docroot.createTextNode(lookup->GetRecGroup()));
646  }
647  // Playback Group
648  if (!lookup->GetPlayGroup().isEmpty())
649  {
650  QDomElement playgroup = docroot.createElement("playgroup");
651  item.appendChild(playgroup);
652  playgroup.appendChild(docroot.createTextNode(lookup->GetPlayGroup()));
653  }
654  // SeriesID
655  if (!lookup->GetSeriesId().isEmpty())
656  {
657  QDomElement seriesid = docroot.createElement("seriesid");
658  item.appendChild(seriesid);
659  seriesid.appendChild(docroot.createTextNode(lookup->GetSeriesId()));
660  }
661  // ProgramID
662  if (!lookup->GetProgramId().isEmpty())
663  {
664  QDomElement programid = docroot.createElement("programid");
665  item.appendChild(programid);
666  programid.appendChild(docroot.createTextNode(lookup->GetProgramId()));
667  }
668  // Storage Group
669  if (!lookup->GetStorageGroup().isEmpty())
670  {
671  QDomElement sgroup = docroot.createElement("storagegroup");
672  item.appendChild(sgroup);
673  sgroup.appendChild(docroot.createTextNode(lookup->GetStorageGroup()));
674  }
675  // Start TS
676  if (!lookup->GetStartTS().isNull())
677  {
678  QDomElement startts = docroot.createElement("startts");
679  item.appendChild(startts);
680  startts.appendChild(docroot.createTextNode(
681  lookup->GetStartTS().toString(RFC822)));
682  }
683  // End TS
684  if (!lookup->GetEndTS().isNull())
685  {
686  QDomElement endts = docroot.createElement("endts");
687  item.appendChild(endts);
688  endts.appendChild(docroot.createTextNode(
689  lookup->GetEndTS().toString(RFC822)));
690  }
691  // Rec Start TS
692  if (!lookup->GetRecStartTS().isNull())
693  {
694  QDomElement recstartts = docroot.createElement("recstartts");
695  item.appendChild(recstartts);
696  recstartts.appendChild(docroot.createTextNode(
697  lookup->GetRecStartTS().toString(RFC822)));
698  }
699  // Rec End TS
700  if (!lookup->GetRecEndTS().isNull())
701  {
702  QDomElement recendts = docroot.createElement("recendts");
703  item.appendChild(recendts);
704  recendts.appendChild(docroot.createTextNode(
705  lookup->GetRecEndTS().toString(RFC822)));
706  }
707  // Program Flags
708  if (lookup->GetProgramFlags() > 0)
709  {
710  QDomElement progflags = docroot.createElement("programflags");
711  item.appendChild(progflags);
712  progflags.appendChild(docroot.createTextNode(
713  QString::number(lookup->GetProgramFlags())));
714  }
715  // Audio Properties
716  if (lookup->GetAudioProperties() > 0)
717  {
718  QDomElement audioprops = docroot.createElement("audioproperties");
719  item.appendChild(audioprops);
720  audioprops.appendChild(docroot.createTextNode(
721  QString::number(lookup->GetAudioProperties())));
722  }
723  // Video Properties
724  if (lookup->GetVideoProperties() > 0)
725  {
726  QDomElement videoprops = docroot.createElement("videoproperties");
727  item.appendChild(videoprops);
728  videoprops.appendChild(docroot.createTextNode(
729  QString::number(lookup->GetVideoProperties())));
730  }
731  // Subtitle Type
732  if (lookup->GetSubtitleType() > 0)
733  {
734  QDomElement subprops = docroot.createElement("subtitletype");
735  item.appendChild(subprops);
736  subprops.appendChild(docroot.createTextNode(
737  QString::number(lookup->GetSubtitleType())));
738  }
739  // Release Date
740  if (!lookup->GetReleaseDate().isNull())
741  {
742  QDomElement releasedate = docroot.createElement("releasedate");
743  item.appendChild(releasedate);
744  releasedate.appendChild(docroot.createTextNode(
745  lookup->GetReleaseDate().toString("yyyy-MM-dd")));
746  }
747  // Last Updated
748  if (!lookup->GetLastUpdated().isNull())
749  {
750  QDomElement lastupdated = docroot.createElement("lastupdated");
751  item.appendChild(lastupdated);
752  lastupdated.appendChild(docroot.createTextNode(
753  lookup->GetLastUpdated().toString(RFC822)));
754  }
755  // User Rating
756  if (lookup->GetUserRating() > 0)
757  {
758  QDomElement userrating = docroot.createElement("userrating");
759  item.appendChild(userrating);
760  userrating.appendChild(docroot.createTextNode(QString::number(
761  lookup->GetUserRating())));
762  }
763  // Rating Count
764  if (lookup->GetRatingCount() > 0)
765  {
766  QDomElement ratingcount = docroot.createElement("ratingcount");
767  item.appendChild(ratingcount);
768  ratingcount.appendChild(docroot.createTextNode(QString::number(
769  lookup->GetRatingCount())));
770  }
771  // Track Number
772  if (lookup->GetTrackNumber() > 0)
773  {
774  QDomElement tracknum = docroot.createElement("tracknum");
775  item.appendChild(tracknum);
776  tracknum.appendChild(docroot.createTextNode(QString::number(
777  lookup->GetTrackNumber())));
778  }
779  // Popularity
780  if (lookup->GetPopularity() > 0)
781  {
782  QDomElement popularity = docroot.createElement("popularity");
783  item.appendChild(popularity);
784  popularity.appendChild(docroot.createTextNode(QString::number(
785  lookup->GetPopularity())));
786  }
787  // Budget
788  if (lookup->GetBudget() > 0)
789  {
790  QDomElement budget = docroot.createElement("budget");
791  item.appendChild(budget);
792  budget.appendChild(docroot.createTextNode(QString::number(
793  lookup->GetBudget())));
794  }
795  // Revenue
796  if (lookup->GetRevenue() > 0)
797  {
798  QDomElement revenue = docroot.createElement("revenue");
799  item.appendChild(revenue);
800  revenue.appendChild(docroot.createTextNode(QString::number(
801  lookup->GetRevenue())));
802  }
803  // Runtime
804  auto minutes = lookup->GetRuntime();
805  if (minutes > 0min)
806  {
807  QDomElement runtime = docroot.createElement("runtime");
808  item.appendChild(runtime);
809  runtime.appendChild(docroot.createTextNode(QString::number(
810  minutes.count())));
811  }
812  // Runtimesecs
813  auto seconds = lookup->GetRuntimeSeconds();
814  if (seconds > 0s)
815  {
816  QDomElement runtimesecs = docroot.createElement("runtimesecs");
817  item.appendChild(runtimesecs);
818  runtimesecs.appendChild(docroot.createTextNode(QString::number(
819  seconds.count())));
820  }
821 
822  if (!lookup->GetCertification().isEmpty())
823  AddCertifications(lookup, item, docroot);
824  if (!lookup->GetCategories().empty())
825  AddCategories(lookup, item, docroot);
826  if (!lookup->GetStudios().empty())
827  AddStudios(lookup, item, docroot);
828  if (!lookup->GetCountries().empty())
829  AddCountries(lookup, item, docroot);
830 }
831 
833  QDomElement placetoadd,
834  QDomDocument docroot)
835 {
836  QString certstr = lookup->GetCertification();
837  QDomElement certifications = docroot.createElement("certifications");
838  placetoadd.appendChild(certifications);
839 
840  QDomElement cert = docroot.createElement("certification");
841  certifications.appendChild(cert);
842  cert.setAttribute("locale", gCoreContext->GetLocale()->GetCountryCode());
843  cert.setAttribute("name", certstr);
844 }
845 
847  QDomElement placetoadd,
848  QDomDocument docroot)
849 {
850  QStringList cats = lookup->GetCategories();
851  QDomElement categories = docroot.createElement("categories");
852  placetoadd.appendChild(categories);
853 
854  for (const auto & str : qAsConst(cats))
855  {
856  QDomElement cat = docroot.createElement("category");
857  categories.appendChild(cat);
858  cat.setAttribute("type", "genre");
859  cat.setAttribute("name", str);
860  }
861 }
862 
864  QDomElement placetoadd,
865  QDomDocument docroot)
866 {
867  QStringList studs = lookup->GetStudios();
868  QDomElement studios = docroot.createElement("studios");
869  placetoadd.appendChild(studios);
870 
871  for (const auto & str : qAsConst(studs))
872  {
873  QDomElement stud = docroot.createElement("studio");
874  studios.appendChild(stud);
875  stud.setAttribute("name", str);
876  }
877 }
878 
880  QDomElement placetoadd,
881  QDomDocument docroot)
882 {
883  QStringList counts = lookup->GetCountries();
884  QDomElement countries = docroot.createElement("countries");
885  placetoadd.appendChild(countries);
886 
887  for (const auto & str : qAsConst(counts))
888  {
889  QDomElement count = docroot.createElement("country");
890  countries.appendChild(count);
891  count.setAttribute("name", str);
892  }
893 }
894 
895 MetadataLookup* ParseMetadataItem(const QDomElement& item,
896  MetadataLookup *lookup,
897  bool passseas)
898 {
899  if (!lookup)
900  return new MetadataLookup();
901 
902  uint season = 0;
903  uint episode = 0;
904  uint chanid = 0;
905  uint programflags = 0;
906  uint audioproperties = 0;
907  uint videoproperties = 0;
908  uint subtitletype = 0;
909  uint tracknum = 0;
910  uint budget = 0;
911  uint revenue = 0;
912  uint year = 0;
913  uint ratingcount = 0;
914  QString title;
915  QString network;
916  QString status;
917  QString subtitle;
918  QString tagline;
919  QString description;
920  QString certification;
921  QString channum;
922  QString chansign;
923  QString channame;
924  QString chanplaybackfilters;
925  QString recgroup;
926  QString playgroup;
927  QString seriesid;
928  QString programid;
929  QString storagegroup;
930  QString album;
931  QString system;
932  QString inetref;
933  QString collectionref;
934  QString tmsref;
935  QString imdb;
936  QString homepage;
937  QString trailerURL;
938  QString language;
939  QStringList categories;
940  QStringList countries;
941  QStringList studios;
942  float userrating = 0;
943  float popularity = 0;
944  QDate releasedate;
945  QDateTime lastupdated;
946  QDateTime startts;
947  QDateTime endts;
948  QDateTime recstartts;
949  QDateTime recendts;
950  PeopleMap people;
951  ArtworkMap artwork;
952 
953  // Get the easy parses
954  language = item.firstChildElement("language").text();
955  title = Parse::UnescapeHTML(item.firstChildElement("title").text());
956  network = Parse::UnescapeHTML(item.firstChildElement("network").text());
957  status = Parse::UnescapeHTML(item.firstChildElement("status").text());
958  subtitle = Parse::UnescapeHTML(item.firstChildElement("subtitle").text());
959  tagline = Parse::UnescapeHTML(item.firstChildElement("tagline").text());
960  description = Parse::UnescapeHTML(item.firstChildElement("description").text());
961  album = Parse::UnescapeHTML(item.firstChildElement("albumname").text());
962  inetref = item.firstChildElement("inetref").text();
963  collectionref = item.firstChildElement("collectionref").text();
964  tmsref = item.firstChildElement("tmsref").text();
965  imdb = item.firstChildElement("imdb").text();
966  homepage = item.firstChildElement("homepage").text();
967  trailerURL = item.firstChildElement("trailer").text();
968 
969  // ProgramInfo specific parsing
970  chanid = item.firstChildElement("chanid").text().toUInt();
971  channum = item.firstChildElement("channum").text();
972  chansign = item.firstChildElement("chansign").text();
973  channame = item.firstChildElement("channame").text();
974  chanplaybackfilters = item.firstChildElement("chanplaybackfilters").text();
975  recgroup = item.firstChildElement("recgroup").text();
976  playgroup = item.firstChildElement("playgroup").text();
977  seriesid = item.firstChildElement("seriesid").text();
978  programid = item.firstChildElement("programid").text();
979  storagegroup = item.firstChildElement("storagegroup").text();
980  startts = RFC822TimeToQDateTime(item.
981  firstChildElement("startts").text());
982  endts = RFC822TimeToQDateTime(item.
983  firstChildElement("endts").text());
984  recstartts = RFC822TimeToQDateTime(item.
985  firstChildElement("recstartts").text());
986  recendts = RFC822TimeToQDateTime(item.
987  firstChildElement("recendts").text());
988  programflags = item.firstChildElement("programflags").text().toUInt();
989  audioproperties = item.firstChildElement("audioproperties").text().toUInt();
990  videoproperties = item.firstChildElement("videoproperties").text().toUInt();
991  subtitletype = item.firstChildElement("subtitletype").text().toUInt();
992 
993  QString tmpDate = item.firstChildElement("releasedate").text();
994  if (!tmpDate.isEmpty())
995  releasedate = QDate::fromString(tmpDate, "yyyy-MM-dd");
996  lastupdated = RFC822TimeToQDateTime(item.
997  firstChildElement("lastupdated").text());
998 
999  userrating = item.firstChildElement("userrating").text().toFloat();
1000  ratingcount = item.firstChildElement("ratingcount").text().toUInt();
1001  tracknum = item.firstChildElement("tracknum").text().toUInt();
1002  popularity = item.firstChildElement("popularity").text().toFloat();
1003  budget = item.firstChildElement("budget").text().toUInt();
1004  revenue = item.firstChildElement("revenue").text().toUInt();
1005  year = item.firstChildElement("year").text().toUInt();
1006  if (!year && !releasedate.isNull())
1007  year = releasedate.toString("yyyy").toUInt();
1008  auto runtime = std::chrono::minutes(item.firstChildElement("runtime").text().toUInt());
1009  auto runtimesecs = std::chrono::seconds(item.firstChildElement("runtimesecs").text().toUInt());
1010 
1011  QDomElement systems = item.firstChildElement("systems");
1012  if (!systems.isNull())
1013  {
1014  QDomElement firstSystem = systems.firstChildElement("system");
1015  if (!firstSystem.isNull())
1016  system = firstSystem.text();
1017  }
1018 
1019  // TODO: Once TMDB supports certification per-locale, come back and match
1020  // locale of myth to certification locale.
1021  QDomElement certifications = item.firstChildElement("certifications");
1022  QVector< QPair<QString,QString> > ratinglist;
1023  if (!certifications.isNull())
1024  {
1025  QDomElement cert = certifications.firstChildElement("certification");
1026  if (!cert.isNull())
1027  {
1028  while (!cert.isNull())
1029  {
1030  if (cert.hasAttribute("locale") && cert.hasAttribute("name"))
1031  {
1032  QPair<QString,QString> newcert(cert.attribute("locale"),
1033  cert.attribute("name"));
1034  ratinglist.append(newcert);
1035  }
1036  cert = cert.nextSiblingElement("certification");
1037  }
1038  }
1039  }
1040  // HACK: To go away when someone supports ratings by locale.
1041  if (!ratinglist.isEmpty())
1042  certification = ratinglist.takeFirst().second;
1043 
1044  // Categories
1045  QDomElement categoriesxml = item.firstChildElement("categories");
1046  if (!categoriesxml.isNull())
1047  {
1048  QDomElement cat = categoriesxml.firstChildElement("category");
1049  if (!cat.isNull())
1050  {
1051  while (!cat.isNull())
1052  {
1053  if (cat.hasAttribute("name"))
1054  categories.append(cat.attribute("name"));
1055  cat = cat.nextSiblingElement("category");
1056  }
1057  }
1058  }
1059 
1060  // Countries
1061  QDomElement countriesxml = item.firstChildElement("countries");
1062  if (!countriesxml.isNull())
1063  {
1064  QDomElement cntry = countriesxml.firstChildElement("country");
1065  if (!cntry.isNull())
1066  {
1067  while (!cntry.isNull())
1068  {
1069  if (cntry.hasAttribute("name"))
1070  countries.append(cntry.attribute("name"));
1071  cntry = cntry.nextSiblingElement("country");
1072  }
1073  }
1074  }
1075 
1076  // Studios
1077  QDomElement studiosxml = item.firstChildElement("studios");
1078  if (!studiosxml.isNull())
1079  {
1080  QDomElement studio = studiosxml.firstChildElement("studio");
1081  if (!studio.isNull())
1082  {
1083  while (!studio.isNull())
1084  {
1085  if (studio.hasAttribute("name"))
1086  studios.append(studio.attribute("name"));
1087  studio = studio.nextSiblingElement("studio");
1088  }
1089  }
1090  }
1091 
1092  // People
1093  QDomElement peoplexml = item.firstChildElement("people");
1094  if (!peoplexml.isNull())
1095  {
1096  people = ParsePeople(peoplexml);
1097  }
1098 
1099  // Artwork
1100  QDomElement artworkxml = item.firstChildElement("images");
1101  if (!artworkxml.isNull())
1102  {
1103  artwork = ParseArtwork(artworkxml);
1104  }
1105 
1106  // Have to handle season and episode a little differently.
1107  // If the query object comes in with a season or episode number,
1108  // we want to pass that through. However, if we are doing a title/subtitle
1109  // lookup, we need to parse for season and episode.
1110  if (passseas)
1111  {
1112  season = lookup->GetSeason();
1113  episode = lookup->GetEpisode();
1114  }
1115 
1116  if (lookup->GetPreferDVDOrdering())
1117  {
1118  if (!season)
1119  {
1120  season = item.firstChildElement("dvdseason").text().toUInt();
1121  }
1122  if (!episode)
1123  {
1124  episode = item.firstChildElement("dvdepisode").text().toUInt();
1125  }
1126  }
1127 
1128  if (!season)
1129  {
1130  season = item.firstChildElement("season").text().toUInt();
1131  }
1132  if (!episode)
1133  {
1134  episode = item.firstChildElement("episode").text().toUInt();
1135  }
1136  LOG(VB_GENERAL, LOG_INFO, QString("Result Found, Season %1 Episode %2")
1137  .arg(season).arg(episode));
1138 
1139  return new MetadataLookup(lookup->GetType(), lookup->GetSubtype(),
1140  lookup->GetData(), lookup->GetStep(), lookup->GetAutomatic(),
1141  lookup->GetHandleImages(), lookup->GetAllowOverwrites(),
1142  lookup->GetAllowGeneric(), lookup->GetPreferDVDOrdering(), lookup->GetHost(),
1143  lookup->GetFilename(), title, network, status, categories, userrating,
1144  ratingcount, language, subtitle, tagline, description, season,
1145  episode, chanid, channum, chansign, channame,
1146  chanplaybackfilters, recgroup, playgroup, seriesid, programid,
1147  storagegroup, startts, endts, recstartts, recendts, programflags,
1148  audioproperties, videoproperties, subtitletype, certification,
1149  countries, popularity, budget, revenue, album, tracknum, system, year,
1150  releasedate, lastupdated, runtime, runtimesecs, inetref, collectionref,
1151  tmsref, imdb, people, studios, homepage, trailerURL, artwork, DownloadMap());
1152 }
1153 
1154 MetadataLookup* ParseMetadataMovieNFO(const QDomElement& item,
1155  MetadataLookup *lookup)
1156 {
1157  if (!lookup)
1158  return new MetadataLookup();
1159 
1160  uint year = 0;
1161  uint season = 0;
1162  uint episode = 0;
1163  QString title;
1164  QString subtitle;
1165  QString tagline;
1166  QString description;
1167  QString inetref;
1168  QString trailer;
1169  QString certification;
1170  float userrating = 0;
1171  QDate releasedate;
1172  QStringList categories;
1173  PeopleMap people;
1174  ArtworkMap artwork;
1175 
1176  // Get the easy parses
1177  if (item.tagName() == "movie")
1178  title = Parse::UnescapeHTML(item.firstChildElement("title").text());
1179  else if (item.tagName() == "episodedetails")
1180  subtitle = Parse::UnescapeHTML(item.firstChildElement("title").text());
1181  userrating = item.firstChildElement("rating").text().toFloat();
1182  year = item.firstChildElement("year").text().toUInt();
1183  season = item.firstChildElement("season").text().toUInt();
1184  episode = item.firstChildElement("episode").text().toUInt();
1185  description = Parse::UnescapeHTML(item.firstChildElement("plot").text());
1186  tagline = Parse::UnescapeHTML(item.firstChildElement("tagline").text());
1187  inetref = item.firstChildElement("id").text();
1188  trailer = item.firstChildElement("trailer").text();
1189  certification = item.firstChildElement("mpaa").text();
1190  categories.append(item.firstChildElement("genre").text());
1191 
1192  QString tmpDate = item.firstChildElement("releasedate").text();
1193  if (!tmpDate.isEmpty())
1194  releasedate = QDate::fromString(tmpDate, "yyyy-MM-dd");
1195  else if (year > 0)
1196  releasedate = QDate::fromString(QString::number(year), "yyyy");
1197 
1198  auto runtime =
1199  std::chrono::minutes(item.firstChildElement("runtime").text()
1200  .remove(QRegularExpression("[A-Za-z]"))
1201  .trimmed().toUInt());
1202 
1203  QDomElement actor = item.firstChildElement("actor");
1204  if (!actor.isNull())
1205  {
1206  while (!actor.isNull())
1207  {
1208  PersonInfo info;
1209  info.name = actor.firstChildElement("name").text();
1210  info.role = actor.firstChildElement("role").text();
1211  info.thumbnail = actor.firstChildElement("thumb").text();
1212  people.insert(kPersonActor, info);
1213  actor = actor.nextSiblingElement("actor");
1214  }
1215  }
1216 
1217  QString director = item.firstChildElement("director").text();
1218  if (!director.isEmpty())
1219  {
1220  PersonInfo info;
1221  info.name = director;
1222  people.insert(kPersonDirector, info);
1223  }
1224 
1225  return new MetadataLookup(lookup->GetType(), lookup->GetSubtype(),
1226  lookup->GetData(), lookup->GetStep(),
1227  lookup->GetAutomatic(), lookup->GetHandleImages(),
1228  lookup->GetAllowOverwrites(), lookup->GetAllowGeneric(),
1229  lookup->GetPreferDVDOrdering(), lookup->GetHost(),
1230  lookup->GetFilename(), title, categories,
1231  userrating, subtitle, tagline, description, season, episode,
1232  certification, year, releasedate, runtime, runtime,
1233  inetref, people, trailer, artwork, DownloadMap());
1234 }
1235 
1236 PeopleMap ParsePeople(const QDomElement& people)
1237 {
1238  PeopleMap ret;
1239 
1240  QDomElement person = people.firstChildElement("person");
1241  if (!person.isNull())
1242  {
1243  while (!person.isNull())
1244  {
1245  if (person.hasAttribute("job"))
1246  {
1247  QString jobstring = person.attribute("job");
1249  if (jobstring.toLower() == "actor")
1250  type = kPersonActor; // NOLINT(bugprone-branch-clone)
1251  else if (jobstring.toLower() == "author")
1252  type = kPersonAuthor;
1253  else if (jobstring.toLower() == "producer")
1255  else if (jobstring.toLower() == "executive producer")
1257  else if (jobstring.toLower() == "director")
1259  else if (jobstring.toLower() == "cinematographer")
1261  else if (jobstring.toLower() == "composer")
1263  else if (jobstring.toLower() == "editor")
1264  type = kPersonEditor;
1265  else if (jobstring.toLower() == "casting")
1267  else if (jobstring.toLower() == "artist")
1268  type = kPersonArtist;
1269  else if (jobstring.toLower() == "album artist")
1271  else if (jobstring.toLower() == "guest star")
1273  else
1274  type = kPersonActor;
1275 
1276  PersonInfo info;
1277  if (person.hasAttribute("name"))
1278  info.name = person.attribute("name");
1279  if (person.hasAttribute("character"))
1280  info.role = person.attribute("character");
1281  if (person.hasAttribute("thumb"))
1282  info.thumbnail = person.attribute("thumb");
1283  if (person.hasAttribute("url"))
1284  info.url = person.attribute("url");
1285 
1286  ret.insert(type,info);
1287  }
1288  person = person.nextSiblingElement("person");
1289  }
1290  }
1291  return ret;
1292 }
1293 
1294 ArtworkMap ParseArtwork(const QDomElement& artwork)
1295 {
1296  ArtworkMap ret;
1297 
1298  QDomElement image = artwork.firstChildElement("image");
1299  if (!image.isNull())
1300  {
1301  while (!image.isNull())
1302  {
1303  if (image.hasAttribute("type"))
1304  {
1305  QString typestring = image.attribute("type");
1307  if (typestring.toLower() == "coverart")
1308  type = kArtworkCoverart; // NOLINT(bugprone-branch-clone)
1309  else if (typestring.toLower() == "fanart")
1310  type = kArtworkFanart;
1311  else if (typestring.toLower() == "banner")
1312  type = kArtworkBanner;
1313  else if (typestring.toLower() == "screenshot")
1315  else if (typestring.toLower() == "poster")
1316  type = kArtworkPoster;
1317  else if (typestring.toLower() == "back cover")
1319  else if (typestring.toLower() == "inside cover")
1321  else if (typestring.toLower() == "cd image")
1323  else
1325 
1326  ArtworkInfo info;
1327  if (image.hasAttribute("thumb"))
1328  info.thumbnail = image.attribute("thumb");
1329  if (image.hasAttribute("url"))
1330  info.url = image.attribute("url");
1331  if (image.hasAttribute("width"))
1332  info.width = image.attribute("width").toUInt();
1333  else
1334  info.width = 0;
1335  if (image.hasAttribute("height"))
1336  info.height = image.attribute("height").toUInt();
1337  else
1338  info.height = 0;
1339 
1340  ret.insert(type,info);
1341  }
1342  image = image.nextSiblingElement("image");
1343  }
1344  }
1345  return ret;
1346 }
1347 
1348 int editDistance( const QString& s, const QString& t )
1349 {
1350 #define D( i, j ) d[(i) * n + (j)]
1351  int m = s.length() + 1;
1352  int n = t.length() + 1;
1353  int *d = new int[m * n];
1354 
1355  for ( int i = 0; i < m; i++ )
1356  D( i, 0 ) = i;
1357  for ( int j = 0; j < n; j++ )
1358  D( 0, j ) = j;
1359  for ( int i = 1; i < m; i++ )
1360  {
1361  for ( int j = 1; j < n; j++ )
1362  {
1363  if ( s[i - 1] == t[j - 1] )
1364  D( i, j ) = D( i - 1, j - 1 );
1365  else
1366  {
1367  int x = D( i - 1, j );
1368  int y = D( i - 1, j - 1 );
1369  int z = D( i, j - 1 );
1370  D( i, j ) = 1 + std::min({x, y, z});
1371  }
1372  }
1373  }
1374  int result = D( m - 1, n - 1 );
1375  delete[] d;
1376  return result;
1377 #undef D
1378 }
1379 
1380 QString nearestName(const QString& actual, const QStringList& candidates)
1381 {
1382  int deltaBest = 10000;
1383  int numBest = 0;
1384  int tolerance = gCoreContext->GetNumSetting("MetadataLookupTolerance", 5);
1385  QString best;
1386 
1387  QStringList::ConstIterator i = candidates.begin();
1388  while ( i != candidates.end() )
1389  {
1390  QString candidate = *i;
1391  int delta = editDistance( actual.toLower(), candidate.toLower() );
1392  if ( delta < deltaBest )
1393  {
1394  deltaBest = delta;
1395  numBest = 1;
1396  best = *i;
1397  }
1398  else if ( delta == deltaBest )
1399  {
1400  numBest++;
1401  }
1402  ++i;
1403  }
1404 
1405  if ( numBest == 1 && deltaBest <= tolerance &&
1406  actual.length() + best.length() >= 5 )
1407  return best;
1408  return QString();
1409 }
1410 
1411 QDateTime RFC822TimeToQDateTime(const QString& t)
1412 {
1413  QMap<QString, int> TimezoneOffsets;
1414 
1415  if (t.size() < 20)
1416  return QDateTime();
1417 
1418  QString time = t.simplified();
1419  short int hoursShift = 0;
1420  short int minutesShift = 0;
1421 
1422  QStringList tmp = time.split(' ');
1423  if (tmp.isEmpty())
1424  return QDateTime();
1425  if (tmp.at(0).contains(QRegularExpression("\\D")))
1426  tmp.removeFirst();
1427  if (tmp.size() != 5)
1428  return QDateTime();
1429  QString ltimezone = tmp.takeAt(tmp.size() -1);
1430  if (ltimezone.size() == 5)
1431  {
1432  bool ok = false;
1433  int tz = ltimezone.toInt(&ok);
1434  if(ok)
1435  {
1436  hoursShift = tz / 100;
1437  minutesShift = tz % 100;
1438  }
1439  }
1440  else
1441  hoursShift = TimezoneOffsets.value(ltimezone, 0);
1442 
1443  if (tmp.at(0).size() == 1)
1444  tmp[0].prepend("0");
1445  tmp [1].truncate(3);
1446 
1447  time = tmp.join(" ");
1448 
1449  QDateTime result;
1450  if (tmp.at(2).size() == 4)
1451  result = QLocale::c().toDateTime(time, "dd MMM yyyy hh:mm:ss");
1452  else
1453  result = QLocale::c().toDateTime(time, "dd MMM yy hh:mm:ss");
1454  if (result.isNull() || !result.isValid())
1455  return QDateTime();
1456  result = result.addSecs(hoursShift * 3600 * (-1) + minutesShift *60 * (-1));
1457  result.setTimeSpec(Qt::UTC);
1458  return result;
1459 }
MetadataLookup::m_season
uint m_season
Definition: metadatacommon.h:401
PeopleType
PeopleType
Definition: metadatacommon.h:69
MetadataLookup::m_network
QString m_network
Definition: metadatacommon.h:390
MetadataLookup::m_system
QString m_system
Definition: metadatacommon.h:433
VideoArtworkType
VideoArtworkType
Definition: metadataimagehelper.h:10
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MetadataLookup::GetTMSref
QString GetTMSref() const
Definition: metadatacommon.h:359
MetadataLookup::GetTrackNumber
uint GetTrackNumber() const
Definition: metadatacommon.h:343
MetadataLookup::m_tagline
const QString m_tagline
Definition: metadatacommon.h:399
MetadataLookup::m_people
const PeopleMap m_people
Definition: metadatacommon.h:450
kArtworkInsideCover
@ kArtworkInsideCover
Definition: metadataimagehelper.h:17
MetadataLookup::m_recStartTs
const QDateTime m_recStartTs
Definition: metadatacommon.h:415
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
ProgramInfo::GetHostname
QString GetHostname(void) const
Definition: programinfo.h:421
kMetadataRecording
@ kMetadataRecording
Definition: metadatacommon.h:44
MetadataLookup::m_filename
QString m_filename
Definition: metadatacommon.h:387
MetadataType
MetadataType
Definition: metadatacommon.h:42
MetadataLookup::GetTitle
QString GetTitle() const
Definition: metadatacommon.h:299
MetadataLookup::m_year
uint m_year
Definition: metadatacommon.h:436
MetadataLookup::m_releaseDate
const QDate m_releaseDate
Definition: metadatacommon.h:437
MythCoreContext::GetLocale
MythLocale * GetLocale(void) const
Definition: mythcorecontext.cpp:1768
ArtworkList
QList< ArtworkInfo > ArtworkList
Definition: metadataimagehelper.h:30
MetadataLookup::GetSubtype
LookupType GetSubtype() const
Definition: metadatacommon.h:287
MetadataLookup::m_collectionRef
QString m_collectionRef
Definition: metadatacommon.h:444
MetadataLookup::GetNetwork
QString GetNetwork() const
Definition: metadatacommon.h:308
Parse::UnescapeHTML
static QString UnescapeHTML(const QString &escaped)
Definition: rssparse.cpp:1139
ProgramInfo::GetChannelName
QString GetChannelName(void) const
This is the channel name in the local market, i.e.
Definition: programinfo.h:386
MetadataLookup::m_runtimeSecs
std::chrono::seconds m_runtimeSecs
Definition: metadatacommon.h:440
kPersonAuthor
@ kPersonAuthor
Definition: metadatacommon.h:71
hardwareprofile.devicelist.cat
def cat(file_name)
Definition: devicelist.py:95
ProgramInfo::GetChanNum
QString GetChanNum(void) const
This is the channel "number", in the form 1, 1_2, 1-2, 1#1, etc.
Definition: programinfo.h:376
PersonInfo::role
QString role
Definition: metadatacommon.h:36
MetadataLookup::GetLanguage
QString GetLanguage() const
Definition: metadatacommon.h:304
rssparse.h
MetadataLookup::m_chanNum
const QString m_chanNum
Definition: metadatacommon.h:404
kPersonProducer
@ kPersonProducer
Definition: metadatacommon.h:73
MetadataLookup::GetAlbumTitle
QString GetAlbumTitle() const
Definition: metadatacommon.h:342
MetadataLookup::m_seriesId
const QString m_seriesId
Definition: metadatacommon.h:410
ProgramInfo::GetChannelSchedulingID
QString GetChannelSchedulingID(void) const
This is the unique programming identifier of a channel.
Definition: programinfo.h:383
ProgramInfo::GetCategory
QString GetCategory(void) const
Definition: programinfo.h:369
MetadataLookup::m_homepage
const QString m_homepage
Definition: metadatacommon.h:454
MetadataLookup::GetSeriesId
QString GetSeriesId() const
Definition: metadatacommon.h:323
MetadataLookup::GetArtwork
ArtworkList GetArtwork(VideoArtworkType type) const
Definition: metadatacommon.cpp:330
MetadataLookup::m_endTs
const QDateTime m_endTs
Definition: metadatacommon.h:414
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
ProgramInfo::GetScheduledEndTime
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
Definition: programinfo.h:397
kPersonEditor
@ kPersonEditor
Definition: metadatacommon.h:77
MetadataLookup::m_chanPlaybackFilters
const QString m_chanPlaybackFilters
Definition: metadatacommon.h:407
MetadataLookup::GetCertification
QString GetCertification() const
Definition: metadatacommon.h:335
MetadataLookup::m_chanId
uint m_chanId
Definition: metadatacommon.h:403
ArtworkInfo::width
uint width
Definition: metadataimagehelper.h:26
kArtworkBackCover
@ kArtworkBackCover
Definition: metadataimagehelper.h:16
ProgramInfo::GetRecordingEndTime
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
Definition: programinfo.h:412
ProgramInfo::GetProgramFlags
uint32_t GetProgramFlags(void) const
Definition: programinfo.h:472
ProgramInfo::GetRecordingGroup
QString GetRecordingGroup(void) const
Definition: programinfo.h:419
kArtworkCDImage
@ kArtworkCDImage
Definition: metadataimagehelper.h:18
MetadataLookup::GetBudget
uint GetBudget() const
Definition: metadatacommon.h:338
MetadataLookup::GetAudioProperties
uint GetAudioProperties() const
Definition: metadatacommon.h:331
MetadataLookup::m_storageGroup
const QString m_storageGroup
Definition: metadatacommon.h:412
MetadataLookup::m_playGroup
const QString m_playGroup
Definition: metadatacommon.h:409
MetadataLookup::GetTrailerURL
QString GetTrailerURL() const
Definition: metadatacommon.h:368
MetadataLookup::GetPreferDVDOrdering
bool GetPreferDVDOrdering() const
Definition: metadatacommon.h:313
MetadataLookup::toMap
void toMap(InfoMap &map)
Definition: metadatacommon.cpp:347
ProgramInfo::GetRecordingStartTime
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
Definition: programinfo.h:404
kPersonGuestStar
@ kPersonGuestStar
Definition: metadatacommon.h:81
tmp
static guint32 * tmp
Definition: goom_core.cpp:32
MetadataLookup::GetStep
LookupStep GetStep() const
Definition: metadatacommon.h:289
nearestName
QString nearestName(const QString &actual, const QStringList &candidates)
Definition: metadatacommon.cpp:1380
MetadataLookup
Definition: metadatacommon.h:87
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MetadataLookup::m_subtitle
QString m_subtitle
Definition: metadatacommon.h:398
RFC822TimeToQDateTime
QDateTime RFC822TimeToQDateTime(const QString &t)
Definition: metadatacommon.cpp:1411
AddCertifications
void AddCertifications(MetadataLookup *lookup, QDomElement placetoadd, QDomDocument docroot)
Definition: metadatacommon.cpp:832
MetadataLookup::GetRatingCount
uint GetRatingCount() const
Definition: metadatacommon.h:303
MetadataLookup::m_inetRef
QString m_inetRef
Definition: metadatacommon.h:443
ProgramInfo::GetInetRef
QString GetInetRef(void) const
Definition: programinfo.h:437
MetadataLookup::GetChanSign
QString GetChanSign() const
Definition: metadatacommon.h:318
ProgramInfo::GetYearOfInitialRelease
uint GetYearOfInitialRelease(void) const
Definition: programinfo.h:423
kPersonCastingDirector
@ kPersonCastingDirector
Definition: metadatacommon.h:78
PersonInfo::thumbnail
QString thumbnail
Definition: metadatacommon.h:37
MetadataLookup::m_baseTitle
QString m_baseTitle
Definition: metadatacommon.h:389
MetadataLookup::m_runtime
std::chrono::minutes m_runtime
Definition: metadatacommon.h:439
programinfo.h
ProgramInfo::GetScheduledStartTime
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
Definition: programinfo.h:390
mythlogging.h
MythLocale::GetCountryCode
QString GetCountryCode() const
Definition: mythlocale.cpp:57
MetadataLookup::GetEpisode
uint GetEpisode() const
Definition: metadatacommon.h:315
MetadataLookup::GetDescription
QString GetDescription() const
Definition: metadatacommon.h:312
MetadataLookup::GetIMDB
QString GetIMDB() const
Definition: metadatacommon.h:358
MetadataLookup::m_revenue
uint m_revenue
Definition: metadatacommon.h:426
kPersonActor
@ kPersonActor
Definition: metadatacommon.h:70
MetadataLookup::GetAllowOverwrites
bool GetAllowOverwrites() const
Definition: metadatacommon.h:294
MetadataLookup::m_lastUpdated
const QDateTime m_lastUpdated
Definition: metadatacommon.h:438
ArtworkInfo
Definition: metadataimagehelper.h:21
ParsePeople
PeopleMap ParsePeople(const QDomElement &people)
Definition: metadatacommon.cpp:1236
hardwareprofile.i18n.t
t
Definition: i18n.py:36
PersonInfo::url
QString url
Definition: metadatacommon.h:38
MetadataLookup::m_album
QString m_album
Definition: metadatacommon.h:429
RefCountedList
General purpose reference counted list.
Definition: referencecounterlist.h:55
MetadataLookup::GetData
QVariant GetData() const
Definition: metadatacommon.h:288
MetadataLookup::GetStartTS
QDateTime GetStartTS() const
Definition: metadatacommon.h:326
ProgramInfo::GetTitle
QString GetTitle(void) const
Definition: programinfo.h:361
ProgramInfo::GetDescription
QString GetDescription(void) const
Definition: programinfo.h:365
kLookupData
@ kLookupData
Definition: metadatacommon.h:29
kArtworkPoster
@ kArtworkPoster
Definition: metadataimagehelper.h:15
kPersonDirector
@ kPersonDirector
Definition: metadatacommon.h:72
ParseArtwork
ArtworkMap ParseArtwork(const QDomElement &artwork)
Definition: metadatacommon.cpp:1294
CreateMetadataXMLItem
void CreateMetadataXMLItem(MetadataLookup *lookup, QDomElement placetoadd, QDomDocument docroot)
Definition: metadatacommon.cpp:478
MetadataLookup::m_artwork
const ArtworkMap m_artwork
Definition: metadatacommon.h:458
MetadataLookup::m_episode
uint m_episode
Definition: metadatacommon.h:402
MetadataLookup::GetType
MetadataType GetType() const
Definition: metadatacommon.h:286
x0
static int x0
Definition: metadatacommon.cpp:18
MetadataLookup::m_countries
const QStringList m_countries
Definition: metadatacommon.h:423
MetadataLookup::GetChanNum
QString GetChanNum() const
Definition: metadatacommon.h:317
MetadataLookup::m_studios
const QStringList m_studios
Definition: metadatacommon.h:451
MetadataLookup::GetRecGroup
QString GetRecGroup() const
Definition: metadatacommon.h:321
kArtworkFanart
@ kArtworkFanart
Definition: metadataimagehelper.h:12
MetadataLookup::GetSubtitle
QString GetSubtitle() const
Definition: metadatacommon.h:310
MetadataLookup::GetCountries
QStringList GetCountries() const
Definition: metadatacommon.h:336
MetadataLookup::GetLastUpdated
QDateTime GetLastUpdated() const
Definition: metadatacommon.h:351
MetadataLookup::GetVideoProperties
uint GetVideoProperties() const
Definition: metadatacommon.h:332
MetadataLookup::GetRecEndTS
QDateTime GetRecEndTS() const
Definition: metadatacommon.h:329
ProgramInfo::GetAudioProperties
uint GetAudioProperties(void) const
Definition: programinfo.h:499
MetadataLookup::m_recEndTs
const QDateTime m_recEndTs
Definition: metadatacommon.h:416
kPersonComposer
@ kPersonComposer
Definition: metadatacommon.h:76
MetadataLookup::GetPeople
QList< PersonInfo > GetPeople(PeopleType type) const
Definition: metadatacommon.cpp:314
ProgramInfo::GetPlaybackGroup
QString GetPlaybackGroup(void) const
Definition: programinfo.h:420
kPersonAlbumArtist
@ kPersonAlbumArtist
Definition: metadatacommon.h:80
mythlocale.h
ProgramInfo::GetChannelPlaybackFilters
QString GetChannelPlaybackFilters(void) const
Definition: programinfo.h:387
MetadataLookup::GetCollectionref
QString GetCollectionref() const
Definition: metadatacommon.h:357
MetadataLookup::m_certification
const QString m_certification
Definition: metadatacommon.h:422
MetadataLookup::GetHandleImages
bool GetHandleImages() const
Definition: metadatacommon.h:293
uint
unsigned int uint
Definition: compat.h:79
MetadataLookup::GetUserRating
float GetUserRating() const
Definition: metadatacommon.h:302
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:59
ProgramInfo::GetSeriesID
QString GetSeriesID(void) const
Definition: programinfo.h:435
MetadataLookup::m_popularity
float m_popularity
Definition: metadatacommon.h:424
MetadataLookup::m_imdb
QString m_imdb
Definition: metadatacommon.h:446
MetadataLookup::GetAllowGeneric
bool GetAllowGeneric() const
Definition: metadatacommon.h:295
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:916
ProgramInfo::GetStorageGroup
QString GetStorageGroup(void) const
Definition: programinfo.h:422
ProgramInfo::GetOriginalAirDate
QDate GetOriginalAirDate(void) const
Definition: programinfo.h:428
MetadataLookup::GetSeason
uint GetSeason() const
Definition: metadatacommon.h:314
PeopleMap
QMultiMap< PeopleType, PersonInfo > PeopleMap
Definition: metadatacommon.h:85
MetadataLookup::GetFilename
QString GetFilename() const
Definition: metadatacommon.h:298
ProgramInfo::GetVideoProperties
uint GetVideoProperties(void) const
Definition: programinfo.h:497
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
kUnknownVideo
@ kUnknownVideo
Definition: metadatacommon.h:54
MetadataLookup::GetPopularity
float GetPopularity() const
Definition: metadatacommon.h:337
MetadataLookup::GetCategories
QStringList GetCategories() const
Definition: metadatacommon.h:301
MetadataLookup::m_categories
const QStringList m_categories
Definition: metadatacommon.h:392
MetadataLookup::GetStatus
QString GetStatus() const
Definition: metadatacommon.h:309
ProgramInfo::GetChanID
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:372
MetadataLookup::GetRuntime
std::chrono::minutes GetRuntime() const
Definition: metadatacommon.h:352
MetadataLookup::m_title
QString m_title
Definition: metadatacommon.h:388
ProgramInfo::GetEpisode
uint GetEpisode(void) const
Definition: programinfo.h:367
MetadataLookup::m_description
const QString m_description
Definition: metadatacommon.h:400
MetadataLookup::GetChanPlaybackFilters
QString GetChanPlaybackFilters() const
Definition: metadatacommon.h:320
MetadataLookup::m_tmsRef
QString m_tmsRef
Definition: metadatacommon.h:445
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
mythmiscutil.h
MetadataLookup::GetStorageGroup
QString GetStorageGroup() const
Definition: metadatacommon.h:325
ProgramInfo::GetLastModifiedTime
QDateTime GetLastModifiedTime(void) const
Definition: programinfo.h:429
ProgramInfo::GetSeason
uint GetSeason(void) const
Definition: programinfo.h:366
mythcorecontext.h
AddCountries
void AddCountries(MetadataLookup *lookup, QDomElement placetoadd, QDomDocument docroot)
Definition: metadatacommon.cpp:879
MetadataLookup::m_language
const QString m_language
Definition: metadatacommon.h:395
MetadataLookup::GetTagline
QString GetTagline() const
Definition: metadatacommon.h:311
MetadataLookup::GetRevenue
uint GetRevenue() const
Definition: metadatacommon.h:339
MetadataLookup::m_programid
const QString m_programid
Definition: metadatacommon.h:411
MetadataLookup::m_trailerURL
const QString m_trailerURL
Definition: metadatacommon.h:455
MetadataLookup::GetInetref
QString GetInetref() const
Definition: metadatacommon.h:356
MetadataLookup::m_chanName
const QString m_chanName
Definition: metadatacommon.h:406
MetadataLookup::MetadataLookup
MetadataLookup(void)
Definition: metadatacommon.h:90
PersonInfo::name
QString name
Definition: metadatacommon.h:35
std
Definition: mythchrono.h:23
MetadataLookup::GetStudios
QStringList GetStudios() const
Definition: metadatacommon.h:364
ArtworkInfo::height
uint height
Definition: metadataimagehelper.h:27
kPersonExecProducer
@ kPersonExecProducer
Definition: metadatacommon.h:74
MetadataLookup::GetRecStartTS
QDateTime GetRecStartTS() const
Definition: metadatacommon.h:328
AddCategories
void AddCategories(MetadataLookup *lookup, QDomElement placetoadd, QDomDocument docroot)
Definition: metadatacommon.cpp:846
kPersonCinematographer
@ kPersonCinematographer
Definition: metadatacommon.h:75
MetadataLookup::m_budget
uint m_budget
Definition: metadatacommon.h:425
MetadataLookup::m_ratingCount
uint m_ratingCount
Definition: metadatacommon.h:394
MetadataLookup::GetSubtitleType
uint GetSubtitleType() const
Definition: metadatacommon.h:333
LookupType
LookupType
Definition: metadatacommon.h:50
CreateMetadataXML
QDomDocument CreateMetadataXML(MetadataLookupList list)
Definition: metadatacommon.cpp:439
kArtworkBanner
@ kArtworkBanner
Definition: metadataimagehelper.h:13
MythDate::kDateFull
@ kDateFull
Default local time.
Definition: mythdate.h:19
DownloadMap
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
Definition: metadatacommon.h:84
kPersonArtist
@ kPersonArtist
Definition: metadatacommon.h:79
ArtworkMap
QMultiMap< VideoArtworkType, ArtworkInfo > ArtworkMap
Definition: metadataimagehelper.h:31
ParseMetadataItem
MetadataLookup * ParseMetadataItem(const QDomElement &item, MetadataLookup *lookup, bool passseas)
Definition: metadatacommon.cpp:895
MetadataLookup::m_status
QString m_status
Definition: metadatacommon.h:391
ProgramInfo::GetProgramID
QString GetProgramID(void) const
Definition: programinfo.h:436
MetadataLookup::GetReleaseDate
QDate GetReleaseDate() const
Definition: metadatacommon.h:350
MetadataLookup::GetRuntimeSeconds
std::chrono::seconds GetRuntimeSeconds() const
Definition: metadatacommon.h:353
MetadataLookup::m_trackNum
uint m_trackNum
Definition: metadatacommon.h:430
MetadataLookup::m_startTs
const QDateTime m_startTs
Definition: metadatacommon.h:413
ArtworkInfo::thumbnail
QString thumbnail
Definition: metadataimagehelper.h:24
MetadataLookup::GetChanId
uint GetChanId() const
Definition: metadatacommon.h:316
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
kArtworkScreenshot
@ kArtworkScreenshot
Definition: metadataimagehelper.h:14
MetadataLookup::GetPlayGroup
QString GetPlayGroup() const
Definition: metadatacommon.h:322
MetadataLookup::GetAutomatic
bool GetAutomatic() const
Definition: metadatacommon.h:290
MetadataLookup::m_recGroup
const QString m_recGroup
Definition: metadatacommon.h:408
MetadataLookup::GetHomepage
QString GetHomepage() const
Definition: metadatacommon.h:367
ParseMetadataMovieNFO
MetadataLookup * ParseMetadataMovieNFO(const QDomElement &item, MetadataLookup *lookup)
Definition: metadatacommon.cpp:1154
MetadataLookup::GetHost
QString GetHost() const
Definition: metadatacommon.h:305
MetadataLookup::GetChanName
QString GetChanName() const
Definition: metadatacommon.h:319
AddStudios
void AddStudios(MetadataLookup *lookup, QDomElement placetoadd, QDomDocument docroot)
Definition: metadatacommon.cpp:863
ProgramInfo::GetBasename
QString GetBasename(void) const
Definition: programinfo.h:344
ProgramInfo::GetSubtitleType
uint GetSubtitleType(void) const
Definition: programinfo.h:495
build_compdb.filename
filename
Definition: build_compdb.py:21
MetadataLookup::GetProgramFlags
uint GetProgramFlags() const
Definition: metadatacommon.h:330
D
#define D(i, j)
PersonInfo
Definition: metadatacommon.h:33
MetadataLookup::GetEndTS
QDateTime GetEndTS() const
Definition: metadatacommon.h:327
metadatacommon.h
kArtworkCoverart
@ kArtworkCoverart
Definition: metadataimagehelper.h:11
ReferenceCounter
General purpose reference counter.
Definition: referencecounter.h:26
LookupFromProgramInfo
MetadataLookup * LookupFromProgramInfo(ProgramInfo *pginfo)
Definition: metadatacommon.cpp:409
MetadataLookup::GetProgramId
QString GetProgramId() const
Definition: metadatacommon.h:324
MetadataLookup::m_chanSign
const QString m_chanSign
Definition: metadatacommon.h:405
editDistance
int editDistance(const QString &s, const QString &t)
Definition: metadatacommon.cpp:1348
ArtworkInfo::url
QString url
Definition: metadataimagehelper.h:25
LookupStep
LookupStep
Definition: metadatacommon.h:27
ProgramInfo::GetSubtitle
QString GetSubtitle(void) const
Definition: programinfo.h:363
MetadataLookup::m_userRating
float m_userRating
Definition: metadatacommon.h:393
ProgramInfo::GetStars
float GetStars(void) const
Definition: programinfo.h:442