void CGUIWindowMusicBase::ShowAlbumInfo(const CAlbum& album, const CStdString& path, bool bShowInfo /* = true */) { bool saveDb = album.idAlbum != -1; if (!CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() && !g_passwordManager.bMasterUser) saveDb = false; CMusicAlbumInfo albumInfo; while (1) { if (!m_musicdatabase.HasAlbumInfo(album.idAlbum) || !m_musicdatabase.GetAlbumInfo(album.idAlbum, albumInfo.GetAlbum(), &albumInfo.GetAlbum().songs)) { if (g_application.IsMusicScanning()) { CGUIDialogOK::ShowAndGetInput(189, 14057, 0, 0); break; } if (!FindAlbumInfo(album.strAlbum, StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator), albumInfo, bShowInfo ? SELECTION_ALLOWED : SELECTION_AUTO)) break; if (!albumInfo.Loaded()) { CGUIDialogOK::ShowAndGetInput(185, 0, 500, 0); break; } albumInfo.GetAlbum().strAlbum = album.strAlbum; if (saveDb) m_musicdatabase.SetAlbumInfo(album.idAlbum, albumInfo.GetAlbum(), albumInfo.GetSongs()); } CGUIDialogMusicInfo *pDlgAlbumInfo = (CGUIDialogMusicInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_INFO); if (pDlgAlbumInfo) { pDlgAlbumInfo->SetAlbum(albumInfo.GetAlbum(), path); pDlgAlbumInfo->DoModal(); if (pDlgAlbumInfo->NeedRefresh()) { m_musicdatabase.DeleteAlbumInfo(album.idAlbum); continue; } else if (pDlgAlbumInfo->HasUpdatedThumb()) { UpdateThumb(album, path); } } break; } if (m_dlgProgress) m_dlgProgress->Close(); }
bool CGUIWindowMusicBase::FindAlbumInfo(const CStdString& strAlbum, const CStdString& strArtist, CMusicAlbumInfo& album, const SScraperInfo& info, ALLOW_SELECTION allowSelection) { // quietly return if Internet lookups are disabled if (!g_guiSettings.GetBool("network.enableinternet")) return false; // show dialog box indicating we're searching the album if (m_dlgProgress && allowSelection != SELECTION_AUTO) { m_dlgProgress->SetHeading(185); m_dlgProgress->SetLine(0, strAlbum); m_dlgProgress->SetLine(1, strArtist); m_dlgProgress->SetLine(2, ""); m_dlgProgress->StartModal(); } CMusicInfoScanner scanner; CStdString strPath; CStdString strTempAlbum(strAlbum); CStdString strTempArtist(strArtist); long idAlbum = m_musicdatabase.GetAlbumByName(strAlbum,strArtist); strPath.Format("musicdb://3/%d/",idAlbum); bool bCanceled(false); bool needsRefresh(true); do { if (!scanner.DownloadAlbumInfo(strPath,strTempArtist,strTempAlbum,bCanceled,album,m_dlgProgress)) { if (m_dlgProgress && allowSelection != SELECTION_AUTO) { if (!CGUIDialogKeyboard::ShowAndGetInput(strTempAlbum, g_localizeStrings.Get(16011), false)) return false; if (!CGUIDialogKeyboard::ShowAndGetInput(strTempArtist, g_localizeStrings.Get(16025), false)) return false; } else needsRefresh = false; } else needsRefresh = false; } while (needsRefresh || bCanceled); // Read the album information from the database if we are dealing with a DB album. if (idAlbum != -1) m_musicdatabase.GetAlbumInfo(idAlbum,album.GetAlbum(),&album.GetAlbum().songs); album.SetLoaded(true); return true; }
INFO_RET CMusicInfoScanner::UpdateDatabaseAlbumInfo(CAlbum& album, const ADDON::ScraperPtr& scraper, bool bAllowSelection, CGUIDialogProgress* pDialog /* = NULL */) { if (!scraper) return INFO_ERROR; CMusicAlbumInfo albumInfo; loop: CLog::Log(LOGDEBUG, "%s downloading info for: %s", __FUNCTION__, album.strAlbum.c_str()); INFO_RET albumDownloadStatus = DownloadAlbumInfo(album, scraper, albumInfo, pDialog); if (albumDownloadStatus == INFO_NOT_FOUND) { if (pDialog && bAllowSelection) { if (!CGUIKeyboardFactory::ShowAndGetInput(album.strAlbum, CVariant{g_localizeStrings.Get(16011)}, false)) return INFO_CANCELLED; std::string strTempArtist(album.GetAlbumArtistString()); if (!CGUIKeyboardFactory::ShowAndGetInput(strTempArtist, CVariant{g_localizeStrings.Get(16025)}, false)) return INFO_CANCELLED; album.strArtistDesc = strTempArtist; goto loop; } else { CEventLog::GetInstance().Add(EventPtr(new CMediaLibraryEvent( MediaTypeAlbum, album.strPath, 24146, StringUtils::Format(g_localizeStrings.Get(24147).c_str(), MediaTypeAlbum, album.strAlbum.c_str()), CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb()), CURL::GetRedacted(album.strPath), EventLevel::Warning))); } } else if (albumDownloadStatus == INFO_ADDED) { bool overridetags = CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_OVERRIDETAGS); album.MergeScrapedAlbum(albumInfo.GetAlbum(), overridetags); m_musicDatabase.Open(); m_musicDatabase.UpdateAlbum(album, overridetags); GetAlbumArtwork(album.idAlbum, album); m_musicDatabase.Close(); albumInfo.SetLoaded(true); } return albumDownloadStatus; }
INFO_RET CMusicInfoScanner::UpdateDatabaseAlbumInfo(CAlbum& album, const ADDON::ScraperPtr& scraper, bool bAllowSelection, CGUIDialogProgress* pDialog /* = NULL */) { if (!scraper) return INFO_ERROR; CMusicAlbumInfo albumInfo; loop: CLog::Log(LOGDEBUG, "%s downloading info for: %s", __FUNCTION__, album.strAlbum.c_str()); INFO_RET albumDownloadStatus = DownloadAlbumInfo(album, scraper, albumInfo, pDialog); if (albumDownloadStatus == INFO_NOT_FOUND) { if (pDialog && bAllowSelection) { if (!CGUIKeyboardFactory::ShowAndGetInput(album.strAlbum, g_localizeStrings.Get(16011), false)) return INFO_CANCELLED; std::string strTempArtist(StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator)); if (!CGUIKeyboardFactory::ShowAndGetInput(strTempArtist, g_localizeStrings.Get(16025), false)) return INFO_CANCELLED; album.artist = StringUtils::Split(strTempArtist, g_advancedSettings.m_musicItemSeparator); goto loop; } } else if (albumDownloadStatus == INFO_ADDED) { album.MergeScrapedAlbum(albumInfo.GetAlbum(), CSettings::Get().GetBool("musiclibrary.overridetags")); m_musicDatabase.Open(); m_musicDatabase.UpdateAlbum(album); GetAlbumArtwork(album.idAlbum, album); m_musicDatabase.Close(); albumInfo.SetLoaded(true); } return albumDownloadStatus; }
void CGUIWindowMusicBase::ShowAlbumInfo(const CAlbum& album, const CStdString& path, bool bRefresh, bool bShowInfo) { bool saveDb = album.idAlbum != -1; if (!g_settings.GetCurrentProfile().canWriteDatabases() && !g_passwordManager.bMasterUser) saveDb = false; // check cache CAlbum albumInfo; if (!bRefresh && m_musicdatabase.GetAlbumInfo(album.idAlbum, albumInfo, &albumInfo.songs)) { if (!bShowInfo) return; CGUIDialogMusicInfo *pDlgAlbumInfo = (CGUIDialogMusicInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_INFO); if (pDlgAlbumInfo) { pDlgAlbumInfo->SetAlbum(albumInfo, path); if (bShowInfo) pDlgAlbumInfo->DoModal(); if (!pDlgAlbumInfo->NeedRefresh()) { if (pDlgAlbumInfo->HasUpdatedThumb()) UpdateThumb(albumInfo, path); return; } bRefresh = true; m_musicdatabase.DeleteAlbumInfo(albumInfo.idAlbum); } } // If we are scanning for music info in the background, // other writing access to the database is prohibited. if (g_application.IsMusicScanning()) { CGUIDialogOK::ShowAndGetInput(189, 14057, 0, 0); return; } CMusicAlbumInfo info; if (FindAlbumInfo(album.strAlbum, StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator), info, bShowInfo ? (bRefresh ? SELECTION_FORCED : SELECTION_ALLOWED) : SELECTION_AUTO)) { // download the album info if ( info.Loaded() ) { // set album title from musicinfotag, not the one we got from allmusic.com info.SetTitle(album.strAlbum); if (saveDb) { // save to database m_musicdatabase.SetAlbumInfo(album.idAlbum, info.GetAlbum(), info.GetSongs()); } if (m_dlgProgress && bShowInfo) m_dlgProgress->Close(); UpdateThumb(album, path); // ok, show album info CGUIDialogMusicInfo *pDlgAlbumInfo = (CGUIDialogMusicInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_INFO); if (pDlgAlbumInfo) { pDlgAlbumInfo->SetAlbum(info.GetAlbum(), path); if (bShowInfo) pDlgAlbumInfo->DoModal(); CAlbum albumInfo = info.GetAlbum(); albumInfo.idAlbum = album.idAlbum; if (pDlgAlbumInfo->HasUpdatedThumb()) UpdateThumb(albumInfo, path); if (pDlgAlbumInfo->NeedRefresh()) { m_musicdatabase.DeleteAlbumInfo(albumInfo.idAlbum); ShowAlbumInfo(album, path, true, bShowInfo); return; } } } else { // failed 2 download album info CGUIDialogOK::ShowAndGetInput(185, 0, 500, 0); } } if (m_dlgProgress && bShowInfo) m_dlgProgress->Close(); }
INFO_RET CMusicInfoScanner::DownloadAlbumInfo(const CAlbum& album, const ADDON::ScraperPtr& info, CMusicAlbumInfo& albumInfo, CGUIDialogProgress* pDialog) { if (m_handle) { m_handle->SetTitle(StringUtils::Format(g_localizeStrings.Get(20321).c_str(), info->Name().c_str())); m_handle->SetText(StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator) + " - " + album.strAlbum); } // clear our scraper cache info->ClearCache(); CMusicInfoScraper scraper(info); bool bMusicBrainz = false; if (!album.strMusicBrainzAlbumID.empty()) { CScraperUrl musicBrainzURL; if (ResolveMusicBrainz(album.strMusicBrainzAlbumID, info, musicBrainzURL)) { CMusicAlbumInfo albumNfo("nfo", musicBrainzURL); scraper.GetAlbums().clear(); scraper.GetAlbums().push_back(albumNfo); bMusicBrainz = true; } } // handle nfo files std::string path = album.strPath; if (path.empty()) m_musicDatabase.GetAlbumPath(album.idAlbum, path); std::string strNfo = URIUtils::AddFileToFolder(path, "album.nfo"); CNfoFile::NFOResult result = CNfoFile::NO_NFO; CNfoFile nfoReader; if (XFILE::CFile::Exists(strNfo)) { CLog::Log(LOGDEBUG,"Found matching nfo file: %s", strNfo.c_str()); result = nfoReader.Create(strNfo, info); if (result == CNfoFile::FULL_NFO) { CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__); nfoReader.GetDetails(albumInfo.GetAlbum()); return INFO_ADDED; } else if (result == CNfoFile::URL_NFO || result == CNfoFile::COMBINED_NFO) { CScraperUrl scrUrl(nfoReader.ScraperUrl()); CMusicAlbumInfo albumNfo("nfo",scrUrl); ADDON::ScraperPtr nfoReaderScraper = nfoReader.GetScraperInfo(); CLog::Log(LOGDEBUG,"-- nfo-scraper: %s", nfoReaderScraper->Name().c_str()); CLog::Log(LOGDEBUG,"-- nfo url: %s", scrUrl.m_url[0].m_url.c_str()); scraper.SetScraperInfo(nfoReaderScraper); scraper.GetAlbums().clear(); scraper.GetAlbums().push_back(albumNfo); } else CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str()); } if (!scraper.CheckValidOrFallback(CSettings::Get().GetString("musiclibrary.albumsscraper"))) { // the current scraper is invalid, as is the default - bail CLog::Log(LOGERROR, "%s - current and default scrapers are invalid. Pick another one", __FUNCTION__); return INFO_ERROR; } if (!scraper.GetAlbumCount()) { scraper.FindAlbumInfo(album.strAlbum, StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator)); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); return INFO_CANCELLED; } Sleep(1); } } CGUIDialogSelect *pDlg = NULL; int iSelectedAlbum=0; if (result == CNfoFile::NO_NFO && !bMusicBrainz) { iSelectedAlbum = -1; // set negative so that we can detect a failure if (scraper.Succeeded() && scraper.GetAlbumCount() >= 1) { double bestRelevance = 0; double minRelevance = THRESHOLD; if (scraper.GetAlbumCount() > 1) // score the matches { //show dialog with all albums found if (pDialog) { pDlg = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); pDlg->SetHeading(g_localizeStrings.Get(181).c_str()); pDlg->Reset(); pDlg->EnableButton(true, 413); // manual } for (int i = 0; i < scraper.GetAlbumCount(); ++i) { CMusicAlbumInfo& info = scraper.GetAlbum(i); double relevance = info.GetRelevance(); if (relevance < 0) relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, album.strAlbum, StringUtils::Join(info.GetAlbum().artist, g_advancedSettings.m_musicItemSeparator), StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator)); // 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 bestRelevance = relevance; iSelectedAlbum = i; } if (pDialog) { // set the label to [relevance] album - artist std::string strTemp = StringUtils::Format("[%0.2f] %s", relevance, info.GetTitle2().c_str()); CFileItem item(strTemp); item.m_idepth = i; // use this to hold the index of the album in the scraper pDlg->Add(&item); } if (relevance > .99f) // we're so close, no reason to search further break; } if (pDialog && bestRelevance < THRESHOLD) { pDlg->Sort(false); pDlg->DoModal(); // and wait till user selects one if (pDlg->GetSelectedLabel() < 0) { // none chosen if (!pDlg->IsButtonPressed()) return INFO_CANCELLED; // manual button pressed std::string strNewAlbum = album.strAlbum; if (!CGUIKeyboardFactory::ShowAndGetInput(strNewAlbum, g_localizeStrings.Get(16011), false)) return INFO_CANCELLED; if (strNewAlbum == "") return INFO_CANCELLED; std::string strNewArtist = StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator); if (!CGUIKeyboardFactory::ShowAndGetInput(strNewArtist, g_localizeStrings.Get(16025), false)) return INFO_CANCELLED; pDialog->SetLine(0, strNewAlbum); pDialog->SetLine(1, strNewArtist); pDialog->Progress(); CAlbum newAlbum = album; newAlbum.strAlbum = strNewAlbum; newAlbum.artist = StringUtils::Split(strNewArtist, g_advancedSettings.m_musicItemSeparator); return DownloadAlbumInfo(newAlbum, info, albumInfo, pDialog); } iSelectedAlbum = pDlg->GetSelectedItem()->m_idepth; } } else { CMusicAlbumInfo& info = scraper.GetAlbum(0); double relevance = info.GetRelevance(); if (relevance < 0) relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, album.strAlbum, StringUtils::Join(info.GetAlbum().artist, g_advancedSettings.m_musicItemSeparator), StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator)); if (relevance < THRESHOLD) return INFO_NOT_FOUND; iSelectedAlbum = 0; } } if (iSelectedAlbum < 0) return INFO_NOT_FOUND; } scraper.LoadAlbumInfo(iSelectedAlbum); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); return INFO_CANCELLED; } Sleep(1); } if (!scraper.Succeeded()) return INFO_ERROR; albumInfo = scraper.GetAlbum(iSelectedAlbum); if (result == CNfoFile::COMBINED_NFO) nfoReader.GetDetails(albumInfo.GetAlbum(), NULL, true); return INFO_ADDED; }
bool CGUIWindowMusicBase::ShowAlbumInfo(const CFileItem *pItem, bool bShowInfo /* = true */) { CQueryParams params; CDirectoryNode::GetDatabaseInfo(pItem->GetPath(), params); CMusicAlbumInfo albumInfo; while (1) { if (!m_musicdatabase.HasAlbumInfo(params.GetAlbumId()) || !m_musicdatabase.GetAlbumInfo(params.GetAlbumId(), albumInfo.GetAlbum(), &albumInfo.GetAlbum().songs)) { if (!CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() && !g_passwordManager.bMasterUser) { // TODO: should display a dialog saying no permissions if (m_dlgProgress) m_dlgProgress->Close(); return false; } if (g_application.IsMusicScanning()) { CGUIDialogOK::ShowAndGetInput(189, 14057, 0, 0); if (m_dlgProgress) m_dlgProgress->Close(); return false; } // show dialog box indicating we're searching the album if (m_dlgProgress && bShowInfo) { m_dlgProgress->SetHeading(185); m_dlgProgress->SetLine(0, pItem->GetMusicInfoTag()->GetAlbum()); m_dlgProgress->SetLine(1, StringUtils::Join(pItem->GetMusicInfoTag()->GetAlbumArtist(), g_advancedSettings.m_musicItemSeparator)); m_dlgProgress->SetLine(2, ""); m_dlgProgress->StartModal(); } CMusicInfoScanner scanner; if (scanner.UpdateDatabaseAlbumInfo(pItem->GetPath(), albumInfo, bShowInfo) != INFO_ADDED || !albumInfo.Loaded()) { CGUIDialogOK::ShowAndGetInput(185, 0, 500, 0); if (m_dlgProgress) m_dlgProgress->Close(); return false; } } if (m_dlgProgress) m_dlgProgress->Close(); CGUIDialogMusicInfo *pDlgAlbumInfo = (CGUIDialogMusicInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_INFO); if (pDlgAlbumInfo) { CStdString strPath; m_musicdatabase.GetAlbumPath(params.GetAlbumId(), strPath); pDlgAlbumInfo->SetAlbum(albumInfo.GetAlbum(), strPath); pDlgAlbumInfo->DoModal(); if (pDlgAlbumInfo->NeedRefresh()) { m_musicdatabase.DeleteAlbumInfo(params.GetAlbumId()); continue; } else if (pDlgAlbumInfo->HasUpdatedThumb()) { UpdateThumb(albumInfo.GetAlbum(), strPath); } } break; } if (m_dlgProgress) m_dlgProgress->Close(); return true; }
void CGUIWindowMusicBase::ShowAlbumInfo(const CAlbum& album, const CStdString& path, bool bRefresh, bool bShowInfo) { bool saveDb = album.idAlbum != -1; if (!g_settings.m_vecProfiles[g_settings.m_iLastLoadedProfileIndex].canWriteDatabases() && !g_passwordManager.bMasterUser) saveDb = false; // check cache CAlbum albumInfo; if (!bRefresh && m_musicdatabase.GetAlbumInfo(album.idAlbum, albumInfo, &albumInfo.songs)) { if (!bShowInfo) return; CGUIWindowMusicInfo *pDlgAlbumInfo = (CGUIWindowMusicInfo*)m_gWindowManager.GetWindow(WINDOW_MUSIC_INFO); if (pDlgAlbumInfo) { pDlgAlbumInfo->SetAlbum(albumInfo, path); if (bShowInfo) pDlgAlbumInfo->DoModal(); else pDlgAlbumInfo->RefreshThumb(); // downloads the thumb if we don't already have one if (!pDlgAlbumInfo->NeedRefresh()) { if (pDlgAlbumInfo->HasUpdatedThumb()) UpdateThumb(albumInfo, path); return; } bRefresh = true; m_musicdatabase.DeleteAlbumInfo(albumInfo.idAlbum); } } // If we are scanning for music info in the background, // other writing access to the database is prohibited. CGUIDialogMusicScan* dlgMusicScan = (CGUIDialogMusicScan*)m_gWindowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN); if (dlgMusicScan->IsDialogRunning()) { CGUIDialogOK::ShowAndGetInput(189, 14057, 0, 0); return; } // find album info SScraperInfo scraper; if (!m_musicdatabase.GetScraperForPath(path,scraper)) return; CMusicAlbumInfo info; if (FindAlbumInfo(album.strAlbum, album.strArtist, info, scraper, bShowInfo ? (bRefresh ? SELECTION_FORCED : SELECTION_ALLOWED) : SELECTION_AUTO)) { // download the album info if ( info.Loaded() ) { // set album title from musicinfotag, not the one we got from allmusic.com info.SetTitle(album.strAlbum); UpdateThumb(album, path); if (saveDb) { // save to database m_musicdatabase.SetAlbumInfo(album.idAlbum, info.GetAlbum(), info.GetSongs()); } if (m_dlgProgress && bShowInfo) m_dlgProgress->Close(); // ok, show album info CGUIWindowMusicInfo *pDlgAlbumInfo = (CGUIWindowMusicInfo*)m_gWindowManager.GetWindow(WINDOW_MUSIC_INFO); if (pDlgAlbumInfo) { pDlgAlbumInfo->SetAlbum(info.GetAlbum(), path); if (bShowInfo) pDlgAlbumInfo->DoModal(); else pDlgAlbumInfo->RefreshThumb(); // downloads the thumb if we don't already have one CAlbum albumInfo = info.GetAlbum(); albumInfo.idAlbum = album.idAlbum; if (pDlgAlbumInfo->HasUpdatedThumb()) UpdateThumb(albumInfo, path); if (pDlgAlbumInfo->NeedRefresh()) { m_musicdatabase.DeleteAlbumInfo(albumInfo.idAlbum); ShowAlbumInfo(album, path, true, bShowInfo); return; } } } else { // failed 2 download album info CGUIDialogOK::ShowAndGetInput(185, 0, 500, 0); } } if (m_dlgProgress && bShowInfo) m_dlgProgress->Close(); }