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 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 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 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(); }
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(); }