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