void dumpAllLookups(RetsMetadata * metadata, MetadataResource * resource) { string resourceName = resource->GetResourceID(); MetadataLookupList classes = metadata->GetAllLookups(resourceName); MetadataLookupList::iterator i; for (i = classes.begin(); i != classes.end(); i++) { MetadataLookup * lookup = *i; cout << "Resource name: " << resourceName << " [" << resource->GetStandardName() << "]" << endl; cout << "Lookup name: " << lookup->GetLookupName() << " (" << lookup->GetVisibleName() << ")"; if (!lookup->GetMetadataEntryID().empty()) { cout << " MetadataEntryID: " << lookup->GetMetadataEntryID(); } cout << endl; dumpAllLookupTypes(metadata, lookup); cout << endl; } }
MetadataLookup* LookupFromProgramInfo(ProgramInfo *pginfo) { uint runtimesecs = pginfo->GetRecordingStartTime() .secsTo(pginfo->GetRecordingEndTime()); uint runtime = (runtimesecs/60); MetadataLookup *ret = new MetadataLookup(kMetadataRecording, kUnknownVideo, qVariantFromValue(pginfo), kLookupData, false, false, false, false, false, pginfo->GetHostname(),pginfo->GetBasename(),pginfo->GetTitle(), QStringList() << pginfo->GetCategory(), pginfo->GetStars() * 10, pginfo->GetSubtitle(), pginfo->GetDescription(), pginfo->GetChanID(), pginfo->GetChanNum(), pginfo->GetChannelSchedulingID(), pginfo->GetChannelName(), pginfo->GetChannelPlaybackFilters(), pginfo->GetRecordingGroup(), pginfo->GetPlaybackGroup(), pginfo->GetSeriesID(), pginfo->GetProgramID(), pginfo->GetStorageGroup(), pginfo->GetScheduledStartTime(), pginfo->GetScheduledEndTime(), pginfo->GetRecordingStartTime(), pginfo->GetRecordingEndTime(), pginfo->GetProgramFlags(), pginfo->GetAudioProperties(), pginfo->GetVideoProperties(), pginfo->GetSubtitleType(), pginfo->GetYearOfInitialRelease(), pginfo->GetOriginalAirDate(), pginfo->GetLastModifiedTime(), runtime, runtimesecs); ret->SetSeason(pginfo->GetSeason()); ret->SetEpisode(pginfo->GetEpisode()); ret->SetInetref(pginfo->GetInetRef()); return ret; }
QDomDocument CreateMetadataXML(ProgramInfo *pginfo) { QDomDocument doc("MythMetadataXML"); MetadataLookup *lookup = LookupFromProgramInfo(pginfo); if (lookup) doc = CreateMetadataXML(lookup); lookup->DecrRef(); lookup = nullptr; return doc; }
bool MetadataDownload::findBestMatch(MetadataLookupList list, QString originaltitle) { QStringList titles; // Build a list of all the titles for (MetadataLookupList::const_iterator i = list.begin(); i != list.end(); ++i) { titles.append((*i)->GetTitle()); } // Apply Levenshtein distance algorithm to determine closest match QString bestTitle = nearestName(originaltitle, titles); // If no "best" was chosen, give up. if (bestTitle.isEmpty()) { LOG(VB_GENERAL, LOG_ERR, QString("No adequate match or multiple " "matches found for %1. Update manually.") .arg(originaltitle)); return false; } LOG(VB_GENERAL, LOG_INFO, QString("Best Title Match For %1: %2") .arg(originaltitle).arg(bestTitle)); // Grab the one item that matches the besttitle (IMPERFECT) for (MetadataLookupList::const_iterator i = list.begin(); i != list.end(); ++i) { if ((*i)->GetTitle() == bestTitle) { MetadataLookup *newlookup = (*i); newlookup->SetStep(kLookupData); prependLookup(newlookup); return true; } } return false; }
void GameUI::StartGameImageSet(MythGenericTree *node, QStringList coverart, QStringList fanart, QStringList screenshot) { if (!node) return; RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData()); if (!metadata) return; ArtworkMap map; QString inetref = metadata->Inetref(); QString system = metadata->System(); QString title = metadata->Gamename(); if (metadata->Boxart().isEmpty() && coverart.size()) { ArtworkInfo info; info.url = coverart.takeAt(0).trimmed(); map.insert(kArtworkCoverart, info); } if (metadata->Fanart().isEmpty() && fanart.size()) { ArtworkInfo info; info.url = fanart.takeAt(0).trimmed(); map.insert(kArtworkFanart, info); } if (metadata->Screenshot().isEmpty() && screenshot.size()) { ArtworkInfo info; info.url = screenshot.takeAt(0).trimmed(); map.insert(kArtworkScreenshot, info); } MetadataLookup *lookup = new MetadataLookup(); lookup->SetTitle(metadata->Gamename()); lookup->SetSystem(metadata->System()); lookup->SetInetref(metadata->Inetref()); lookup->SetType(kMetadataGame); lookup->SetDownloads(map); lookup->SetData(qVariantFromValue(node)); m_imageDownload->addDownloads(lookup); }
// TODO // using the MetadataLookup object as both argument input, and parsed output, // is clumsy. break the inputs out into a separate object, and spawn a new // MetadataLookup object in ParseMetadataItem, rather than requiring an // existing one to reuse. MetadataLookupList MetaGrabberScript::RunGrabber(const QStringList &args, MetadataLookup *lookup, bool passseas) { MythSystemLegacy grabber(m_fullcommand, args, kMSStdOut); MetadataLookupList list; LOG(VB_GENERAL, LOG_INFO, QString("Running Grabber: %1 %2") .arg(m_fullcommand).arg(args.join(" "))); grabber.Run(); if (grabber.Wait() != GENERIC_EXIT_OK) return list; QByteArray result = grabber.ReadAll(); if (!result.isEmpty()) { QDomDocument doc; doc.setContent(result, true); QDomElement root = doc.documentElement(); QDomElement item = root.firstChildElement("item"); while (!item.isNull()) { MetadataLookup *tmp = ParseMetadataItem(item, lookup, passseas); tmp->SetInetref(QString("%1_%2").arg(m_command) .arg(tmp->GetInetref())); if (!tmp->GetCollectionref().isEmpty()) { tmp->SetCollectionref(QString("%1_%2").arg(m_command) .arg(tmp->GetCollectionref())); } list.append(tmp); // MetadataLookup is to be owned by the list tmp->DecrRef(); item = item.nextSiblingElement("item"); } } return list; }
void GameUI::gameSearch(MythGenericTree *node, bool automode) { if (!node) node = m_gameUITree->GetCurrentNode(); if (!node) return; RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData()); if (!metadata) return; MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataGame); lookup->SetData(qVariantFromValue(node)); if (automode) { lookup->SetAutomatic(true); } lookup->SetTitle(metadata->Gamename()); lookup->SetInetref(metadata->Inetref()); if (m_query->isRunning()) m_query->prependLookup(lookup); else m_query->addLookup(lookup); if (!automode) { //: %1 is the game name QString msg = tr("Fetching details for %1") .arg(metadata->Gamename()); createBusyDialog(msg); } }
void MetadataFactory::Lookup(ProgramInfo *pginfo, bool automatic, bool getimages, bool allowgeneric) { if (!pginfo) return; MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataRecording); lookup->SetSubtype(GuessLookupType(pginfo)); lookup->SetData(qVariantFromValue(pginfo)); lookup->SetAutomatic(automatic); lookup->SetHandleImages(getimages); lookup->SetAllowGeneric(allowgeneric); lookup->SetHost(gCoreContext->GetMasterHostName()); lookup->SetTitle(pginfo->GetTitle()); lookup->SetSubtitle(pginfo->GetSubtitle()); lookup->SetSeason(pginfo->GetSeason()); lookup->SetEpisode(pginfo->GetEpisode()); lookup->SetInetref(pginfo->GetInetRef()); if (m_lookupthread->isRunning()) m_lookupthread->prependLookup(lookup); else m_lookupthread->addLookup(lookup); }
void MetadataFactory::Lookup(RecordingRule *recrule, bool automatic, bool getimages, bool allowgeneric) { if (!recrule) return; MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataRecording); lookup->SetSubtype(GuessLookupType(recrule)); lookup->SetData(qVariantFromValue(recrule)); lookup->SetAutomatic(automatic); lookup->SetHandleImages(getimages); lookup->SetAllowGeneric(allowgeneric); lookup->SetHost(gCoreContext->GetMasterHostName()); lookup->SetTitle(recrule->m_title); lookup->SetSubtitle(recrule->m_subtitle); lookup->SetInetref(recrule->m_inetref); lookup->SetSeason(recrule->m_season); lookup->SetEpisode(recrule->m_episode); if (m_lookupthread->isRunning()) m_lookupthread->prependLookup(lookup); else m_lookupthread->addLookup(lookup); }
META_PUBLIC MetadataLookupList MetadataFactory::SynchronousLookup(QString title, QString subtitle, QString inetref, int season, int episode, QString grabber, bool allowgeneric) { MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataRecording); lookup->SetAutomatic(false); lookup->SetHandleImages(false); lookup->SetAllowGeneric(allowgeneric); lookup->SetTitle(title); lookup->SetSubtitle(subtitle); lookup->SetSeason(season); lookup->SetEpisode(episode); lookup->SetInetref(inetref); if (grabber.toLower() == "movie") lookup->SetSubtype(kProbableMovie); else if (grabber.toLower() == "tv" || grabber.toLower() == "television") lookup->SetSubtype(kProbableTelevision); else lookup->SetSubtype(GuessLookupType(lookup)); return SynchronousLookup(lookup); }
void MetadataFactory::Lookup(VideoMetadata *metadata, bool automatic, bool getimages, bool allowgeneric) { if (!metadata) return; MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataVideo); if (metadata->GetSeason() > 0 || metadata->GetEpisode() > 0) lookup->SetSubtype(kProbableTelevision); else if (metadata->GetSubtitle().isEmpty()) lookup->SetSubtype(kProbableMovie); else lookup->SetSubtype(kUnknownVideo); lookup->SetData(qVariantFromValue(metadata)); lookup->SetAutomatic(automatic); lookup->SetHandleImages(getimages); lookup->SetAllowGeneric(allowgeneric); lookup->SetHost(metadata->GetHost()); lookup->SetTitle(metadata->GetTitle()); lookup->SetSubtitle(metadata->GetSubtitle()); lookup->SetSeason(metadata->GetSeason()); lookup->SetEpisode(metadata->GetEpisode()); lookup->SetInetref(metadata->GetInetRef()); QString fntmp; if (metadata->GetHost().isEmpty()) fntmp = metadata->GetFilename(); else fntmp = generate_file_url("Videos", metadata->GetHost(), metadata->GetFilename()); lookup->SetFilename(fntmp); if (m_lookupthread->isRunning()) m_lookupthread->prependLookup(lookup); else m_lookupthread->addLookup(lookup); }
void MetadataFactory::Lookup(VideoMetadata *metadata, bool automatic, bool getimages, bool allowgeneric) { if (!metadata) return; MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataVideo); lookup->SetSubtype(GuessLookupType(metadata)); lookup->SetData(qVariantFromValue(metadata)); lookup->SetAutomatic(automatic); lookup->SetHandleImages(getimages); lookup->SetAllowGeneric(allowgeneric); lookup->SetHost(metadata->GetHost()); lookup->SetTitle(metadata->GetTitle()); lookup->SetSubtitle(metadata->GetSubtitle()); lookup->SetSeason(metadata->GetSeason()); lookup->SetEpisode(metadata->GetEpisode()); lookup->SetInetref(metadata->GetInetRef()); lookup->SetFilename(generate_file_url("Videos", metadata->GetHost(), metadata->GetFilename())); if (m_lookupthread->isRunning()) m_lookupthread->prependLookup(lookup); else m_lookupthread->addLookup(lookup); }
void MetadataImageDownload::run() { // Always handle thumbnails first, they're higher priority. ThumbnailData *thumb; while ((thumb = moreThumbs()) != NULL) { QString sFilename = getDownloadFilename(thumb->title, thumb->url); bool exists = QFile::exists(sFilename); if (!exists && !thumb->url.isEmpty()) GetMythDownloadManager()->download(thumb->url, sFilename); // inform parent we have thumbnail ready for it if (QFile::exists(sFilename) && m_parent) { VERBOSE(VB_GENERAL|VB_EXTRA, QString("Threaded Image Thumbnail Download: %1") .arg(sFilename)); thumb->url = sFilename; QCoreApplication::postEvent(m_parent, new ThumbnailDLEvent(thumb)); } else delete thumb; } MetadataLookup *lookup; while ((lookup = moreDownloads()) != NULL) { DownloadMap downloads = lookup->GetDownloads(); DownloadMap downloaded; for (DownloadMap::iterator i = downloads.begin(); i != downloads.end(); ++i) { ArtworkType type = i.key(); ArtworkInfo info = i.value(); QString filename = getDownloadFilename( type, lookup, info.url ); if (lookup->GetHost().isEmpty()) { QString path = getLocalWritePath(lookup->GetType(), type); QDir dirPath(path); if (!dirPath.exists()) if (!dirPath.mkpath(path)) { VERBOSE(VB_GENERAL, QString("Metadata Image Download: Unable to create " "path %1, aborting download.").arg(path)); continue; } QString finalfile = path + "/" + filename; QString oldurl = info.url; info.url = finalfile; if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites()) { QFile dest_file(finalfile); if (dest_file.exists()) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); dest_file.remove(); } VERBOSE(VB_GENERAL, QString("Metadata Image Download: %1 ->%2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { VERBOSE(VB_IMPORTANT,QString("Tried to write %1, " "but it appears to be an HTML redirect " "(filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; continue; } if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(*download, download->size()); if (size != download->size()) { VERBOSE(VB_IMPORTANT, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); } else downloaded.insert(type, info); } delete download; } else downloaded.insert(type, info); } else { QString path = getStorageGroupURL(type, lookup->GetHost()); QString finalfile = path + filename; QString oldurl = info.url; info.url = finalfile; if (!RemoteFile::Exists(finalfile) || lookup->GetAllowOverwrites()) { if (RemoteFile::Exists(finalfile)) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); RemoteFile::DeleteFile(finalfile); } VERBOSE(VB_GENERAL, QString("Metadata Image Download: %1 -> %2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { VERBOSE(VB_IMPORTANT,QString("Tried to write %1, " "but it appears to be an HTML redirect " "or corrupt file (filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; continue; } RemoteFile *outFile = new RemoteFile(finalfile, true); if (!outFile->isOpen()) { VERBOSE(VB_IMPORTANT, QString("Image Download: Failed to open " "remote file (%1) for write. Does " "Storage Group Exist?") .arg(finalfile)); delete outFile; outFile = NULL; } else { off_t written = outFile->Write(*download, download->size()); if (written != download->size()) { VERBOSE(VB_IMPORTANT, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); } else downloaded.insert(type, info); delete outFile; outFile = NULL; } delete download; } else downloaded.insert(type, info); } } lookup->SetDownloads(downloaded); QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup)); } }
void MetadataImageDownload::run() { RunProlog(); // Always handle thumbnails first, they're higher priority. ThumbnailData *thumb; while ((thumb = moreThumbs()) != NULL) { QString sFilename = getDownloadFilename(thumb->title, thumb->url); bool exists = QFile::exists(sFilename); if (!exists && !thumb->url.isEmpty()) { if (!GetMythDownloadManager()->download(thumb->url, sFilename)) { LOG(VB_GENERAL, LOG_ERR, QString("MetadataImageDownload: failed to download thumbnail from: %1") .arg(thumb->url)); delete thumb; continue; } } // inform parent we have thumbnail ready for it if (QFile::exists(sFilename) && m_parent) { LOG(VB_GENERAL, LOG_DEBUG, QString("Threaded Image Thumbnail Download: %1") .arg(sFilename)); thumb->url = sFilename; QCoreApplication::postEvent(m_parent, new ThumbnailDLEvent(thumb)); } else delete thumb; } while (true) { m_mutex.lock(); if (m_downloadList.isEmpty()) { // no more to process, we're done m_mutex.unlock(); break; } // Ref owns the MetadataLookup object for the duration of the loop // and it will be deleted automatically when the loop completes RefCountHandler<MetadataLookup> ref = m_downloadList.takeFirstAndDecr(); m_mutex.unlock(); MetadataLookup *lookup = ref; DownloadMap downloads = lookup->GetDownloads(); DownloadMap downloaded; bool errored = false; for (DownloadMap::iterator i = downloads.begin(); i != downloads.end(); ++i) { VideoArtworkType type = i.key(); ArtworkInfo info = i.value(); QString filename = getDownloadFilename( type, lookup, info.url ); if (lookup->GetHost().isEmpty()) { QString path = getLocalWritePath(lookup->GetType(), type); QDir dirPath(path); if (!dirPath.exists()) { if (!dirPath.mkpath(path)) { LOG(VB_GENERAL, LOG_ERR, QString("Metadata Image Download: Unable to create " "path %1, aborting download.").arg(path)); errored = true; break; } } QString finalfile = path + "/" + filename; QString oldurl = info.url; info.url = finalfile; if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites()) { QFile dest_file(finalfile); if (dest_file.exists()) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); dest_file.remove(); } LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 ->%2") .arg(oldurl).arg(finalfile)); QByteArray download; GetMythDownloadManager()->download(oldurl, &download); QImage testImage; bool didLoad = testImage.loadFromData(download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect (filesize %2).") .arg(oldurl).arg(download.size())); errored = true; break; } if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(download, download.size()); dest_file.close(); if (size != download.size()) { // File creation failed for some reason, delete it RemoteFile::DeleteFile(finalfile); LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); errored = true; break; } } } } else { QString path = getStorageGroupURL(type, lookup->GetHost()); QString finalfile = path + filename; QString oldurl = info.url; info.url = finalfile; bool exists = false; bool onMaster = false; QString resolvedFN; if (gCoreContext->IsMasterBackend() && gCoreContext->IsThisHost(lookup->GetHost())) { StorageGroup sg(getStorageGroupName(type), lookup->GetHost()); resolvedFN = sg.FindFile(filename); exists = !resolvedFN.isEmpty() && QFile::exists(resolvedFN); if (!exists) { resolvedFN = getLocalStorageGroupPath(type, lookup->GetHost()) + "/" + filename; } onMaster = true; } else exists = RemoteFile::Exists(finalfile); if (!exists || lookup->GetAllowOverwrites()) { if (exists && !onMaster) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); RemoteFile::DeleteFile(finalfile); } else if (exists) QFile::remove(resolvedFN); LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 -> %2") .arg(oldurl).arg(finalfile)); QByteArray download; GetMythDownloadManager()->download(oldurl, &download); QImage testImage; bool didLoad = testImage.loadFromData(download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect or corrupt file " "(filesize %2).") .arg(oldurl).arg(download.size())); errored = true; break; } if (!onMaster) { RemoteFile outFile(finalfile, true); if (!outFile.isOpen()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Failed to open " "remote file (%1) for write. Does " "Storage Group Exist?") .arg(finalfile)); errored = true; break; } off_t written = outFile.Write(download, download.size()); if (written != download.size()) { // File creation failed for some reason, delete it RemoteFile::DeleteFile(finalfile); LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); errored = true; break; } } else { QFile dest_file(resolvedFN); if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(download, download.size()); dest_file.close(); if (size != download.size()) { // File creation failed for some reason, delete it RemoteFile::DeleteFile(resolvedFN); LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); errored = true; break; } } } } } if (!errored) { // update future Artwork Map with what we've successfully // retrieved (either downloaded or already existing downloaded.insert(type, info); } } if (errored) { QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); errored = false; } lookup->SetDownloads(downloaded); QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup)); } RunEpilog(); }
void EditMetadataDialog::OnSearchListSelection(ArtworkInfo info, VideoArtworkType type) { QString msg = tr("Downloading selected artwork..."); createBusyDialog(msg); MetadataLookup *lookup = new MetadataLookup(); lookup->SetType(kMetadataVideo); if (m_workingMetadata->GetSeason() > 0 || m_workingMetadata->GetEpisode() > 0) lookup->SetSubtype(kProbableTelevision); else if (m_workingMetadata->GetSubtitle().isEmpty()) lookup->SetSubtype(kProbableMovie); else lookup->SetSubtype(kUnknownVideo); lookup->SetHost(m_workingMetadata->GetHost()); lookup->SetAutomatic(true); lookup->SetData(qVariantFromValue<VideoArtworkType>(type)); ArtworkMap downloads; downloads.insert(type, info); lookup->SetDownloads(downloads); lookup->SetAllowOverwrites(true); lookup->SetTitle(m_workingMetadata->GetTitle()); lookup->SetSubtitle(m_workingMetadata->GetSubtitle()); lookup->SetSeason(m_workingMetadata->GetSeason()); lookup->SetEpisode(m_workingMetadata->GetEpisode()); lookup->SetInetref(m_workingMetadata->GetInetRef()); m_imageDownload->addDownloads(lookup); }
void MetadataDownload::run() { MetadataLookup* lookup; threadRegister("MetadataDownload"); while ((lookup = moreWork()) != NULL) { MetadataLookupList list; // Go go gadget Metadata Lookup if (lookup->GetType() == VID) { if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0) list = handleTelevision(lookup); else if (!lookup->GetSubtitle().isEmpty()) list = handleVideoUndetermined(lookup); else list = handleMovie(lookup); } // else if (lookup->GetType() == MUSIC) // list = handleMusic(lookup); else if (lookup->GetType() == GAME) list = handleGame(lookup); // inform parent we have lookup ready for it if (m_parent && list.count() >= 1) { // If there's only one result, don't bother asking // our parent about it, just add it to the back of // the queue in GETDATA mode. if (list.count() == 1 && list.at(0)->GetStep() == SEARCH) { MetadataLookup *newlookup = list.takeFirst(); newlookup->SetStep(GETDATA); prependLookup(newlookup); continue; } // If we're in automatic mode, we need to make // these decisions on our own. Pass to title match. if (list.at(0)->GetAutomatic() && list.count() > 1) { if (!findBestMatch(list, lookup->GetTitle())) QCoreApplication::postEvent(m_parent, new MetadataLookupFailure(MetadataLookupList() << lookup)); continue; } VERBOSE(VB_GENERAL, QString("Returning Metadata Results: %1 %2 %3") .arg(lookup->GetTitle()).arg(lookup->GetSeason()) .arg(lookup->GetEpisode())); QCoreApplication::postEvent(m_parent, new MetadataLookupEvent(list)); } else { list.append(lookup); QCoreApplication::postEvent(m_parent, new MetadataLookupFailure(list)); } } threadDeregister(); }
void ImportFile::doGetRecording(void) { MythUIButtonListItem *item = m_recordingButtonList->GetItemCurrent(); if (!item) return; ImportItem *i = item->GetData().value<ImportItem *>(); if (!i) return; uint duration = 60; //i->actualDuration; QString videoFile = getTempDirectory() + "work/video.ts"; QString mxmlFile = getTempDirectory() + "work/video.mxml"; // record the mp4 video stream QString recCommand = QString("mythffmpeg -y -i %1 -t %2 -acodec copy -vcodec copy %3") .arg(STREAMURL).arg(duration).arg(videoFile); QScopedPointer<MythSystem> cmd(MythSystem::Create(recCommand, kMSRunShell)); cmd->Wait(0); if (cmd.data()->GetExitCode() != GENERIC_EXIT_OK) { LOG(VB_GENERAL, LOG_ERR, QString("ERROR - ffmpeg exited with result: %1").arg(cmd.data()->GetExitCode())); return; } // create a mxml file with the metadata for this recording QStringList categories(i->category.split(',')); MetadataLookup *lookup = new MetadataLookup(kMetadataVideo, kProbableTelevision, QVariant(), kLookupSearch, false, false, false, false, false, "", videoFile, i->title, categories, 0.0, i->subtitle, "", i->description, i->season, i->episode, i->startTime, 0, i->chanNo, i->chanSign, i->chanName, i->certification, i->startTime.date().year(), i->startTime.date(), i->duration / 60, i->duration, "", PeopleMap(), "", ArtworkMap(), DownloadMap()); if (i->category == "Movies") lookup->SetVideoContentType(kContentMovie); else lookup->SetVideoContentType(kContentTelevision); QDomDocument mxmlDoc = CreateMetadataXML(lookup); // save the mxml to the file QFile f(mxmlFile); if (!f.open(QIODevice::WriteOnly)) { LOG(VB_GENERAL, LOG_ERR, QString("ImportFile: Failed to open mxml file for writing - %1").arg(mxmlFile)); return; } QTextStream t(&f); t << mxmlDoc.toString(4); f.close(); // workout where to save the file in the Video storage group QString dstFile = filenameFromMetadataLookup(lookup); QString saveFilename; // copy the recording to the Video storage group saveFilename = gCoreContext->GenMythURL(gCoreContext->GetMasterHostName(), 0, dstFile + ".mp4", "Videos"); bool result = RemoteFile::CopyFile(videoFile, saveFilename); if (!result) { LOG(VB_GENERAL, LOG_ERR, QString("ImportFile: Failed to copy video file to %1").arg(saveFilename)); return; } // copy the metadata xml file to the Video storage group saveFilename = gCoreContext->GenMythURL(gCoreContext->GetMasterHostName(), 0, dstFile + ".mxml", "Videos"); result = RemoteFile::CopyFile(mxmlFile, saveFilename); if (!result) { LOG(VB_GENERAL, LOG_ERR, QString("ImportFile: Failed to copy xml file to %1").arg(saveFilename)); return; } }
void GameUI::customEvent(QEvent *event) { if (event->type() == DialogCompletionEvent::kEventType) { DialogCompletionEvent *dce = (DialogCompletionEvent*)(event); QString resultid = dce->GetId(); QString resulttext = dce->GetResultText(); if (resultid == "showMenuPopup") { if (resulttext == tr("Edit Details")) { edit(); } if (resulttext == tr("Scan For Changes")) { doScan(); } else if (resulttext == tr("Show Information")) { showInfo(); } else if (resulttext == tr("Make Favorite") || resulttext == tr("Remove Favorite")) { toggleFavorite(); } else if (resulttext == tr("Retrieve Details")) { gameSearch(); } } else if (resultid == "chooseSystemPopup") { if (!resulttext.isEmpty() && resulttext != tr("Cancel")) { MythGenericTree *node = m_gameUITree->GetCurrentNode(); RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData()); GameHandler::Launchgame(romInfo, resulttext); } } else if (resultid == "editMetadata") { MythGenericTree *node = m_gameUITree->GetCurrentNode(); RomInfo *oldRomInfo = qVariantValue<RomInfo *>(node->GetData()); delete oldRomInfo; RomInfo *romInfo = qVariantValue<RomInfo *>(dce->GetData()); node->SetData(qVariantFromValue(romInfo)); node->SetText(romInfo->Gamename()); romInfo->SaveToDatabase(); updateChangedNode(node, romInfo); } else if (resultid == "detailsPopup") { // Play button pushed itemClicked(0); } } if (event->type() == MetadataLookupEvent::kEventType) { MetadataLookupEvent *lue = (MetadataLookupEvent *)event; MetadataLookupList lul = lue->lookupList; if (m_busyPopup) { m_busyPopup->Close(); m_busyPopup = NULL; } if (lul.isEmpty()) return; if (lul.count() == 1) { OnGameSearchDone(lul.takeFirst()); } else { MetadataResultsDialog *resultsdialog = new MetadataResultsDialog(m_popupStack, lul); connect(resultsdialog, SIGNAL(haveResult(MetadataLookup*)), SLOT(OnGameSearchListSelection(MetadataLookup*)), Qt::QueuedConnection); if (resultsdialog->Create()) m_popupStack->AddScreen(resultsdialog); } } else if (event->type() == MetadataLookupFailure::kEventType) { MetadataLookupFailure *luf = (MetadataLookupFailure *)event; MetadataLookupList lul = luf->lookupList; if (m_busyPopup) { m_busyPopup->Close(); m_busyPopup = NULL; } if (lul.size()) { MetadataLookup *lookup = lul.takeFirst(); MythGenericTree *node = qVariantValue<MythGenericTree *>(lookup->GetData()); if (node) { RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData()); if (metadata) { } } LOG(VB_GENERAL, LOG_ERR, QString("No results found for %1").arg(lookup->GetTitle())); } } else if (event->type() == ImageDLEvent::kEventType) { ImageDLEvent *ide = (ImageDLEvent *)event; MetadataLookup *lookup = ide->item; if (!lookup) return; handleDownloadedImages(lookup); } }
void LookerUpper::customEvent(QEvent *levent) { if (levent->type() == MetadataFactoryMultiResult::kEventType) { VERBOSE(VB_IMPORTANT, "Got a multiresult."); // We shouldn't get any of these. If we do, metadataFactory->Lookup // was called with the wrong arguments. } else if (levent->type() == MetadataFactorySingleResult::kEventType) { MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent); if (!mfsr) return; MetadataLookup *lookup = mfsr->result; if (!lookup) return; ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(lookup->GetData()); // This null check could hang us as this pginfo would then never be removed if (!pginfo) return; VERBOSE(VB_GENERAL|VB_EXTRA, QString("I found the following data:")); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Input Title: %1").arg(pginfo->GetTitle())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Input Sub: %1").arg(pginfo->GetSubtitle())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Title: %1").arg(lookup->GetTitle())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Subtitle: %1").arg(lookup->GetSubtitle())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Season: %1").arg(lookup->GetSeason())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Episode: %1").arg(lookup->GetEpisode())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Inetref: %1").arg(lookup->GetInetref())); VERBOSE(VB_GENERAL|VB_EXTRA, QString(" User Rating: %1").arg(lookup->GetUserRating())); pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); pginfo->SaveInetRef(lookup->GetInetref()); m_busyRecList.removeAll(pginfo); } else if (levent->type() == MetadataFactoryNoResult::kEventType) { MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent); if (!mfnr) return; MetadataLookup *lookup = mfnr->result; if (!lookup) return; ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(lookup->GetData()); // This null check could hang us as this pginfo would then never be removed if (!pginfo) return; m_busyRecList.removeAll(pginfo); } }
void LookerUpper::customEvent(QEvent *levent) { if (levent->type() == MetadataFactoryMultiResult::kEventType) { MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent); if (!mfmr) return; MetadataLookupList list = mfmr->results; if (list.count() > 1) { int yearindex = -1; for (int p = 0; p != list.size(); ++p) { ProgramInfo *pginfo = list[p]->GetData().value<ProgramInfo *>(); if (pginfo && !pginfo->GetSeriesID().isEmpty() && pginfo->GetSeriesID() == (list[p])->GetTMSref()) { MetadataLookup *lookup = list[p]; if (lookup->GetSubtype() != kProbableGenericTelevision) pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); pginfo->SaveInetRef(lookup->GetInetref()); m_busyRecList.removeAll(pginfo); return; } else if (pginfo && pginfo->GetYearOfInitialRelease() != 0 && (list[p])->GetYear() != 0 && pginfo->GetYearOfInitialRelease() == (list[p])->GetYear()) { if (yearindex != -1) { LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite " "match could be found."); m_busyRecList.removeAll(pginfo); return; } else { LOG(VB_GENERAL, LOG_INFO, "Matched from multiple results based on year. "); yearindex = p; } } } if (yearindex > -1) { MetadataLookup *lookup = list[yearindex]; ProgramInfo *pginfo = lookup->GetData().value<ProgramInfo *>(); if (lookup->GetSubtype() != kProbableGenericTelevision) pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); pginfo->SaveInetRef(lookup->GetInetref()); m_busyRecList.removeAll(pginfo); return; } LOG(VB_GENERAL, LOG_INFO, "Unable to match this title, too many possible matches. " "You may wish to manually set the season, episode, and " "inetref in the 'Watch Recordings' screen."); ProgramInfo *pginfo = list[0]->GetData().value<ProgramInfo *>(); if (pginfo) { m_busyRecList.removeAll(pginfo); } } } else if (levent->type() == MetadataFactorySingleResult::kEventType) { MetadataFactorySingleResult *mfsr = dynamic_cast<MetadataFactorySingleResult*>(levent); if (!mfsr) return; MetadataLookup *lookup = mfsr->result; if (!lookup) return; ProgramInfo *pginfo = lookup->GetData().value<ProgramInfo *>(); // This null check could hang us as this pginfo would then never be // removed if (!pginfo) return; LOG(VB_GENERAL, LOG_DEBUG, "I found the following data:"); LOG(VB_GENERAL, LOG_DEBUG, QString(" Input Title: %1").arg(pginfo->GetTitle())); LOG(VB_GENERAL, LOG_DEBUG, QString(" Input Sub: %1").arg(pginfo->GetSubtitle())); LOG(VB_GENERAL, LOG_DEBUG, QString(" Title: %1").arg(lookup->GetTitle())); LOG(VB_GENERAL, LOG_DEBUG, QString(" Subtitle: %1").arg(lookup->GetSubtitle())); LOG(VB_GENERAL, LOG_DEBUG, QString(" Season: %1").arg(lookup->GetSeason())); LOG(VB_GENERAL, LOG_DEBUG, QString(" Episode: %1").arg(lookup->GetEpisode())); LOG(VB_GENERAL, LOG_DEBUG, QString(" Inetref: %1").arg(lookup->GetInetref())); LOG(VB_GENERAL, LOG_DEBUG, QString(" User Rating: %1").arg(lookup->GetUserRating())); if (lookup->GetSubtype() != kProbableGenericTelevision) pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); pginfo->SaveInetRef(lookup->GetInetref()); if (m_updaterules) { RecordingRule *rule = new RecordingRule(); if (rule) { rule->LoadByProgram(pginfo); if (rule->m_inetref.isEmpty() && (rule->m_searchType == kNoSearch)) { rule->m_inetref = lookup->GetInetref(); } rule->m_season = lookup->GetSeason(); rule->m_episode = lookup->GetEpisode(); rule->Save(); delete rule; } } if (m_updateartwork) { ArtworkMap map = lookup->GetDownloads(); SetArtwork(lookup->GetInetref(), lookup->GetIsCollection() ? 0 : lookup->GetSeason(), gCoreContext->GetMasterHostName(), map); } m_busyRecList.removeAll(pginfo); } else if (levent->type() == MetadataFactoryNoResult::kEventType) { MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent); if (!mfnr) return; MetadataLookup *lookup = mfnr->result; if (!lookup) return; ProgramInfo *pginfo = lookup->GetData().value<ProgramInfo *>(); // This null check could hang us as this pginfo would then never be removed if (!pginfo) return; m_busyRecList.removeAll(pginfo); } }
void EditMetadataDialog::FindNetArt(VideoArtworkType type) { QString msg = tr("Searching for available artwork..."); createBusyDialog(msg); MetadataLookup *lookup = new MetadataLookup(); lookup->SetStep(kLookupSearch); lookup->SetType(kMetadataVideo); lookup->SetAutomatic(true); if (m_workingMetadata->GetSeason() > 0 || m_workingMetadata->GetEpisode() > 0) lookup->SetSubtype(kProbableTelevision); else if (m_workingMetadata->GetSubtitle().isEmpty()) lookup->SetSubtype(kProbableMovie); else lookup->SetSubtype(kUnknownVideo); lookup->SetData(qVariantFromValue<VideoArtworkType>(type)); lookup->SetTitle(m_workingMetadata->GetTitle()); lookup->SetSubtitle(m_workingMetadata->GetSubtitle()); lookup->SetSeason(m_workingMetadata->GetSeason()); lookup->SetEpisode(m_workingMetadata->GetEpisode()); lookup->SetInetref(m_workingMetadata->GetInetRef()); m_query->addLookup(lookup); }
void MetadataImageDownload::run() { RunProlog(); // Always handle thumbnails first, they're higher priority. ThumbnailData *thumb; while ((thumb = moreThumbs()) != NULL) { QString sFilename = getDownloadFilename(thumb->title, thumb->url); bool exists = QFile::exists(sFilename); if (!exists && !thumb->url.isEmpty()) { if (!GetMythDownloadManager()->download(thumb->url, sFilename)) { LOG(VB_GENERAL, LOG_ERR, QString("MetadataImageDownload: failed to download thumbnail from: %1") .arg(thumb->url)); delete thumb; continue; } } // inform parent we have thumbnail ready for it if (QFile::exists(sFilename) && m_parent) { LOG(VB_GENERAL, LOG_DEBUG, QString("Threaded Image Thumbnail Download: %1") .arg(sFilename)); thumb->url = sFilename; QCoreApplication::postEvent(m_parent, new ThumbnailDLEvent(thumb)); } else delete thumb; } MetadataLookup *lookup; while ((lookup = moreDownloads()) != NULL) { DownloadMap downloads = lookup->GetDownloads(); DownloadMap downloaded; for (DownloadMap::iterator i = downloads.begin(); i != downloads.end(); ++i) { VideoArtworkType type = i.key(); ArtworkInfo info = i.value(); QString filename = getDownloadFilename( type, lookup, info.url ); if (lookup->GetHost().isEmpty()) { QString path = getLocalWritePath(lookup->GetType(), type); QDir dirPath(path); if (!dirPath.exists()) if (!dirPath.mkpath(path)) { LOG(VB_GENERAL, LOG_ERR, QString("Metadata Image Download: Unable to create " "path %1, aborting download.").arg(path)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); continue; } QString finalfile = path + "/" + filename; QString oldurl = info.url; info.url = finalfile; if (!QFile::exists(finalfile) || lookup->GetAllowOverwrites()) { QFile dest_file(finalfile); if (dest_file.exists()) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); dest_file.remove(); } LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 ->%2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect (filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); continue; } if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(*download, download->size()); if (size != download->size()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else downloaded.insert(type, info); } delete download; } else downloaded.insert(type, info); } else { QString path = getStorageGroupURL(type, lookup->GetHost()); QString finalfile = path + filename; QString oldurl = info.url; info.url = finalfile; bool exists = false; bool onMaster = false; QString resolvedFN; if ((lookup->GetHost().toLower() == gCoreContext->GetHostName().toLower()) || (gCoreContext->IsThisHost(lookup->GetHost()))) { StorageGroup sg; resolvedFN = sg.FindFile(filename); exists = QFile::exists(resolvedFN); if (!exists) { resolvedFN = getLocalStorageGroupPath(type, lookup->GetHost()) + "/" + filename; } onMaster = true; } else exists = RemoteFile::Exists(finalfile); if (!exists || lookup->GetAllowOverwrites()) { if (exists && !onMaster) { QFileInfo fi(finalfile); GetMythUI()->RemoveFromCacheByFile(fi.fileName()); RemoteFile::DeleteFile(finalfile); } else if (exists) QFile::remove(resolvedFN); LOG(VB_GENERAL, LOG_INFO, QString("Metadata Image Download: %1 -> %2") .arg(oldurl).arg(finalfile)); QByteArray *download = new QByteArray(); GetMythDownloadManager()->download(oldurl, download); QImage testImage; bool didLoad = testImage.loadFromData(*download); if (!didLoad) { LOG(VB_GENERAL, LOG_ERR, QString("Tried to write %1, but it appears to be " "an HTML redirect or corrupt file " "(filesize %2).") .arg(oldurl).arg(download->size())); delete download; download = NULL; QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); continue; } if (!onMaster) { RemoteFile *outFile = new RemoteFile(finalfile, true); if (!outFile->isOpen()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Failed to open " "remote file (%1) for write. Does " "Storage Group Exist?") .arg(finalfile)); delete outFile; outFile = NULL; QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else { off_t written = outFile->Write(*download, download->size()); if (written != download->size()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else downloaded.insert(type, info); delete outFile; outFile = NULL; } } else { QFile dest_file(resolvedFN); if (dest_file.open(QIODevice::WriteOnly)) { off_t size = dest_file.write(*download, download->size()); if (size != download->size()) { LOG(VB_GENERAL, LOG_ERR, QString("Image Download: Error Writing Image " "to file: %1").arg(finalfile)); QCoreApplication::postEvent(m_parent, new ImageDLFailureEvent(lookup)); } else downloaded.insert(type, info); } } delete download; } else downloaded.insert(type, info); } } lookup->SetDownloads(downloaded); QCoreApplication::postEvent(m_parent, new ImageDLEvent(lookup)); } RunEpilog(); }
void EditMetadataDialog::customEvent(QEvent *levent) { if (levent->type() == DialogCompletionEvent::kEventType) { DialogCompletionEvent *dce = (DialogCompletionEvent*)(levent); const QString resultid = dce->GetId(); if (resultid == CEID_COVERARTFILE) SetCoverArt(dce->GetResultText()); else if (resultid == CEID_BANNERFILE) SetBanner(dce->GetResultText()); else if (resultid == CEID_FANARTFILE) SetFanart(dce->GetResultText()); else if (resultid == CEID_SCREENSHOTFILE) SetScreenshot(dce->GetResultText()); else if (resultid == CEID_TRAILERFILE) SetTrailer(dce->GetResultText()); else if (resultid == CEID_NEWCATEGORY) AddCategory(dce->GetResultText()); } else if (levent->type() == MetadataLookupEvent::kEventType) { MetadataLookupEvent *lue = (MetadataLookupEvent *)levent; MetadataLookupList lul = lue->lookupList; if (lul.isEmpty()) return; // There should really only be one result here. // If not, USER ERROR! if (lul.count() == 1) { OnArtworkSearchDone(lul[0]); } else { if (m_busyPopup) { m_busyPopup->Close(); m_busyPopup = NULL; } } } else if (levent->type() == MetadataLookupFailure::kEventType) { MetadataLookupFailure *luf = (MetadataLookupFailure *)levent; MetadataLookupList lul = luf->lookupList; if (m_busyPopup) { m_busyPopup->Close(); m_busyPopup = NULL; } if (lul.size()) { MetadataLookup *lookup = lul[0]; LOG(VB_GENERAL, LOG_INFO, QString("No results found for %1 %2 %3").arg(lookup->GetTitle()) .arg(lookup->GetSeason()).arg(lookup->GetEpisode())); } } else if (levent->type() == ImageDLEvent::kEventType) { ImageDLEvent *ide = (ImageDLEvent *)levent; MetadataLookup *lookup = ide->item; if (!lookup) return; handleDownloadedImages(lookup); } else if (levent->type() == ImageDLFailureEvent::kEventType) { MythErrorNotification n(tr("Failed to retrieve image"), tr("Metadata Editor"), tr("Check logs")); GetNotificationCenter()->Queue(n); } }
void MetadataDownload::run() { RunProlog(); MetadataLookup* lookup; while ((lookup = moreWork()) != NULL) { MetadataLookupList list; // Go go gadget Metadata Lookup if (lookup->GetType() == kMetadataVideo) { if (lookup->GetSubtype() == kProbableTelevision) list = handleTelevision(lookup); else if (lookup->GetSubtype() == kProbableMovie) list = handleMovie(lookup); else list = handleVideoUndetermined(lookup); if (!list.size() && lookup->GetSubtype() == kUnknownVideo) { list = handleMovie(lookup); } } else if (lookup->GetType() == kMetadataRecording) { if (lookup->GetSubtype() == kProbableTelevision) { if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0) list = handleTelevision(lookup); else if (!lookup->GetSubtitle().isEmpty()) list = handleVideoUndetermined(lookup); if (!list.size()) list = handleRecordingGeneric(lookup); } else if (lookup->GetSubtype() == kProbableMovie) { list = handleMovie(lookup); if (lookup->GetInetref().isEmpty()) list.append(handleRecordingGeneric(lookup)); } else { list = handleRecordingGeneric(lookup); if (lookup->GetInetref().isEmpty()) list.append(handleMovie(lookup)); } } else if (lookup->GetType() == kMetadataGame) list = handleGame(lookup); // inform parent we have lookup ready for it if (m_parent && list.count() >= 1) { // If there's only one result, don't bother asking // our parent about it, just add it to the back of // the queue in kLookupData mode. if (list.count() == 1 && list.at(0)->GetStep() == kLookupSearch) { MetadataLookup *newlookup = list.takeFirst(); newlookup->SetStep(kLookupData); prependLookup(newlookup); continue; } // If we're in automatic mode, we need to make // these decisions on our own. Pass to title match. if (list.at(0)->GetAutomatic() && list.count() > 1) { if (!findBestMatch(list, lookup->GetTitle())) QCoreApplication::postEvent(m_parent, new MetadataLookupFailure(MetadataLookupList() << lookup)); continue; } LOG(VB_GENERAL, LOG_INFO, QString("Returning Metadata Results: %1 %2 %3") .arg(lookup->GetTitle()).arg(lookup->GetSeason()) .arg(lookup->GetEpisode())); QCoreApplication::postEvent(m_parent, new MetadataLookupEvent(list)); } else { list.append(lookup); QCoreApplication::postEvent(m_parent, new MetadataLookupFailure(list)); } } RunEpilog(); }
DTC::VideoLookupList* Video::LookupVideo( const QString &Title, const QString &Subtitle, const QString &Inetref, int Season, int Episode, const QString &GrabberType ) { DTC::VideoLookupList *pVideoLookups = new DTC::VideoLookupList(); MetadataLookupList list; MetadataFactory *factory = new MetadataFactory(NULL); if (factory) list = factory->SynchronousLookup(Title, Subtitle, Inetref, Season, Episode, GrabberType); if ( !list.size() ) return pVideoLookups; for( int n = 0; n < list.size(); n++ ) { DTC::VideoLookup *pVideoLookup = pVideoLookups->AddNewVideoLookup(); MetadataLookup *lookup = list[n]; if (lookup) { pVideoLookup->setTitle(lookup->GetTitle()); pVideoLookup->setSubTitle(lookup->GetSubtitle()); pVideoLookup->setSeason(lookup->GetSeason()); pVideoLookup->setEpisode(lookup->GetEpisode()); pVideoLookup->setYear(lookup->GetYear()); pVideoLookup->setTagline(lookup->GetTagline()); pVideoLookup->setDescription(lookup->GetDescription()); pVideoLookup->setCertification(lookup->GetCertification()); pVideoLookup->setInetref(lookup->GetInetref()); pVideoLookup->setHomePage(lookup->GetHomepage()); pVideoLookup->setReleaseDate(QDateTime(lookup->GetReleaseDate())); pVideoLookup->setUserRating(lookup->GetUserRating()); pVideoLookup->setLength(lookup->GetRuntime()); pVideoLookup->setLanguage(lookup->GetLanguage()); pVideoLookup->setCountries(lookup->GetCountries()); pVideoLookup->setPopularity(lookup->GetPopularity()); pVideoLookup->setBudget(lookup->GetBudget()); pVideoLookup->setRevenue(lookup->GetRevenue()); pVideoLookup->setIMDB(lookup->GetIMDB()); pVideoLookup->setTMSRef(lookup->GetTMSref()); ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart); ArtworkList::iterator c; for (c = coverartlist.begin(); c != coverartlist.end(); ++c) { DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork(); art->setType("coverart"); art->setUrl((*c).url); art->setThumbnail((*c).thumbnail); art->setWidth((*c).width); art->setHeight((*c).height); } ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart); ArtworkList::iterator f; for (f = fanartlist.begin(); f != fanartlist.end(); ++f) { DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork(); art->setType("fanart"); art->setUrl((*f).url); art->setThumbnail((*f).thumbnail); art->setWidth((*f).width); art->setHeight((*f).height); } ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner); ArtworkList::iterator b; for (b = bannerlist.begin(); b != bannerlist.end(); ++b) { DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork(); art->setType("banner"); art->setUrl((*b).url); art->setThumbnail((*b).thumbnail); art->setWidth((*b).width); art->setHeight((*b).height); } ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot); ArtworkList::iterator s; for (s = screenshotlist.begin(); s != screenshotlist.end(); ++s) { DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork(); art->setType("screenshot"); art->setUrl((*s).url); art->setThumbnail((*s).thumbnail); art->setWidth((*s).width); art->setHeight((*s).height); } delete lookup; } } pVideoLookups->setCount ( list.count() ); pVideoLookups->setAsOf ( QDateTime::currentDateTime() ); pVideoLookups->setVersion ( MYTH_BINARY_VERSION ); pVideoLookups->setProtoVer ( MYTH_PROTO_VERSION ); delete factory; return pVideoLookups; }