bool CMusicInfoScanner::DownloadAlbumInfo(const CStdString& strPath, const CStdString& strArtist, const CStdString& strAlbum, bool& bCanceled, CMusicAlbumInfo& albumInfo, CGUIDialogProgress* pDialog) { CAlbum album; VECSONGS songs; DIRECTORY::MUSICDATABASEDIRECTORY::CQueryParams params; DIRECTORY::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(strPath, params); bCanceled = false; m_musicDatabase.Open(); if (m_musicDatabase.HasAlbumInfo(params.GetAlbumId()) && m_musicDatabase.GetAlbumInfo(params.GetAlbumId(),album,&songs)) return true; // find album info SScraperInfo info; if (!m_musicDatabase.GetScraperForPath(strPath,info)) { m_musicDatabase.Close(); return false; } if (m_pObserver) { m_pObserver->OnStateChanged(DOWNLOADING_ALBUM_INFO); m_pObserver->OnDirectoryChanged(strAlbum); } CMusicInfoScraper scraper(info); // handle nfo files CStdString strAlbumPath, strNfo; m_musicDatabase.GetAlbumPath(params.GetAlbumId(),strAlbumPath); CUtil::AddFileToFolder(strAlbumPath,"album.nfo",strNfo); if (XFILE::CFile::Exists(strNfo)) { CLog::Log(LOGDEBUG,"Found matching nfo file: %s", strNfo.c_str()); CNfoFile nfoReader("albums"); if (nfoReader.Create(strNfo) == S_OK) { if (nfoReader.m_strScraper == "NFO") { CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__); CAlbum album; VECSONGS songs; nfoReader.GetDetails(album); m_musicDatabase.SetAlbumInfo(params.GetAlbumId(), album, songs); m_musicDatabase.Close(); return true; } else { CScraperUrl scrUrl(nfoReader.m_strImDbUrl); CMusicAlbumInfo album("nfo",scrUrl); scraper.GetAlbums().push_back(album); } } else CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str()); } if (!scraper.GetAlbumCount()) scraper.FindAlbuminfo(strAlbum, strArtist); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); break; } Sleep(1); } CGUIDialogSelect *pDlg=NULL; int iSelectedAlbum=0; if (scraper.Successfull() && scraper.GetAlbumCount() >= 1) { int bestMatch = 0; double bestRelevance = 0; double minRelevance = THRESHOLD; if (scraper.GetAlbumCount() > 1) // score the matches { //show dialog with all albums found if (pDialog) { pDlg = (CGUIDialogSelect*)m_gWindowManager.GetWindow(WINDOW_DIALOG_SELECT); pDlg->SetHeading(g_localizeStrings.Get(181).c_str()); pDlg->Reset(); pDlg->EnableButton(true); pDlg->SetButtonLabel(413); // manual } double secondBestRelevance = 0; for (int i = 0; i < scraper.GetAlbumCount(); ++i) { CMusicAlbumInfo& info = scraper.GetAlbum(i); double relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, strAlbum, info.GetAlbum().strArtist, strArtist); // if we're doing auto-selection (ie querying all albums at once, then allow 95->100% for perfect matches) // otherwise, perfect matches only if (relevance >= max(minRelevance, bestRelevance)) { // we auto-select the best of these secondBestRelevance = bestRelevance; bestRelevance = relevance; bestMatch = i; } if (pDialog) { // set the label to [relevance] album - artist CStdString strTemp; strTemp.Format("[%0.2f] %s", relevance, info.GetTitle2()); CFileItem item(strTemp); item.m_idepth = i; // use this to hold the index of the album in the scraper pDlg->Add(&item); } } } else { CMusicAlbumInfo& info = scraper.GetAlbum(0); double relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, strAlbum, info.GetAlbum().strArtist, strArtist); if (relevance < THRESHOLD) { m_musicDatabase.Close(); return false; } } iSelectedAlbum = bestMatch; if (pDialog && bestRelevance < THRESHOLD) { pDlg->Sort(false); pDlg->DoModal(); // and wait till user selects one if (pDlg->GetSelectedLabel() < 0) { // none chosen if (!pDlg->IsButtonPressed()) { bCanceled = true; return false; } // manual button pressed CStdString strNewAlbum = strAlbum; if (!CGUIDialogKeyboard::ShowAndGetInput(strNewAlbum, g_localizeStrings.Get(16011), false)) return false; if (strNewAlbum == "") return false; CStdString strNewArtist = strArtist; if (!CGUIDialogKeyboard::ShowAndGetInput(strNewArtist, g_localizeStrings.Get(16025), false)) return false; pDialog->SetLine(0, strNewAlbum); pDialog->SetLine(1, strNewArtist); pDialog->Progress(); m_musicDatabase.Close(); return DownloadAlbumInfo(strPath,strArtist,strAlbum,bCanceled,albumInfo,pDialog); } iSelectedAlbum = pDlg->GetSelectedItem().m_idepth; } } else { m_musicDatabase.Close(); return false; } scraper.LoadAlbuminfo(iSelectedAlbum); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); break; } Sleep(1); } if (scraper.Successfull()) { albumInfo = scraper.GetAlbum(iSelectedAlbum); album = scraper.GetAlbum(iSelectedAlbum).GetAlbum(); m_musicDatabase.SetAlbumInfo(params.GetAlbumId(), album, scraper.GetAlbum(iSelectedAlbum).GetSongs(),false); } else { m_musicDatabase.Close(); return false; } // check thumb stuff if (album.thumbURL.m_url.size()) { CStdString thumb; if (!m_musicDatabase.GetAlbumThumb(params.GetAlbumId(),thumb) || thumb.IsEmpty() || !XFILE::CFile::Exists(thumb)) { thumb = CUtil::GetCachedAlbumThumb(album.strAlbum,album.strArtist); CScraperUrl::DownloadThumbnail(thumb,album.thumbURL.m_url[0]); m_musicDatabase.SaveAlbumThumb(params.GetAlbumId(), thumb); } } m_musicDatabase.Close(); return true; }
bool CMetadataResolverMusic::GetMetadataFromAMG(const CStdString& _strAlbum, const CStdString& _strArtist,MUSIC_GRABBER::CMusicAlbumInfo& album) { CStdString strAlbum = _strAlbum; strAlbum = strAlbum.ToLower(); CStdString strArtist = _strArtist; strArtist = strArtist.ToLower(); // This function can resolve by album only, so we do not care about the artist at this point if (strAlbum.IsEmpty() || strArtist.IsEmpty()) return false; SScraperInfo info; info.strPath = "allmusic.xml"; info.strContent = "albums"; int iRetries = 2; while (iRetries-- > 0) { MUSIC_GRABBER::CMusicInfoScraper scraper(info); scraper.SetAlbum(strAlbum); scraper.SetArtist(strArtist); scraper.FindAlbuminfo(); scraper.LoadAlbuminfo(); int iSelectedAlbum = 0; while (!scraper.Completed() && !scraper.IsCanceled()) { if (m_bStopped) { if (!scraper.IsCanceled()) { //CLog::Log(LOGDEBUG, "LIBRARY: Boxee Metadata Resolver, Canceling scraper"); scraper.Cancel(); break; } } Sleep(200); } if (scraper.Successfull() && scraper.GetAlbumCount() > 0) { // did we found at least 1 album? int iAlbumCount = scraper.GetAlbumCount(); if (iAlbumCount >= 1) { if (iAlbumCount > 1) { int bestMatch = -1; double minRelevance; minRelevance = 0.7; double bestRelevance = 0; double secondBestRelevance = 0; for (int i = 0; i < iAlbumCount; ++i) { MUSIC_GRABBER::CMusicAlbumInfo& info = scraper.GetAlbum(i); CStdString strFoundAlbum = info.GetAlbum().strAlbum; strFoundAlbum.MakeLower(); CStdString strFoundArtist = info.GetAlbum().strArtist; strFoundArtist.MakeLower(); bool bFoundSoundtrack = false; if ((strFoundAlbum.Find("soundtrack") != -1) || (strFoundArtist.Find("soundtrack") != -1)) { bFoundSoundtrack = true; // reset found artist in order to avoid artist comparison strFoundArtist = ""; //strFoundAlbum = CleanAlbumName(strFoundAlbum); // check if we can remove the "[original soundtrack]" token int pos = strFoundAlbum.Find("[original soundtrack]"); if (pos != -1) { strFoundAlbum.erase(pos, 21); } else { // try to remove words separately int pos1 = strFoundAlbum.Find("soundtrack"); if (pos1 != -1) { strFoundAlbum.erase(pos1, 10); } int pos2 = strFoundAlbum.Find("original"); if (pos2 != -1) { strFoundAlbum.erase(pos2, 8); } } } // TODO: Check if originally we were looking for a soundtrack // Check if we need a sound track // if (pContext->bIsSoundtrack && !bFoundSoundtrack) // { // continue; // } double relevance = CUtil::AlbumRelevance(strFoundAlbum, strAlbum, strFoundArtist, strArtist); // if we're doing auto-selection (ie querying all albums at once, then allow 95->100% for perfect matches) // otherwise, perfect matches only if (relevance >= std::max(minRelevance, bestRelevance)) { // we auto-select the best of these secondBestRelevance = bestRelevance; bestRelevance = relevance; bestMatch = i; } } if (bestMatch > -1 && bestRelevance != secondBestRelevance) { // autochoose the single best matching item iSelectedAlbum = bestMatch; } else { // nothing found, or two equal matches to choose from // perform additional checks return false; } } } else { return false; } MUSIC_GRABBER::CMusicAlbumInfo info = scraper.GetAlbum(iSelectedAlbum); // Save album and artist names as they get erased in the process CStdString strTempAlbumName = info.GetAlbum().strAlbum; CStdString strTempArtistName = info.GetAlbum().strArtist; scraper.LoadAlbuminfo(iSelectedAlbum); while (!scraper.Completed() && !scraper.IsCanceled()) { // if (m_bStopped) // { // if (!scraper.IsCanceled()) { // scraper.Cancel(); // } // } Sleep(200); } if (!scraper.IsCanceled() && scraper.Successfull()) { album = scraper.GetAlbum(iSelectedAlbum); // Restore erased fields album.GetAlbum().strAlbum = strTempAlbumName; album.GetAlbum().strArtist = strTempArtistName; return true; } else { if (scraper.HadNetworkProblems()) { Sleep(500); continue; } return false; } } else { if (scraper.HadNetworkProblems()) { Sleep(500); continue; } return false; } } // while retries return false; }