MythTV  master
metadatafactory.cpp
Go to the documentation of this file.
1 
2 #include "metadatafactory.h"
3 
4 // C++
5 #include <algorithm>
6 #include <unistd.h> // for sleep()
7 using std::max;
8 
9 // QT
10 #include <QApplication>
11 #include <QList>
12 #include <QUrl>
13 
14 // libmythbase
15 #include "mythlogging.h"
16 #include "compat.h"
17 
18 // libmyth
19 #include "mythcontext.h"
20 #include "remoteutil.h"
21 
22 // libmythmetadata
23 #include "videoutils.h"
24 
25 // Needed to perform a lookup
26 #include "metadatadownload.h"
27 #include "metadataimagedownload.h"
28 
29 // Needed for video scanning
31 #include "globals.h"
32 
33 // Input for a lookup
34 #include "videometadata.h"
35 #include "programinfo.h"
36 #include "recordingrule.h"
37 
38 
40  (QEvent::Type) QEvent::registerEventType();
41 
43 {
44  if (m_result)
45  {
46  m_result->DecrRef();
47  m_result = nullptr;
48  }
49 }
50 
52  (QEvent::Type) QEvent::registerEventType();
53 
55 {
56  if (m_result)
57  {
58  m_result->DecrRef();
59  m_result = nullptr;
60  }
61 }
62 
64  (QEvent::Type) QEvent::registerEventType();
65 
66 // Force this class to have a vtable so that dynamic_cast works.
67 // NOLINTNEXTLINE(modernize-use-equals-default)
69 {
70 }
71 
73  (QEvent::Type) QEvent::registerEventType();
74 
75 // Force this class to have a vtable so that dynamic_cast works.
76 // NOLINTNEXTLINE(modernize-use-equals-default)
78 {
79 }
80 
82  QObject(parent)
83 {
84  m_lookupthread = new MetadataDownload(this);
87 
89 }
90 
92 {
93  if (m_lookupthread)
94  {
96  delete m_lookupthread;
97  m_lookupthread = nullptr;
98  }
99 
100  if (m_imagedownload)
101  {
103  delete m_imagedownload;
104  m_imagedownload = nullptr;
105  }
106 
108  delete m_videoscanner;
109 
110  delete m_mlm;
111  m_mlm = nullptr;
112 }
113 
114 void MetadataFactory::Lookup(RecordingRule *recrule, bool automatic,
115  bool getimages, bool allowgeneric)
116 {
117  if (!recrule)
118  return;
119 
120  auto *lookup = new MetadataLookup();
121 
122  lookup->SetStep(kLookupSearch);
123  lookup->SetType(kMetadataRecording);
124  lookup->SetSubtype(GuessLookupType(recrule));
125  lookup->SetData(QVariant::fromValue(recrule));
126  lookup->SetAutomatic(automatic);
127  lookup->SetHandleImages(getimages);
128  lookup->SetAllowGeneric(allowgeneric);
129  lookup->SetHost(gCoreContext->GetMasterHostName());
130  lookup->SetTitle(recrule->m_title);
131  lookup->SetSubtitle(recrule->m_subtitle);
132  lookup->SetInetref(recrule->m_inetref);
133  lookup->SetSeason(recrule->m_season);
134  lookup->SetEpisode(recrule->m_episode);
135 
136  if (m_lookupthread->isRunning())
137  m_lookupthread->prependLookup(lookup);
138  else
139  m_lookupthread->addLookup(lookup);
140 }
141 
142 void MetadataFactory::Lookup(ProgramInfo *pginfo, bool automatic,
143  bool getimages, bool allowgeneric)
144 {
145  if (!pginfo)
146  return;
147 
148  auto *lookup = new MetadataLookup();
149 
150  lookup->SetStep(kLookupSearch);
151  lookup->SetType(kMetadataRecording);
152  lookup->SetSubtype(GuessLookupType(pginfo));
153  lookup->SetData(QVariant::fromValue(pginfo));
154  lookup->SetAutomatic(automatic);
155  lookup->SetHandleImages(getimages);
156  lookup->SetAllowGeneric(allowgeneric);
157  lookup->SetHost(gCoreContext->GetMasterHostName());
158  lookup->SetTitle(pginfo->GetTitle());
159  lookup->SetSubtitle(pginfo->GetSubtitle());
160  lookup->SetSeason(pginfo->GetSeason());
161  lookup->SetEpisode(pginfo->GetEpisode());
162  lookup->SetInetref(pginfo->GetInetRef());
163 
164  if (m_lookupthread->isRunning())
165  m_lookupthread->prependLookup(lookup);
166  else
167  m_lookupthread->addLookup(lookup);
168 }
169 
170 void MetadataFactory::Lookup(VideoMetadata *metadata, bool automatic,
171  bool getimages, bool allowgeneric)
172 {
173  if (!metadata)
174  return;
175 
176  auto *lookup = new MetadataLookup();
177 
178  lookup->SetStep(kLookupSearch);
179  lookup->SetType(kMetadataVideo);
180  lookup->SetSubtype(GuessLookupType(metadata));
181  lookup->SetData(QVariant::fromValue(metadata));
182  lookup->SetAutomatic(automatic);
183  lookup->SetHandleImages(getimages);
184  lookup->SetAllowGeneric(allowgeneric);
185  lookup->SetHost(metadata->GetHost());
186  lookup->SetTitle(metadata->GetTitle());
187  lookup->SetSubtitle(metadata->GetSubtitle());
188  lookup->SetSeason(metadata->GetSeason());
189  lookup->SetEpisode(metadata->GetEpisode());
190  lookup->SetInetref(metadata->GetInetRef());
191  lookup->SetFilename(generate_file_url("Videos", metadata->GetHost(),
192  metadata->GetFilename()));
193 
194  if (m_lookupthread->isRunning())
195  m_lookupthread->prependLookup(lookup);
196  else
197  m_lookupthread->addLookup(lookup);
198 }
199 
201 {
202  if (!lookup)
203  return;
204 
205  if (m_lookupthread->isRunning())
206  m_lookupthread->prependLookup(lookup);
207  else
208  m_lookupthread->addLookup(lookup);
209 }
210 
212  const QString& subtitle,
213  const QString& inetref,
214  int season,
215  int episode,
216  const QString& grabber,
217  bool allowgeneric)
218 {
219  auto *lookup = new MetadataLookup();
220 
221  lookup->SetStep(kLookupSearch);
222  lookup->SetType(kMetadataRecording);
223  lookup->SetAutomatic(false);
224  lookup->SetHandleImages(false);
225  lookup->SetAllowGeneric(allowgeneric);
226  lookup->SetTitle(title);
227  lookup->SetSubtitle(subtitle);
228  lookup->SetSeason(season);
229  lookup->SetEpisode(episode);
230  lookup->SetInetref(inetref);
231  if (grabber.toLower() == "movie")
232  lookup->SetSubtype(kProbableMovie);
233  else if (grabber.toLower() == "tv" ||
234  grabber.toLower() == "television")
235  lookup->SetSubtype(kProbableTelevision);
236  else
237  lookup->SetSubtype(GuessLookupType(lookup));
238 
239  return SynchronousLookup(lookup);
240 }
241 
243 {
244  if (!lookup)
245  return MetadataLookupList();
246 
247  m_sync = true;
248 
249  if (m_lookupthread->isRunning())
250  m_lookupthread->prependLookup(lookup);
251  else
252  m_lookupthread->addLookup(lookup);
253 
254  while (m_returnList.isEmpty() && m_sync)
255  {
256  sleep(1);
257  QCoreApplication::processEvents();
258  }
259 
260  m_sync = false;
261 
262  return m_returnList;
263 }
264 
266 {
269 }
270 
272 {
273  if (IsRunning())
274  return;
275 
276  QStringList hosts;
277  if (!RemoteGetActiveBackends(&hosts))
278  {
279  LOG(VB_GENERAL, LOG_WARNING, "Could not retrieve list of "
280  "available backends.");
281  return;
282  }
283 
284  VideoScan(hosts);
285 }
286 
287 void MetadataFactory::VideoScan(const QStringList& hosts)
288 {
289  if (IsRunning())
290  return;
291 
292  m_scanning = true;
293 
294  m_videoscanner->SetHosts(hosts);
297 }
298 
300 {
301  if (list.isEmpty())
302  return;
303 
304  if (parent())
305  QCoreApplication::postEvent(parent(),
306  new MetadataFactoryMultiResult(list));
307 }
308 
310 {
311  if (!lookup)
312  return;
313 
314  if (lookup->GetHandleImages())
315  {
316  DownloadMap map;
317 
318  ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
319  if (!coverartlist.empty())
320  {
321  ArtworkInfo info;
322  info.url = coverartlist.takeFirst().url;
323  map.insert(kArtworkCoverart, info);
324  }
325 
326  ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
327  if (!fanartlist.empty())
328  {
329  ArtworkInfo info;
330  int index = 0;
331  int season = lookup->GetIsCollection() ? 0 : (int)lookup->GetSeason();
332  if (season > 0 && season <= fanartlist.count())
333  index = season - 1;
334  info.url = fanartlist.takeAt(index).url;
335  map.insert(kArtworkFanart, info);
336  }
337 
338  ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner);
339  if (!bannerlist.empty())
340  {
341  ArtworkInfo info;
342  info.url = bannerlist.takeFirst().url;
343  map.insert(kArtworkBanner, info);
344  }
345 
346  if (lookup->GetType() != kMetadataRecording)
347  {
348  ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
349  if (!screenshotlist.empty())
350  {
351  ArtworkInfo info;
352  info.url = screenshotlist.takeFirst().url;
353  map.insert(kArtworkScreenshot, info);
354  }
355  }
356  lookup->SetDownloads(map);
357  lookup->IncrRef();
358  m_imagedownload->addDownloads(lookup);
359  }
360  else
361  {
362  if (m_scanning)
363  OnVideoResult(lookup);
364  else if (parent())
365  QCoreApplication::postEvent(parent(),
366  new MetadataFactorySingleResult(lookup));
367  }
368 }
369 
371 {
372  if (!lookup)
373  return;
374 
375  if (parent())
376  QCoreApplication::postEvent(parent(),
377  new MetadataFactoryNoResult(lookup));
378 }
379 
381 {
382  if (!lookup)
383  return;
384 
385  if (parent())
386  QCoreApplication::postEvent(parent(),
387  new MetadataFactorySingleResult(lookup));
388 }
389 
391 {
392  if (!lookup)
393  return;
394 
395  auto *metadata = lookup->GetData().value<VideoMetadata *>();
396 
397  if (!metadata)
398  return;
399 
400  metadata->SetTitle(lookup->GetTitle());
401  metadata->SetSubtitle(lookup->GetSubtitle());
402 
403  if (metadata->GetTagline().isEmpty())
404  metadata->SetTagline(lookup->GetTagline());
405  if (metadata->GetYear() == VIDEO_YEAR_DEFAULT || metadata->GetYear() == 0)
406  metadata->SetYear(lookup->GetYear());
407  if (metadata->GetReleaseDate() == QDate())
408  metadata->SetReleaseDate(lookup->GetReleaseDate());
409  if (metadata->GetDirector() == VIDEO_DIRECTOR_UNKNOWN ||
410  metadata->GetDirector().isEmpty())
411  {
412  QList<PersonInfo> director = lookup->GetPeople(kPersonDirector);
413  if (director.count() > 0)
414  metadata->SetDirector(director.takeFirst().name);
415  }
416  if (metadata->GetStudio().isEmpty())
417  {
418  QStringList studios = lookup->GetStudios();
419  if (studios.count() > 0)
420  metadata->SetStudio(studios.takeFirst());
421  }
422  if (metadata->GetPlot() == VIDEO_PLOT_DEFAULT ||
423  metadata->GetPlot().isEmpty())
424  metadata->SetPlot(lookup->GetDescription());
425  if (metadata->GetUserRating() == 0)
426  metadata->SetUserRating(lookup->GetUserRating());
427  if (metadata->GetRating() == VIDEO_RATING_DEFAULT)
428  metadata->SetRating(lookup->GetCertification());
429  if (metadata->GetLength() == 0)
430  metadata->SetLength(lookup->GetRuntime());
431  if (metadata->GetSeason() == 0)
432  metadata->SetSeason(lookup->GetSeason());
433  if (metadata->GetEpisode() == 0)
434  metadata->SetEpisode(lookup->GetEpisode());
435  if (metadata->GetHomepage().isEmpty())
436  metadata->SetHomepage(lookup->GetHomepage());
437 
438  metadata->SetInetRef(lookup->GetInetref());
439 
440 // m_d->AutomaticParentalAdjustment(metadata);
441 
442  // Cast
443  QList<PersonInfo> actors = lookup->GetPeople(kPersonActor);
444  QList<PersonInfo> gueststars = lookup->GetPeople(kPersonGuestStar);
445 
446  for (QList<PersonInfo>::const_iterator p = gueststars.begin();
447  p != gueststars.end(); ++p)
448  {
449  actors.append(*p);
450  }
451 
453  QStringList cl;
454 
455  for (QList<PersonInfo>::const_iterator p = actors.begin();
456  p != actors.end(); ++p)
457  {
458  cl.append((*p).name);
459  }
460 
461  for (QStringList::const_iterator p = cl.begin();
462  p != cl.end(); ++p)
463  {
464  QString cn = (*p).trimmed();
465  if (cn.length())
466  {
467  cast.push_back(VideoMetadata::cast_list::
468  value_type(-1, cn));
469  }
470  }
471 
472  metadata->SetCast(cast);
473 
474  // Genres
475  VideoMetadata::genre_list video_genres;
476  QStringList genres = lookup->GetCategories();
477 
478  for (QStringList::const_iterator p = genres.begin();
479  p != genres.end(); ++p)
480  {
481  QString genre_name = (*p).trimmed();
482  if (genre_name.length())
483  {
484  video_genres.push_back(
485  VideoMetadata::genre_list::value_type(-1, genre_name));
486  }
487  }
488 
489  metadata->SetGenres(video_genres);
490 
491  // Countries
492  VideoMetadata::country_list video_countries;
493  QStringList countries = lookup->GetCountries();
494 
495  for (QStringList::const_iterator p = countries.begin();
496  p != countries.end(); ++p)
497  {
498  QString country_name = (*p).trimmed();
499  if (country_name.length())
500  {
501  video_countries.push_back(
502  VideoMetadata::country_list::value_type(-1,
503  country_name));
504  }
505  }
506 
507  metadata->SetCountries(video_countries);
508 
509  ArtworkMap map = lookup->GetDownloads();
510 
511  QUrl coverurl(map.value(kArtworkCoverart).url);
512  if (!coverurl.path().isEmpty())
513  metadata->SetCoverFile(coverurl.path().remove(0,1));
514 
515  QUrl fanarturl(map.value(kArtworkFanart).url);
516  if (!fanarturl.path().isEmpty())
517  metadata->SetFanart(fanarturl.path().remove(0,1));
518 
519  QUrl bannerurl(map.value(kArtworkBanner).url);
520  if (!bannerurl.path().isEmpty())
521  metadata->SetBanner(bannerurl.path().remove(0,1));
522 
523  QUrl sshoturl(map.value(kArtworkScreenshot).url);
524  if (!sshoturl.path().isEmpty())
525  metadata->SetScreenshot(sshoturl.path().remove(0,1));
526 
527  metadata->SetProcessed(true);
528  metadata->UpdateDatabase();
529 
530  if (gCoreContext->HasGUI() && parent())
531  {
532  QCoreApplication::postEvent(parent(),
533  new MetadataFactorySingleResult(lookup));
534  }
535 }
536 
537 void MetadataFactory::customEvent(QEvent *levent)
538 {
539  if (levent->type() == MetadataLookupEvent::kEventType)
540  {
541  auto *lue = dynamic_cast<MetadataLookupEvent *>(levent);
542  if (lue == nullptr)
543  return;
544 
545  MetadataLookupList lul = lue->m_lookupList;
546  if (lul.isEmpty())
547  return;
548 
549  if (m_sync)
550  {
551  m_returnList = lul;
552  }
553  else if (lul.count() == 1)
554  {
555  OnSingleResult(lul[0]);
556  }
557  else
558  {
559  OnMultiResult(lul);
560  }
561  }
562  else if (levent->type() == MetadataLookupFailure::kEventType)
563  {
564  auto *luf = dynamic_cast<MetadataLookupFailure *>(levent);
565  if (luf == nullptr)
566  return;
567 
568  MetadataLookupList lul = luf->m_lookupList;
569  if (lul.isEmpty())
570  return;
571 
572  if (m_sync)
573  {
575  m_sync = false;
576  }
577  if (!lul.empty())
578  {
579  OnNoResult(lul[0]);
580  }
581  }
582  else if (levent->type() == ImageDLEvent::kEventType)
583  {
584  auto *ide = dynamic_cast<ImageDLEvent *>(levent);
585  if (ide == nullptr)
586  return;
587 
588  MetadataLookup *lookup = ide->m_item;
589  if (!lookup)
590  return;
591 
592  if (m_scanning)
593  OnVideoResult(lookup);
594  else
595  OnImageResult(lookup);
596  }
597  else if (levent->type() == ImageDLFailureEvent::kEventType)
598  {
599  auto *ide = dynamic_cast<ImageDLFailureEvent *>(levent);
600  if (ide == nullptr)
601  return;
602 
603  MetadataLookup *lookup = ide->m_item;
604  if (!lookup)
605  return;
606 
607  // propagate event on image download failure
608  if (parent())
609  QCoreApplication::postEvent(parent(),
610  new ImageDLFailureEvent(lookup));
611  }
612  else if (levent->type() == VideoScanChanges::kEventType)
613  {
614  auto *vsc = dynamic_cast<VideoScanChanges *>(levent);
615  if (!vsc)
616  return;
617 
618  QList<int> additions = vsc->m_additions;
619  QList<int> moves = vsc->m_moved;
620  QList<int> deletions = vsc->m_deleted;
621 
622  if (!m_scanning)
623  {
624  LOG(VB_GENERAL, LOG_INFO,
625  QString("Video Scan Complete: a(%1) m(%2) d(%3)")
626  .arg(additions.count()).arg(moves.count())
627  .arg(deletions.count()));
628 
629  if (parent())
630  {
631  QCoreApplication::postEvent(parent(),
632  new MetadataFactoryVideoChanges(additions, moves,
633  deletions));
634  }
635  }
636  else
637  {
638  LOG(VB_GENERAL, LOG_INFO,
639  QString("Video Scan Complete: a(%1) m(%2) d(%3)")
640  .arg(additions.count()).arg(moves.count())
641  .arg(deletions.count()));
642 
645  m_mlm->setList(ml);
646 
647  for (QList<int>::const_iterator it = additions.begin();
648  it != additions.end(); ++it)
649  {
650  VideoMetadata *metadata = m_mlm->byID(*it).get();
651 
652  if (metadata)
653  Lookup(metadata, true, true);
654  }
655  }
657  }
658 }
659 
660 // These functions exist to determine if we have enough
661 // information to conclusively call something a Show vs. Movie
662 
664 {
665  LookupType ret = GuessLookupType(pginfo->GetInetRef());
666 
667  if (ret != kUnknownVideo)
668  return ret;
669 
670  ProgramInfo::CategoryType catType = pginfo->GetCategoryType();
671  if (catType == ProgramInfo::kCategoryNone)
672  catType = pginfo->QueryCategoryType();
673 
674  if ((!pginfo->GetSubtitle().isEmpty() || pginfo->GetEpisode() > 0) &&
675  (catType == ProgramInfo::kCategorySeries ||
676  catType == ProgramInfo::kCategoryTVShow))
677  ret = kProbableTelevision; // NOLINT(bugprone-branch-clone)
678  else if (catType == ProgramInfo::kCategoryMovie)
679  ret = kProbableMovie;
680  else if (pginfo->GetSeason() > 0 || pginfo->GetEpisode() > 0 ||
681  !pginfo->GetSubtitle().isEmpty())
682  ret = kProbableTelevision;
683  else
684  {
685  // Before committing to something being a movie, we
686  // want to check its rule. If the rule has a season
687  // or episode number, but the recording doesn't,
688  // and the rec doesn't have a subtitle, this is a
689  // generic recording. If neither the rule nor the
690  // recording have an inetref, season, episode, or
691  // subtitle, it's *probably* a movie. If it's some
692  // weird combination of both, we've got to try everything.
693  auto *rule = new RecordingRule();
694  rule->m_recordID = pginfo->GetRecordingRuleID();
695  rule->Load();
696  int ruleepisode = rule->m_episode;
697  delete rule;
698 
699  if (ruleepisode == 0 && pginfo->GetEpisode() == 0 &&
700  pginfo->GetSubtitle().isEmpty())
701  ret = kProbableMovie;
702  else if (ruleepisode > 0 && pginfo->GetSubtitle().isEmpty())
704  else
705  ret = kUnknownVideo;
706  }
707 
708  return ret;
709 }
710 
712 {
713  LookupType ret = GuessLookupType(lookup->GetInetref());
714 
715  if (ret != kUnknownVideo)
716  return ret;
717 
718  if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0 ||
719  !lookup->GetSubtitle().isEmpty())
720  ret = kProbableTelevision;
721  else
722  ret = kProbableMovie;
723 
724  return ret;
725 }
726 
728 {
729  LookupType ret = GuessLookupType(metadata->GetInetRef());
730 
731  if (ret != kUnknownVideo)
732  return ret;
733 
734  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0 ||
735  !metadata->GetSubtitle().isEmpty())
736  ret = kProbableTelevision;
737  else
738  ret = kProbableMovie;
739 
740  return ret;
741 }
742 
744 {
745  LookupType ret = GuessLookupType(recrule->m_inetref);
746 
747  if (ret != kUnknownVideo)
748  return ret;
749 
750  if (recrule->m_season > 0 || recrule->m_episode > 0 ||
751  !recrule->m_subtitle.isEmpty())
752  ret = kProbableTelevision;
753  else
754  ret = kProbableMovie;
755 
756  return ret;
757 }
758 
759 LookupType GuessLookupType(const QString &inetref)
760 {
761  if (inetref.isEmpty() || inetref == "00000000" ||
762  inetref == MetaGrabberScript::CleanedInetref(inetref))
763  {
764  // can't determine subtype from inetref
765  return kUnknownVideo;
766  }
767 
768  // inetref is defined, see if we have a pre-defined grabber
769  MetaGrabberScript grabber =
771 
772  if (!grabber.IsValid())
773  {
774  return kUnknownVideo;
775  }
776 
777  switch (grabber.GetType())
778  {
779  case kGrabberMovie:
780  return kProbableMovie;
781  case kGrabberTelevision:
782  return kProbableTelevision;
783  default:
784  return kUnknownVideo;
785  }
786 }
QString m_subtitle
Definition: recordingrule.h:81
RefCountedList< MetadataLookup > MetadataLookupList
QStringList GetCategories() const
~MetadataFactory() override
ArtworkList GetArtwork(VideoArtworkType type) const
QStringList GetVideoDirs()
Definition: videoutils.cpp:120
static bool MovieGrabberWorks()
MetadataLookupList SynchronousLookup(const QString &title, const QString &subtitle, const QString &inetref, int season, int episode, const QString &grabber, bool allowgeneric=false)
int GetSeason() const
static void loadAllFromDatabase(metadata_list &items, const QString &sql="")
Load videometadata database into memory.
static QString CleanedInetref(const QString &inetref)
uint GetYear() const
bool HasGUI(void) const
std::vector< country_entry > country_list
Definition: videometadata.h:33
bool GetIsCollection() const
QString GetDescription() const
LookupType GuessLookupType(ProgramInfo *pginfo)
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:311
MetadataFactory(QObject *parent)
void SetHosts(const QStringList &hosts)
Definition: videoscan.cpp:98
QString GetTitle(void) const
Definition: programinfo.h:355
void OnSingleResult(MetadataLookup *lookup)
VideoMetadataListManager * m_mlm
std::vector< cast_entry > cast_list
Definition: videometadata.h:34
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void OnNoResult(MetadataLookup *lookup)
QList< PersonInfo > GetPeople(PeopleType type) const
CategoryType QueryCategoryType(void) const
Queries recordedprogram to get the category_type of the recording.
static MetaGrabberScript GetType(const QString &type)
void prependLookup(MetadataLookup *lookup)
prependLookup: Add lookup to top of the queue MetadataDownload::m_lookupList takes ownership of the g...
static bool VideoGrabbersFunctional()
QList< ArtworkInfo > ArtworkList
unsigned sleep(unsigned int x)
Definition: compat.h:159
QString GetInetRef(void) const
Definition: programinfo.h:431
QString GetSubtitle() const
void SetDirs(QStringList dirs)
Definition: videoscan.cpp:105
QStringList GetStudios() const
MetadataType GetType() const
float GetUserRating() const
uint GetSeason() const
QString GetTitle() const
uint GetEpisode() const
bool IsValid(void) const
Holds information on recordings and videos.
Definition: programinfo.h:67
bool RemoteGetActiveBackends(QStringList *list)
return list of backends currently connected to the master
Definition: remoteutil.cpp:577
QString GetTagline() const
void setList(metadata_list &list)
virtual int IncrRef(void)
Increments reference count.
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
#define META_PUBLIC
Definition: mythmetaexp.h:9
int GetEpisode() const
MetadataDownload * m_lookupthread
QStringList GetCountries() const
void addDownloads(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_downloadList takes ownership of the ...
void ResetCounts()
Definition: videoscan.h:75
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
bool isRunning(void) const
Definition: mthread.cpp:274
QString GetSubtitle(void) const
Definition: programinfo.h:357
void OnImageResult(MetadataLookup *lookup)
QString GetMasterHostName(void)
uint GetSeason(void) const
Definition: programinfo.h:360
std::vector< genre_entry > genre_list
Definition: videometadata.h:32
Internal representation of a recording rule, mirrors the record table.
Definition: recordingrule.h:32
void SetDownloads(ArtworkMap map)
QString GetInetref() const
void OnVideoResult(MetadataLookup *lookup)
const QString & GetHost() const
QVariant GetData() const
void customEvent(QEvent *levent) override
QString m_inetref
Definition: recordingrule.h:89
void SetTitle(const QString &title, const QString &sortTitle="")
QDate GetReleaseDate() const
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
const QString & GetFilename() const
MetadataLookupList m_returnList
const QString VIDEO_DIRECTOR_UNKNOWN
Definition: globals.cpp:9
static Type kEventType
QString m_title
Definition: recordingrule.h:79
void Lookup(ProgramInfo *pginfo, bool automatic=true, bool getimages=true, bool allowgeneric=false)
QString GetHomepage() const
uint GetRecordingRuleID(void) const
Definition: programinfo.h:443
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:294
VideoMetadataPtr byID(unsigned int db_id) const
bool GetHandleImages() const
uint GetRuntime() const
QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
Definition: videoutils.h:65
T * get() const
Definition: quicksp.h:73
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
DownloadMap GetDownloads() const
const QString & GetSubtitle() const
void OnMultiResult(const MetadataLookupList &list)
MetadataImageDownload * m_imagedownload
QMultiMap< VideoArtworkType, ArtworkInfo > ArtworkMap
static Type kEventType
Definition: videoscan.h:57
const QString & GetInetRef() const
const QString & GetTitle() const
void addLookup(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_lookupList takes ownership of the gi...
MetadataLookup * m_result
static bool TelevisionGrabberWorks()
LookupType
static MetaGrabberScript FromInetref(const QString &inetref, bool absolute=false)
CategoryType GetCategoryType(void) const
Definition: programinfo.h:432
VideoScannerThread * m_videoscanner
QString GetCertification() const
uint GetEpisode(void) const
Definition: programinfo.h:361
std::list< VideoMetadataPtr > metadata_list
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23