Go to the documentation of this file.
5 #include <QCoreApplication>
24 (QEvent::Type) QEvent::registerEventType();
27 (QEvent::Type) QEvent::registerEventType();
106 else if (!nfo.isEmpty())
155 if (list.count() == 1 && list[0]->GetStep() ==
kLookupSearch)
172 if (list[0]->GetAutomatic() && list.count() > 1
197 if (qEnvironmentVariableIsSet(
"EXPERIMENTAL_METADATA_GRAB"))
215 QCoreApplication::postEvent(
m_parent,
220 LOG(VB_GENERAL, LOG_INFO,
221 QString(
"Returning Metadata Results: %1 %2 %3")
224 QCoreApplication::postEvent(
m_parent,
231 LOG(VB_GENERAL, LOG_INFO,
232 QString(
"Metadata Lookup Failed: No Results %1 %2 %3")
240 QCoreApplication::postEvent(
m_parent,
250 const QString &originaltitle,
253 unsigned int exactMatches = 0;
254 unsigned int exactMatchesWithArt = 0;
256 for (
const auto& lkup : std::as_const(list))
259 if ((QString::compare(lkup->GetTitle(), originaltitle, Qt::CaseInsensitive) == 0))
267 exactMatchesWithArt++;
274 return exactMatchesWithArt;
279 const QString &originaltitle)
283 QDate exactTitleDate;
284 float exactTitlePopularity = 0.0F;
285 int exactMatches = 0;
286 int exactMatchesWithArt = 0;
287 bool foundMatchWithArt =
false;
290 for (
const auto& lkup : std::as_const(list))
293 LOG(VB_GENERAL, LOG_INFO, QString(
"Comparing metadata title '%1' [%2] to recording title '%3'")
294 .arg(title, lkup->GetReleaseDate().toString(), originaltitle));
296 if (QString::compare(title, originaltitle, Qt::CaseInsensitive) == 0)
298 bool hasArtwork = ((!(lkup->GetArtwork(
kArtworkFanart)).empty()) ||
302 LOG(VB_GENERAL, LOG_INFO, QString(
"'%1', popularity = %2, ReleaseDate = %3")
304 .arg(lkup->GetPopularity())
305 .arg(lkup->GetReleaseDate().toString()));
313 if ((ret ==
nullptr) ||
315 ((!foundMatchWithArt) ||
316 ((lkup->GetPopularity() > exactTitlePopularity)) ||
317 ((exactTitlePopularity == 0.0F) && (lkup->GetReleaseDate() > exactTitleDate)))))
319 exactTitleDate = lkup->GetReleaseDate();
320 exactTitlePopularity = lkup->GetPopularity();
326 foundMatchWithArt =
true;
327 exactMatchesWithArt++;
331 titles.append(title);
334 LOG(VB_GENERAL, LOG_DEBUG, QString(
"exactMatches = %1, exactMatchesWithArt = %2")
336 .arg(exactMatchesWithArt));
340 if (exactMatches > 0)
342 if (exactMatches == 1)
344 LOG(VB_GENERAL, LOG_INFO, QString(
"Single exact title match for '%1'")
345 .arg(originaltitle));
349 LOG(VB_GENERAL, LOG_INFO,
350 QString(
"Multiple exact title matches found for '%1'. "
351 "Selecting most popular or most recent [%2]")
352 .arg(originaltitle, exactTitleDate.toString()));
358 QString bestTitle =
nearestName(originaltitle, titles);
361 if (bestTitle.isEmpty())
363 LOG(VB_GENERAL, LOG_ERR,
364 QString(
"No adequate match or multiple "
365 "matches found for %1. Update manually.")
366 .arg(originaltitle));
370 LOG(VB_GENERAL, LOG_INFO, QString(
"Best Title Match For %1: %2")
371 .arg(originaltitle, bestTitle));
374 for (
const auto& item : std::as_const(list))
376 if (item->GetTitle() == bestTitle)
393 LOG(VB_GENERAL, LOG_INFO, QString(
"Running Grabber: %1 %2")
394 .arg(cmd,
args.join(
" ")));
398 QByteArray result = grabber.
ReadAll();
399 if (!result.isEmpty())
402 doc.setContent(result,
true);
403 QDomElement root = doc.documentElement();
404 QDomElement item = root.firstChildElement(
"item");
406 while (!item.isNull())
412 item = item.nextSiblingElement(
"item");
442 LOG(VB_GENERAL, LOG_INFO,
443 QString(
"Movie grabber not functional. Aborting this run."));
454 LOG(VB_GENERAL, LOG_INFO,
455 QString(
"Television grabber not functional. Aborting this run."));
468 LOG(VB_GENERAL, LOG_INFO,
469 QString(
"Matching MXML file found. Parsing %1 for metadata...")
480 bool loaded = rf->SaveAs(mxmlraw);
484 if (doc.setContent(mxmlraw,
true))
487 QDomElement root = doc.documentElement();
488 item = root.firstChildElement(
"item");
492 LOG(VB_GENERAL, LOG_ERR,
493 QString(
"Corrupt or invalid MXML file."));
515 LOG(VB_GENERAL, LOG_INFO,
516 QString(
"Matching NFO file found. Parsing %1 for metadata...")
529 bool loaded = rf->SaveAs(nforaw);
535 if (doc.setContent(nforaw,
true))
538 item = doc.documentElement();
542 LOG(VB_GENERAL, LOG_ERR,
543 QString(
"Invalid NFO file found."));
659 bool searchcollection =
false;
673 if (list.isEmpty() && (!lookup->
GetSubtitle().isEmpty()))
683 searchcollection =
true;
685 else if (list.isEmpty())
691 searchcollection =
true;
719 if (!searchcollection && list.isEmpty() &&
732 for (
auto it = list.begin(); it != list.end(); ++it)
734 (*it)->SetIsCollection(searchcollection);
756 if (list.count() == 1)
787 if (origseason == 0 && origepisode == 0)
795 if (list.count() == 1)
815 QString ext = QFileInfo(qurl.path()).suffix();
820 newname =
filename +
"/" + QFileInfo(qurl.path()).fileName() +
"." +
type;
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
static void error(const char *str,...)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
static bool Exists(const QString &url, struct stat *fileinfo)
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
RefCountHandler< T > takeFirstAndDecr(void)
Removes the first item in the list and returns it.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
uint Wait(std::chrono::seconds timeout=0s)
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
T * takeFirst(void)
Removes the first item in the list and returns it.
bool isRunning(void) const
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
virtual int IncrRef(void)
Increments reference count.
@ kMSStdOut
allow access to stdout