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 
67 {
68 }
69 
71  (QEvent::Type) QEvent::registerEventType();
72 
74 {
75 }
76 
78  QObject(parent)
79 {
80  m_lookupthread = new MetadataDownload(this);
83 
85 }
86 
88 {
89  if (m_lookupthread)
90  {
92  delete m_lookupthread;
93  m_lookupthread = nullptr;
94  }
95 
96  if (m_imagedownload)
97  {
99  delete m_imagedownload;
100  m_imagedownload = nullptr;
101  }
102 
104  delete m_videoscanner;
105 
106  delete m_mlm;
107  m_mlm = nullptr;
108 }
109 
110 void MetadataFactory::Lookup(RecordingRule *recrule, bool automatic,
111  bool getimages, bool allowgeneric)
112 {
113  if (!recrule)
114  return;
115 
116  auto *lookup = new MetadataLookup();
117 
118  lookup->SetStep(kLookupSearch);
119  lookup->SetType(kMetadataRecording);
120  lookup->SetSubtype(GuessLookupType(recrule));
121  lookup->SetData(QVariant::fromValue(recrule));
122  lookup->SetAutomatic(automatic);
123  lookup->SetHandleImages(getimages);
124  lookup->SetAllowGeneric(allowgeneric);
125  lookup->SetHost(gCoreContext->GetMasterHostName());
126  lookup->SetTitle(recrule->m_title);
127  lookup->SetSubtitle(recrule->m_subtitle);
128  lookup->SetInetref(recrule->m_inetref);
129  lookup->SetSeason(recrule->m_season);
130  lookup->SetEpisode(recrule->m_episode);
131 
132  if (m_lookupthread->isRunning())
133  m_lookupthread->prependLookup(lookup);
134  else
135  m_lookupthread->addLookup(lookup);
136 }
137 
138 void MetadataFactory::Lookup(ProgramInfo *pginfo, bool automatic,
139  bool getimages, bool allowgeneric)
140 {
141  if (!pginfo)
142  return;
143 
144  auto *lookup = new MetadataLookup();
145 
146  lookup->SetStep(kLookupSearch);
147  lookup->SetType(kMetadataRecording);
148  lookup->SetSubtype(GuessLookupType(pginfo));
149  lookup->SetData(QVariant::fromValue(pginfo));
150  lookup->SetAutomatic(automatic);
151  lookup->SetHandleImages(getimages);
152  lookup->SetAllowGeneric(allowgeneric);
153  lookup->SetHost(gCoreContext->GetMasterHostName());
154  lookup->SetTitle(pginfo->GetTitle());
155  lookup->SetSubtitle(pginfo->GetSubtitle());
156  lookup->SetSeason(pginfo->GetSeason());
157  lookup->SetEpisode(pginfo->GetEpisode());
158  lookup->SetInetref(pginfo->GetInetRef());
159 
160  if (m_lookupthread->isRunning())
161  m_lookupthread->prependLookup(lookup);
162  else
163  m_lookupthread->addLookup(lookup);
164 }
165 
166 void MetadataFactory::Lookup(VideoMetadata *metadata, bool automatic,
167  bool getimages, bool allowgeneric)
168 {
169  if (!metadata)
170  return;
171 
172  auto *lookup = new MetadataLookup();
173 
174  lookup->SetStep(kLookupSearch);
175  lookup->SetType(kMetadataVideo);
176  lookup->SetSubtype(GuessLookupType(metadata));
177  lookup->SetData(QVariant::fromValue(metadata));
178  lookup->SetAutomatic(automatic);
179  lookup->SetHandleImages(getimages);
180  lookup->SetAllowGeneric(allowgeneric);
181  lookup->SetHost(metadata->GetHost());
182  lookup->SetTitle(metadata->GetTitle());
183  lookup->SetSubtitle(metadata->GetSubtitle());
184  lookup->SetSeason(metadata->GetSeason());
185  lookup->SetEpisode(metadata->GetEpisode());
186  lookup->SetInetref(metadata->GetInetRef());
187  lookup->SetFilename(generate_file_url("Videos", metadata->GetHost(),
188  metadata->GetFilename()));
189 
190  if (m_lookupthread->isRunning())
191  m_lookupthread->prependLookup(lookup);
192  else
193  m_lookupthread->addLookup(lookup);
194 }
195 
197 {
198  if (!lookup)
199  return;
200 
201  if (m_lookupthread->isRunning())
202  m_lookupthread->prependLookup(lookup);
203  else
204  m_lookupthread->addLookup(lookup);
205 }
206 
208  const QString& subtitle,
209  const QString& inetref,
210  int season,
211  int episode,
212  const QString& grabber,
213  bool allowgeneric)
214 {
215  auto *lookup = new MetadataLookup();
216 
217  lookup->SetStep(kLookupSearch);
218  lookup->SetType(kMetadataRecording);
219  lookup->SetAutomatic(false);
220  lookup->SetHandleImages(false);
221  lookup->SetAllowGeneric(allowgeneric);
222  lookup->SetTitle(title);
223  lookup->SetSubtitle(subtitle);
224  lookup->SetSeason(season);
225  lookup->SetEpisode(episode);
226  lookup->SetInetref(inetref);
227  if (grabber.toLower() == "movie")
228  lookup->SetSubtype(kProbableMovie);
229  else if (grabber.toLower() == "tv" ||
230  grabber.toLower() == "television")
231  lookup->SetSubtype(kProbableTelevision);
232  else
233  lookup->SetSubtype(GuessLookupType(lookup));
234 
235  return SynchronousLookup(lookup);
236 }
237 
239 {
240  if (!lookup)
241  return MetadataLookupList();
242 
243  m_sync = true;
244 
245  if (m_lookupthread->isRunning())
246  m_lookupthread->prependLookup(lookup);
247  else
248  m_lookupthread->addLookup(lookup);
249 
250  while (m_returnList.isEmpty() && m_sync)
251  {
252  sleep(1);
253  qApp->processEvents();
254  }
255 
256  m_sync = false;
257 
258  return m_returnList;
259 }
260 
262 {
265 }
266 
268 {
269  if (IsRunning())
270  return;
271 
272  QStringList hosts;
273  if (!RemoteGetActiveBackends(&hosts))
274  {
275  LOG(VB_GENERAL, LOG_WARNING, "Could not retrieve list of "
276  "available backends.");
277  return;
278  }
279 
280  VideoScan(hosts);
281 }
282 
283 void MetadataFactory::VideoScan(const QStringList& hosts)
284 {
285  if (IsRunning())
286  return;
287 
288  m_scanning = true;
289 
290  m_videoscanner->SetHosts(hosts);
293 }
294 
296 {
297  if (list.isEmpty())
298  return;
299 
300  if (parent())
301  QCoreApplication::postEvent(parent(),
302  new MetadataFactoryMultiResult(list));
303 }
304 
306 {
307  if (!lookup)
308  return;
309 
310  if (lookup->GetHandleImages())
311  {
312  DownloadMap map;
313 
314  ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
315  if (!coverartlist.empty())
316  {
317  ArtworkInfo info;
318  info.url = coverartlist.takeFirst().url;
319  map.insert(kArtworkCoverart, info);
320  }
321 
322  ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
323  if (!fanartlist.empty())
324  {
325  ArtworkInfo info;
326  int index = 0;
327  int season = lookup->GetIsCollection() ? 0 : (int)lookup->GetSeason();
328  if (season > 0 && season <= fanartlist.count())
329  index = season - 1;
330  info.url = fanartlist.takeAt(index).url;
331  map.insert(kArtworkFanart, info);
332  }
333 
334  ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner);
335  if (!bannerlist.empty())
336  {
337  ArtworkInfo info;
338  info.url = bannerlist.takeFirst().url;
339  map.insert(kArtworkBanner, info);
340  }
341 
342  if (lookup->GetType() != kMetadataRecording)
343  {
344  ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
345  if (!screenshotlist.empty())
346  {
347  ArtworkInfo info;
348  info.url = screenshotlist.takeFirst().url;
349  map.insert(kArtworkScreenshot, info);
350  }
351  }
352  lookup->SetDownloads(map);
353  lookup->IncrRef();
354  m_imagedownload->addDownloads(lookup);
355  }
356  else
357  {
358  if (m_scanning)
359  OnVideoResult(lookup);
360  else if (parent())
361  QCoreApplication::postEvent(parent(),
362  new MetadataFactorySingleResult(lookup));
363  }
364 }
365 
367 {
368  if (!lookup)
369  return;
370 
371  if (parent())
372  QCoreApplication::postEvent(parent(),
373  new MetadataFactoryNoResult(lookup));
374 }
375 
377 {
378  if (!lookup)
379  return;
380 
381  if (parent())
382  QCoreApplication::postEvent(parent(),
383  new MetadataFactorySingleResult(lookup));
384 }
385 
387 {
388  if (!lookup)
389  return;
390 
391  auto *metadata = lookup->GetData().value<VideoMetadata *>();
392 
393  if (!metadata)
394  return;
395 
396  metadata->SetTitle(lookup->GetTitle());
397  metadata->SetSubtitle(lookup->GetSubtitle());
398 
399  if (metadata->GetTagline().isEmpty())
400  metadata->SetTagline(lookup->GetTagline());
401  if (metadata->GetYear() == VIDEO_YEAR_DEFAULT || metadata->GetYear() == 0)
402  metadata->SetYear(lookup->GetYear());
403  if (metadata->GetReleaseDate() == QDate())
404  metadata->SetReleaseDate(lookup->GetReleaseDate());
405  if (metadata->GetDirector() == VIDEO_DIRECTOR_UNKNOWN ||
406  metadata->GetDirector().isEmpty())
407  {
408  QList<PersonInfo> director = lookup->GetPeople(kPersonDirector);
409  if (director.count() > 0)
410  metadata->SetDirector(director.takeFirst().name);
411  }
412  if (metadata->GetStudio().isEmpty())
413  {
414  QStringList studios = lookup->GetStudios();
415  if (studios.count() > 0)
416  metadata->SetStudio(studios.takeFirst());
417  }
418  if (metadata->GetPlot() == VIDEO_PLOT_DEFAULT ||
419  metadata->GetPlot().isEmpty())
420  metadata->SetPlot(lookup->GetDescription());
421  if (metadata->GetUserRating() == 0)
422  metadata->SetUserRating(lookup->GetUserRating());
423  if (metadata->GetRating() == VIDEO_RATING_DEFAULT)
424  metadata->SetRating(lookup->GetCertification());
425  if (metadata->GetLength() == 0)
426  metadata->SetLength(lookup->GetRuntime());
427  if (metadata->GetSeason() == 0)
428  metadata->SetSeason(lookup->GetSeason());
429  if (metadata->GetEpisode() == 0)
430  metadata->SetEpisode(lookup->GetEpisode());
431  if (metadata->GetHomepage().isEmpty())
432  metadata->SetHomepage(lookup->GetHomepage());
433 
434  metadata->SetInetRef(lookup->GetInetref());
435 
436 // m_d->AutomaticParentalAdjustment(metadata);
437 
438  // Cast
439  QList<PersonInfo> actors = lookup->GetPeople(kPersonActor);
440  QList<PersonInfo> gueststars = lookup->GetPeople(kPersonGuestStar);
441 
442  for (QList<PersonInfo>::const_iterator p = gueststars.begin();
443  p != gueststars.end(); ++p)
444  {
445  actors.append(*p);
446  }
447 
449  QStringList cl;
450 
451  for (QList<PersonInfo>::const_iterator p = actors.begin();
452  p != actors.end(); ++p)
453  {
454  cl.append((*p).name);
455  }
456 
457  for (QStringList::const_iterator p = cl.begin();
458  p != cl.end(); ++p)
459  {
460  QString cn = (*p).trimmed();
461  if (cn.length())
462  {
463  cast.push_back(VideoMetadata::cast_list::
464  value_type(-1, cn));
465  }
466  }
467 
468  metadata->SetCast(cast);
469 
470  // Genres
471  VideoMetadata::genre_list video_genres;
472  QStringList genres = lookup->GetCategories();
473 
474  for (QStringList::const_iterator p = genres.begin();
475  p != genres.end(); ++p)
476  {
477  QString genre_name = (*p).trimmed();
478  if (genre_name.length())
479  {
480  video_genres.push_back(
481  VideoMetadata::genre_list::value_type(-1, genre_name));
482  }
483  }
484 
485  metadata->SetGenres(video_genres);
486 
487  // Countries
488  VideoMetadata::country_list video_countries;
489  QStringList countries = lookup->GetCountries();
490 
491  for (QStringList::const_iterator p = countries.begin();
492  p != countries.end(); ++p)
493  {
494  QString country_name = (*p).trimmed();
495  if (country_name.length())
496  {
497  video_countries.push_back(
498  VideoMetadata::country_list::value_type(-1,
499  country_name));
500  }
501  }
502 
503  metadata->SetCountries(video_countries);
504 
505  ArtworkMap map = lookup->GetDownloads();
506 
507  QUrl coverurl(map.value(kArtworkCoverart).url);
508  if (!coverurl.path().isEmpty())
509  metadata->SetCoverFile(coverurl.path().remove(0,1));
510 
511  QUrl fanarturl(map.value(kArtworkFanart).url);
512  if (!fanarturl.path().isEmpty())
513  metadata->SetFanart(fanarturl.path().remove(0,1));
514 
515  QUrl bannerurl(map.value(kArtworkBanner).url);
516  if (!bannerurl.path().isEmpty())
517  metadata->SetBanner(bannerurl.path().remove(0,1));
518 
519  QUrl sshoturl(map.value(kArtworkScreenshot).url);
520  if (!sshoturl.path().isEmpty())
521  metadata->SetScreenshot(sshoturl.path().remove(0,1));
522 
523  metadata->SetProcessed(true);
524  metadata->UpdateDatabase();
525 
526  if (gCoreContext->HasGUI() && parent())
527  {
528  QCoreApplication::postEvent(parent(),
529  new MetadataFactorySingleResult(lookup));
530  }
531 }
532 
533 void MetadataFactory::customEvent(QEvent *levent)
534 {
535  if (levent->type() == MetadataLookupEvent::kEventType)
536  {
537  auto *lue = dynamic_cast<MetadataLookupEvent *>(levent);
538  if (lue == nullptr)
539  return;
540 
541  MetadataLookupList lul = lue->m_lookupList;
542  if (lul.isEmpty())
543  return;
544 
545  if (m_sync)
546  {
547  m_returnList = lul;
548  }
549  else if (lul.count() == 1)
550  {
551  OnSingleResult(lul[0]);
552  }
553  else
554  {
555  OnMultiResult(lul);
556  }
557  }
558  else if (levent->type() == MetadataLookupFailure::kEventType)
559  {
560  auto *luf = dynamic_cast<MetadataLookupFailure *>(levent);
561  if (luf == nullptr)
562  return;
563 
564  MetadataLookupList lul = luf->m_lookupList;
565  if (lul.isEmpty())
566  return;
567 
568  if (m_sync)
569  {
571  m_sync = false;
572  }
573  if (!lul.empty())
574  {
575  OnNoResult(lul[0]);
576  }
577  }
578  else if (levent->type() == ImageDLEvent::kEventType)
579  {
580  auto *ide = dynamic_cast<ImageDLEvent *>(levent);
581  if (ide == nullptr)
582  return;
583 
584  MetadataLookup *lookup = ide->m_item;
585  if (!lookup)
586  return;
587 
588  if (m_scanning)
589  OnVideoResult(lookup);
590  else
591  OnImageResult(lookup);
592  }
593  else if (levent->type() == ImageDLFailureEvent::kEventType)
594  {
595  auto *ide = dynamic_cast<ImageDLFailureEvent *>(levent);
596  if (ide == nullptr)
597  return;
598 
599  MetadataLookup *lookup = ide->m_item;
600  if (!lookup)
601  return;
602 
603  // propagate event on image download failure
604  if (parent())
605  QCoreApplication::postEvent(parent(),
606  new ImageDLFailureEvent(lookup));
607  }
608  else if (levent->type() == VideoScanChanges::kEventType)
609  {
610  auto *vsc = dynamic_cast<VideoScanChanges *>(levent);
611  if (!vsc)
612  return;
613 
614  QList<int> additions = vsc->m_additions;
615  QList<int> moves = vsc->m_moved;
616  QList<int> deletions = vsc->m_deleted;
617 
618  if (!m_scanning)
619  {
620  LOG(VB_GENERAL, LOG_INFO,
621  QString("Video Scan Complete: a(%1) m(%2) d(%3)")
622  .arg(additions.count()).arg(moves.count())
623  .arg(deletions.count()));
624 
625  if (parent())
626  {
627  QCoreApplication::postEvent(parent(),
628  new MetadataFactoryVideoChanges(additions, moves,
629  deletions));
630  }
631  }
632  else
633  {
634  LOG(VB_GENERAL, LOG_INFO,
635  QString("Video Scan Complete: a(%1) m(%2) d(%3)")
636  .arg(additions.count()).arg(moves.count())
637  .arg(deletions.count()));
638 
641  m_mlm->setList(ml);
642 
643  for (QList<int>::const_iterator it = additions.begin();
644  it != additions.end(); ++it)
645  {
646  VideoMetadata *metadata = m_mlm->byID(*it).get();
647 
648  if (metadata)
649  Lookup(metadata, true, true);
650  }
651  }
653  }
654 }
655 
656 // These functions exist to determine if we have enough
657 // information to conclusively call something a Show vs. Movie
658 
660 {
661  LookupType ret = GuessLookupType(pginfo->GetInetRef());
662 
663  if (ret != kUnknownVideo)
664  return ret;
665 
666  ProgramInfo::CategoryType catType = pginfo->GetCategoryType();
667  if (catType == ProgramInfo::kCategoryNone)
668  catType = pginfo->QueryCategoryType();
669 
670  if ((!pginfo->GetSubtitle().isEmpty() || pginfo->GetEpisode() > 0) &&
671  (catType == ProgramInfo::kCategorySeries ||
672  catType == ProgramInfo::kCategoryTVShow))
673  ret = kProbableTelevision; // NOLINT(bugprone-branch-clone)
674  else if (catType == ProgramInfo::kCategoryMovie)
675  ret = kProbableMovie;
676  else if (pginfo->GetSeason() > 0 || pginfo->GetEpisode() > 0 ||
677  !pginfo->GetSubtitle().isEmpty())
678  ret = kProbableTelevision;
679  else
680  {
681  // Before committing to something being a movie, we
682  // want to check its rule. If the rule has a season
683  // or episode number, but the recording doesn't,
684  // and the rec doesn't have a subtitle, this is a
685  // generic recording. If neither the rule nor the
686  // recording have an inetref, season, episode, or
687  // subtitle, it's *probably* a movie. If it's some
688  // weird combination of both, we've got to try everything.
689  auto *rule = new RecordingRule();
690  rule->m_recordID = pginfo->GetRecordingRuleID();
691  rule->Load();
692  int ruleepisode = rule->m_episode;
693  delete rule;
694 
695  if (ruleepisode == 0 && pginfo->GetEpisode() == 0 &&
696  pginfo->GetSubtitle().isEmpty())
697  ret = kProbableMovie;
698  else if (ruleepisode > 0 && pginfo->GetSubtitle().isEmpty())
700  else
701  ret = kUnknownVideo;
702  }
703 
704  return ret;
705 }
706 
708 {
709  LookupType ret = GuessLookupType(lookup->GetInetref());
710 
711  if (ret != kUnknownVideo)
712  return ret;
713 
714  if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0 ||
715  !lookup->GetSubtitle().isEmpty())
716  ret = kProbableTelevision;
717  else
718  ret = kProbableMovie;
719 
720  return ret;
721 }
722 
724 {
725  LookupType ret = GuessLookupType(metadata->GetInetRef());
726 
727  if (ret != kUnknownVideo)
728  return ret;
729 
730  if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0 ||
731  !metadata->GetSubtitle().isEmpty())
732  ret = kProbableTelevision;
733  else
734  ret = kProbableMovie;
735 
736  return ret;
737 }
738 
740 {
741  LookupType ret = GuessLookupType(recrule->m_inetref);
742 
743  if (ret != kUnknownVideo)
744  return ret;
745 
746  if (recrule->m_season > 0 || recrule->m_episode > 0 ||
747  !recrule->m_subtitle.isEmpty())
748  ret = kProbableTelevision;
749  else
750  ret = kProbableMovie;
751 
752  return ret;
753 }
754 
755 LookupType GuessLookupType(const QString &inetref)
756 {
757  if (inetref.isEmpty() || inetref == "00000000" ||
758  inetref == MetaGrabberScript::CleanedInetref(inetref))
759  {
760  // can't determine subtype from inetref
761  return kUnknownVideo;
762  }
763 
764  // inetref is defined, see if we have a pre-defined grabber
765  MetaGrabberScript grabber =
767 
768  if (!grabber.IsValid())
769  {
770  return kUnknownVideo;
771  }
772 
773  switch (grabber.GetType())
774  {
775  case kGrabberMovie:
776  return kProbableMovie;
777  case kGrabberTelevision:
778  return kProbableTelevision;
779  default:
780  return kUnknownVideo;
781  }
782 }
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:96
void SetTitle(const QString &title, const QString &sortTitle="")
QDate GetReleaseDate() const
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
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:65
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