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