int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/) { CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (!dialog) return 0; CFileItemList items; CStdString heading; int iTypes = 0; for (vector<ADDON::TYPE>::const_iterator it = types.begin(); it != types.end(); ++it) { if (*it == ADDON_UNKNOWN) continue; ADDON::VECADDONS addons; iTypes++; if (*it == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio",addons); else if (*it == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable",addons); else if (*it == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image",addons); else if (*it == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video",addons); else CAddonMgr::Get().GetAddons(*it, addons); for (ADDON::IVECADDONS it2 = addons.begin() ; it2 != addons.end() ; ++it2) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*it2, "")); if (!items.Contains(item->GetPath())) items.Add(item); } if (!heading.empty()) heading += ", "; heading += TranslateType(*it, true); } if (iTypes == 0) return 0; dialog->SetHeading(heading); dialog->Reset(); dialog->SetUseDetails(true); if (multipleSelection) showNone = false; if (multipleSelection || iTypes > 1) dialog->EnableButton(true, 186); else dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SortByLabel, SortOrderAscending); if (addonIDs.size() > 0) { for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); if (!multipleSelection && iTypes == 1 && dialog->IsButtonPressed()) { // switch to the addons browser. vector<CStdString> params; params.push_back("addons://all/"+TranslateType(types[0],false)+"/"); params.push_back("return"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); return 2; } if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0 ; i < list.Size() ; i++) addonIDs.push_back(list.Get(i)->GetPath()); return 1; }
int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, vector<string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) { // if we shouldn't show neither installed nor installable addons the list will be empty if (!showInstalled && !showInstallable) return 0; // can't show the "Get More" button if we already show installable addons if (showInstallable) showMore = false; CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (!dialog) return 0; // get rid of any invalid addon types vector<ADDON::TYPE> validTypes(types.size()); std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; }); if (validTypes.empty()) return 0; // get all addons to show VECADDONS addons; if (showInstalled) { for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { VECADDONS typeAddons; if (*type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons); else if (*type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons); else if (*type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons); else if (*type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons); else CAddonMgr::Get().GetAddons(*type, typeAddons); addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } } if (showInstallable || showMore) { VECADDONS installableAddons; CAddonDatabase database; if (database.Open() && database.GetAddons(installableAddons)) { for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();) { AddonPtr pAddon = *addon; // check if the addon matches one of the provided addon types bool matchesType = false; for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (pAddon->IsType(*type)) { matchesType = true; break; } } // only show addons that match one of the provided addon types and that aren't disabled if (matchesType && !CAddonMgr::Get().IsAddonDisabled(pAddon->ID())) { // check if the addon is installed bool isInstalled = CAddonMgr::Get().IsAddonInstalled(pAddon->ID()); // check if the addon is installed or can be installed if ((showInstallable || showMore) && !isInstalled && CAddonMgr::Get().CanAddonBeInstalled(pAddon)) { ++addon; continue; } } addon = installableAddons.erase(addon); } if (showInstallable) addons.insert(addons.end(), installableAddons.begin(), installableAddons.end()); else if (showMore) showMore = !installableAddons.empty(); } } if (addons.empty() && !showNone) return 0; // turn the addons into items std::map<std::string, AddonPtr> addonMap; CFileItemList items; for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, (*addon)->ID())); if (!items.Contains(item->GetPath())) { items.Add(item); addonMap.insert(std::make_pair(item->GetPath(), *addon)); } } if (items.IsEmpty() && !showNone) return 0; std::string heading; for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (!heading.empty()) heading += ", "; heading += TranslateType(*type, true); } dialog->SetHeading(CVariant{std::move(heading)}); dialog->Reset(); dialog->SetUseDetails(showDetails); if (multipleSelection) { showNone = false; showMore = false; dialog->EnableButton(true, 186); } else if (showMore) dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SortByLabel, SortOrderAscending); if (addonIDs.size() > 0) { for (vector<string>::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); // if the "Get More" button has been pressed and we haven't shown the // installable addons so far show a list of installable addons if (showMore&& dialog->IsButtonPressed()) return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false); if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0; i < list.Size(); i++) { const CFileItemPtr& item = list.Get(i); // check if one of the selected addons needs to be installed if (showInstallable) { std::map<std::string, AddonPtr>::const_iterator itAddon = addonMap.find(item->GetPath()); if (itAddon != addonMap.end()) { const AddonPtr& addon = itAddon->second; // if the addon isn't installed we need to install it if (!CAddonMgr::Get().IsAddonInstalled(addon->ID())) { AddonPtr installedAddon; if (!CAddonInstaller::Get().InstallModal(addon->ID(), installedAddon, false)) continue; } // if the addon is disabled we need to enable it if (CAddonMgr::Get().IsAddonDisabled(addon->ID())) CAddonMgr::Get().EnableAddon(addon->ID()); } } addonIDs.push_back(item->GetPath()); } return 1; }
int CGUIWindowAddonBrowser::SelectAddonID(ADDON::TYPE type, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/) { CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (type == ADDON_UNKNOWN || !dialog) return 0; ADDON::VECADDONS addons; if (type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio",addons); else if (type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable",addons); else if (type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image",addons); else if (type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video",addons); else CAddonMgr::Get().GetAddons(type, addons); CFileItemList items; for (ADDON::IVECADDONS i = addons.begin(); i != addons.end(); ++i) items.Add(CAddonsDirectory::FileItemFromAddon(*i, "")); dialog->SetHeading(TranslateType(type, true)); dialog->Reset(); dialog->SetUseDetails(true); if (multipleSelection) { showNone = false; dialog->EnableButton(true, 186); } else dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SORT_ON_TOP); items.Add(item); } items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); if (addonIDs.size() > 0) { for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); if (!multipleSelection && dialog->IsButtonPressed()) { // switch to the addons browser. vector<CStdString> params; params.push_back("addons://all/"+TranslateType(type,false)+"/"); params.push_back("return"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); return 2; } if (!multipleSelection && dialog->GetSelectedLabel() == -1) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0 ; i < list.Size() ; i++) addonIDs.push_back(list.Get(i)->GetPath()); return 1; }
INFO_RET CMusicInfoScanner::DownloadArtistInfo(const CArtist& artist, const ADDON::ScraperPtr& info, MUSIC_GRABBER::CMusicArtistInfo& artistInfo, CGUIDialogProgress* pDialog) { if (m_handle) { m_handle->SetTitle(StringUtils::Format(g_localizeStrings.Get(20320).c_str(), info->Name().c_str())); m_handle->SetText(artist.strArtist); } // clear our scraper cache info->ClearCache(); CMusicInfoScraper scraper(info); bool bMusicBrainz = false; if (!artist.strMusicBrainzArtistID.empty()) { CScraperUrl musicBrainzURL; if (ResolveMusicBrainz(artist.strMusicBrainzArtistID, info, musicBrainzURL)) { CMusicArtistInfo artistNfo("nfo", musicBrainzURL); scraper.GetArtists().clear(); scraper.GetArtists().push_back(artistNfo); bMusicBrainz = true; } } // handle nfo files std::string path = artist.strPath; if (path.empty()) m_musicDatabase.GetArtistPath(artist.idArtist, path); std::string strNfo = URIUtils::AddFileToFolder(path, "artist.nfo"); CNfoFile::NFOResult result=CNfoFile::NO_NFO; CNfoFile nfoReader; if (XFILE::CFile::Exists(strNfo)) { CLog::Log(LOGDEBUG,"Found matching nfo file: %s", CURL::GetRedacted(strNfo).c_str()); result = nfoReader.Create(strNfo, info); if (result == CNfoFile::FULL_NFO) { CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__); nfoReader.GetDetails(artistInfo.GetArtist()); return INFO_ADDED; } else if (result == CNfoFile::URL_NFO || result == CNfoFile::COMBINED_NFO) { CScraperUrl scrUrl(nfoReader.ScraperUrl()); CMusicArtistInfo artistNfo("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.GetArtists().push_back(artistNfo); } else CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str()); } if (!scraper.GetArtistCount()) { scraper.FindArtistInfo(artist.strArtist); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); return INFO_CANCELLED; } Sleep(1); } } int iSelectedArtist = 0; if (result == CNfoFile::NO_NFO && !bMusicBrainz) { if (scraper.GetArtistCount() >= 1) { // now load the first match if (pDialog && scraper.GetArtistCount() > 1) { // if we found more then 1 album, let user choose one CGUIDialogSelect *pDlg = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); if (pDlg) { pDlg->SetHeading(CVariant{g_localizeStrings.Get(21890)}); pDlg->Reset(); pDlg->EnableButton(true, 413); // manual for (int i = 0; i < scraper.GetArtistCount(); ++i) { // set the label to artist CFileItem item(scraper.GetArtist(i).GetArtist()); std::string strTemp=scraper.GetArtist(i).GetArtist().strArtist; if (!scraper.GetArtist(i).GetArtist().strBorn.empty()) strTemp += " ("+scraper.GetArtist(i).GetArtist().strBorn+")"; if (!scraper.GetArtist(i).GetArtist().genre.empty()) { std::string genres = StringUtils::Join(scraper.GetArtist(i).GetArtist().genre, g_advancedSettings.m_musicItemSeparator); if (!genres.empty()) strTemp = StringUtils::Format("[%s] %s", genres.c_str(), strTemp.c_str()); } item.SetLabel(strTemp); item.m_idepth = i; // use this to hold the index of the album in the scraper pDlg->Add(item); } pDlg->Open(); // and wait till user selects one if (pDlg->GetSelectedItem() < 0) { // none chosen if (!pDlg->IsButtonPressed()) return INFO_CANCELLED; // manual button pressed std::string strNewArtist = artist.strArtist; if (!CGUIKeyboardFactory::ShowAndGetInput(strNewArtist, CVariant{g_localizeStrings.Get(16025)}, false)) return INFO_CANCELLED; if (pDialog) { pDialog->SetLine(0, CVariant{strNewArtist}); pDialog->Progress(); } CArtist newArtist; newArtist.strArtist = strNewArtist; return DownloadArtistInfo(newArtist, info, artistInfo, pDialog); } iSelectedArtist = pDlg->GetSelectedFileItem()->m_idepth; } } } else return INFO_NOT_FOUND; } scraper.LoadArtistInfo(iSelectedArtist, artist.strArtist); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); return INFO_CANCELLED; } Sleep(1); } if (!scraper.Succeeded()) return INFO_ERROR; artistInfo = scraper.GetArtist(iSelectedArtist); if (result == CNfoFile::COMBINED_NFO) nfoReader.GetDetails(artistInfo.GetArtist(), NULL, true); return INFO_ADDED; }
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(album.GetAlbumArtistString() + " - " + 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", CURL::GetRedacted(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 if (result != CNfoFile::PARTIAL_NFO) CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str()); } if (!scraper.CheckValidOrFallback(CServiceBroker::GetSettings().GetString(CSettings::SETTING_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, album.GetAlbumArtistString()); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); return INFO_CANCELLED; } Sleep(1); } } CGUIDialogSelect *pDlg = NULL; int iSelectedAlbum=0; if ((result == CNfoFile::NO_NFO || result == CNfoFile::PARTIAL_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 = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); pDlg->SetHeading(CVariant{g_localizeStrings.Get(181)}); 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, info.GetAlbum().GetAlbumArtistString(), album.GetAlbumArtistString()); // 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 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->Open(); // and wait till user selects one if (pDlg->GetSelectedItem() < 0) { // none chosen if (!pDlg->IsButtonPressed()) return INFO_CANCELLED; // manual button pressed std::string strNewAlbum = album.strAlbum; if (!CGUIKeyboardFactory::ShowAndGetInput(strNewAlbum, CVariant{g_localizeStrings.Get(16011)}, false)) return INFO_CANCELLED; if (strNewAlbum == "") return INFO_CANCELLED; std::string strNewArtist = album.GetAlbumArtistString(); if (!CGUIKeyboardFactory::ShowAndGetInput(strNewArtist, CVariant{g_localizeStrings.Get(16025)}, false)) return INFO_CANCELLED; pDialog->SetLine(0, CVariant{strNewAlbum}); pDialog->SetLine(1, CVariant{strNewArtist}); pDialog->Progress(); CAlbum newAlbum = album; newAlbum.strAlbum = strNewAlbum; newAlbum.strArtistDesc = strNewArtist; return DownloadAlbumInfo(newAlbum, info, albumInfo, pDialog); } iSelectedAlbum = pDlg->GetSelectedFileItem()->m_idepth; } } else { CMusicAlbumInfo& info = scraper.GetAlbum(0); double relevance = info.GetRelevance(); if (relevance < 0) relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, album.strAlbum, info.GetAlbum().GetAlbumArtistString(), album.GetAlbumArtistString()); 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 || result == CNfoFile::PARTIAL_NFO) nfoReader.GetDetails(albumInfo.GetAlbum(), NULL, true); return INFO_ADDED; }
bool CWeather::GetSearchResults(const CStdString &strSearch, CStdString &strResult) { // Check to see if the user entered a weather.com code if (strSearch.size() == 8) { strResult = ""; int i = 0; for (i = 0; i < 4; ++i) { strResult += toupper(strSearch[i]); if (!isalpha(strSearch[i])) break; } if (i == 4) { for ( ; i < 8; ++i) { strResult += strSearch[i]; if (!isdigit(strSearch[i])) break; } if (i == 8) { return true; // match } } // no match, wipe string strResult = ""; } CGUIDialogSelect *pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); CGUIDialogProgress *pDlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); //do the download CStdString strURL; CStdString strXML; XFILE::CFileCurl httpUtil; if (pDlgProgress) { pDlgProgress->SetHeading(410); //"Accessing Weather.com" pDlgProgress->SetLine(0, 194); //"Searching" pDlgProgress->SetLine(1, strSearch); pDlgProgress->SetLine(2, ""); pDlgProgress->StartModal(); pDlgProgress->Progress(); } strURL.Format("http://xoap.weather.com/search/search?where=%s", strSearch); if (!httpUtil.Get(strURL, strXML)) { if (pDlgProgress) pDlgProgress->Close(); return false; } //some select dialog init stuff if (!pDlgSelect) { if (pDlgProgress) pDlgProgress->Close(); return false; } pDlgSelect->SetHeading(396); //"Select Location" pDlgSelect->Reset(); /////////////////////////////// // load the xml file /////////////////////////////// TiXmlDocument xmlDoc; xmlDoc.Parse(strXML.c_str()); if (xmlDoc.Error()) return false; TiXmlElement *pRootElement = xmlDoc.RootElement(); if (pRootElement) { CStdString strItemTmp; TiXmlElement *pElement = pRootElement->FirstChildElement("loc"); while (pElement) { if (!pElement->NoChildren()) { strItemTmp.Format("%s - %s", pElement->Attribute("id"), pElement->FirstChild()->Value()); pDlgSelect->Add(strItemTmp); } pElement = pElement->NextSiblingElement("loc"); } } if (pDlgProgress) pDlgProgress->Close(); pDlgSelect->EnableButton(true, 222); //'Cancel' button returns to weather settings pDlgSelect->DoModal(); if (pDlgSelect->GetSelectedLabel() < 0) { if (pDlgSelect->IsButtonPressed()) { pDlgSelect->Close(); //close the select dialog and return to weather settings return true; } } //copy the selected code into the settings if (pDlgSelect->GetSelectedLabel() >= 0) strResult = pDlgSelect->GetSelectedLabelText(); if (pDlgProgress) pDlgProgress->Close(); return true; }
bool CMusicInfoScanner::DownloadArtistInfo(const CStdString& strPath, const CStdString& strArtist, bool& bCanceled, CGUIDialogProgress* pDialog) { XFILE::MUSICDATABASEDIRECTORY::CQueryParams params; XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(strPath, params); bCanceled = false; CArtist artist; m_musicDatabase.Open(); if (m_musicDatabase.GetArtistInfo(params.GetArtistId(),artist)) // already got the info return true; // find artist info ADDON::ScraperPtr info; if (!m_musicDatabase.GetScraperForPath(strPath, info, ADDON::ADDON_SCRAPER_ARTISTS) || !info) { m_musicDatabase.Close(); return false; } // clear our scraper cache info->ClearCache(); if (m_pObserver) { m_pObserver->OnStateChanged(DOWNLOADING_ARTIST_INFO); m_pObserver->OnDirectoryChanged(strArtist); } CMusicInfoScraper scraper(info); // handle nfo files CStdString strArtistPath, strNfo; m_musicDatabase.GetArtistPath(params.GetArtistId(),strArtistPath); URIUtils::AddFileToFolder(strArtistPath,"artist.nfo",strNfo); 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__); CArtist artist; nfoReader.GetDetails(artist); m_musicDatabase.SetArtistInfo(params.GetArtistId(), artist); GetArtistArtwork(params.GetArtistId(), strArtist, &artist); m_musicDatabase.Close(); return true; } else if (result == CNfoFile::URL_NFO || result == CNfoFile::COMBINED_NFO) { CScraperUrl scrUrl(nfoReader.ScraperUrl()); CMusicArtistInfo artist("nfo",scrUrl); info = nfoReader.GetScraperInfo(); CLog::Log(LOGDEBUG,"-- nfo-scraper: %s",info->Name().c_str()); CLog::Log(LOGDEBUG,"-- nfo url: %s", scrUrl.m_url[0].m_url.c_str()); scraper.SetScraperInfo(info); scraper.GetArtists().push_back(artist); } else CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str()); } if (!scraper.GetArtistCount()) scraper.FindArtistInfo(strArtist); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); bCanceled = true; } Sleep(1); } int iSelectedArtist = 0; if (result == CNfoFile::NO_NFO) { if (scraper.Succeeded() && scraper.GetArtistCount() >= 1) { // now load the first match if (pDialog && scraper.GetArtistCount() > 1) { // if we found more then 1 album, let user choose one CGUIDialogSelect *pDlg = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (pDlg) { pDlg->SetHeading(g_localizeStrings.Get(21890)); pDlg->Reset(); pDlg->EnableButton(true, 413); // manual for (int i = 0; i < scraper.GetArtistCount(); ++i) { // set the label to artist CFileItem item(scraper.GetArtist(i).GetArtist()); CStdString strTemp=scraper.GetArtist(i).GetArtist().strArtist; if (!scraper.GetArtist(i).GetArtist().strBorn.IsEmpty()) strTemp += " ("+scraper.GetArtist(i).GetArtist().strBorn+")"; if (!scraper.GetArtist(i).GetArtist().strGenre.IsEmpty()) strTemp.Format("[%s] %s",scraper.GetArtist(i).GetArtist().strGenre.c_str(),strTemp.c_str()); item.SetLabel(strTemp); item.m_idepth = i; // use this to hold the index of the album in the scraper pDlg->Add(&item); } 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 strNewArtist = strArtist; if (!CGUIDialogKeyboard::ShowAndGetInput(strNewArtist, g_localizeStrings.Get(16025), false)) return false; if (pDialog) { pDialog->SetLine(0, strNewArtist); pDialog->Progress(); } m_musicDatabase.Close(); return DownloadArtistInfo(strPath,strNewArtist,bCanceled,pDialog); } iSelectedArtist = pDlg->GetSelectedItem().m_idepth; } } } else { m_musicDatabase.Close(); return false; } } scraper.LoadArtistInfo(iSelectedArtist, strArtist); while (!scraper.Completed()) { if (m_bStop) { scraper.Cancel(); bCanceled = true; } Sleep(1); } if (scraper.Succeeded()) { artist = scraper.GetArtist(iSelectedArtist).GetArtist(); if (result == CNfoFile::COMBINED_NFO) nfoReader.GetDetails(artist); m_musicDatabase.SetArtistInfo(params.GetArtistId(), artist); } // check thumb stuff GetArtistArtwork(params.GetArtistId(), strArtist, &artist); m_musicDatabase.Close(); return true; }
bool CVideoLibraryRefreshingJob::Work(CVideoDatabase &db) { if (m_item == nullptr) return false; // determine the scraper for the item's path VIDEO::SScanSettings scanSettings; ADDON::ScraperPtr scraper = db.GetScraperForPath(m_item->GetPath(), scanSettings); if (scraper == nullptr) return false; // copy the scraper in case we need it again ADDON::ScraperPtr originalScraper(scraper); // get the item's correct title std::string itemTitle = m_searchTitle; if (itemTitle.empty()) itemTitle = m_item->GetMovieName(scanSettings.parent_name); CScraperUrl scraperUrl; VIDEO::CVideoInfoScanner scanner; bool needsRefresh = m_forceRefresh; bool hasDetails = false; bool ignoreNfo = m_ignoreNfo; // run this in a loop in case we need to refresh again bool failure = false; do { if (!ignoreNfo) { // check if there's an NFO for the item CNfoFile::NFOResult nfoResult = scanner.CheckForNFOFile(m_item.get(), scanSettings.parent_name_root, scraper, scraperUrl); // if there's no NFO remember it in case we have to refresh again if (nfoResult == CNfoFile::ERROR_NFO) ignoreNfo = true; else if (nfoResult != CNfoFile::NO_NFO) hasDetails = true; // if we are performing a forced refresh ask the user to choose between using a valid NFO and a valid scraper if (needsRefresh && IsModal() && !scraper->IsNoop() && nfoResult != CNfoFile::ERROR_NFO) { int heading = 20159; if (scraper->Content() == CONTENT_MOVIES) heading = 13346; else if (scraper->Content() == CONTENT_TVSHOWS) heading = m_item->m_bIsFolder ? 20351 : 20352; else if (scraper->Content() == CONTENT_MUSICVIDEOS) heading = 20393; if (CGUIDialogYesNo::ShowAndGetInput(heading, 20446)) { hasDetails = false; ignoreNfo = true; scraperUrl.Clear(); scraper = originalScraper; } } } // no need to re-fetch the episode guide for episodes if (scraper->Content() == CONTENT_TVSHOWS && !m_item->m_bIsFolder) hasDetails = true; // if we don't have an url or need to refresh anyway do the web search if (!hasDetails && (needsRefresh || scraperUrl.m_url.empty())) { SetTitle(StringUtils::Format(g_localizeStrings.Get(197).c_str(), scraper->Name().c_str())); SetText(itemTitle); SetProgress(0); // clear any cached data from the scraper scraper->ClearCache(); // create the info downloader for the scraper CVideoInfoDownloader infoDownloader(scraper); // try to find a matching item MOVIELIST itemResultList; int result = infoDownloader.FindMovie(itemTitle, itemResultList, GetProgressDialog()); // close the progress dialog MarkFinished(); if (result > 0) { // there are multiple matches for the item if (!itemResultList.empty()) { // choose the first match if (!IsModal()) scraperUrl = itemResultList.at(0); else { // ask the user what to do CGUIDialogSelect* selectDialog = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); selectDialog->Reset(); selectDialog->SetHeading(scraper->Content() == CONTENT_TVSHOWS ? 20356 : 196); for (const auto& itemResult : itemResultList) selectDialog->Add(itemResult.strTitle); selectDialog->EnableButton(true, 413); // "Manual" selectDialog->Open(); // check if the user has chosen one of the results int selectedItem = selectDialog->GetSelectedItem(); if (selectedItem >= 0) scraperUrl = itemResultList.at(selectedItem); // the user hasn't chosen one of the results and but has chosen to manually enter a title to use else if (selectDialog->IsButtonPressed()) { // ask the user to input a title to use if (!CGUIKeyboardFactory::ShowAndGetInput(itemTitle, g_localizeStrings.Get(scraper->Content() == CONTENT_TVSHOWS ? 20357 : 16009), false)) return false; // go through the whole process again needsRefresh = true; continue; } // nothing else we can do else return false; } CLog::Log(LOGDEBUG, "CVideoLibraryRefreshingJob: user selected item '%s' with URL '%s'", scraperUrl.strTitle.c_str(), scraperUrl.m_url.at(0).m_url.c_str()); } } else if (result < 0 || !VIDEO::CVideoInfoScanner::DownloadFailed(GetProgressDialog())) { failure = true; break; } } // if the URL is still empty, check whether or not we're allowed // to prompt and ask the user to input a new search title if (!hasDetails && scraperUrl.m_url.empty()) { if (IsModal()) { // ask the user to input a title to use if (!CGUIKeyboardFactory::ShowAndGetInput(itemTitle, g_localizeStrings.Get(scraper->Content() == CONTENT_TVSHOWS ? 20357 : 16009), false)) return false; // go through the whole process again needsRefresh = true; continue; } // nothing else we can do failure = true; break; } // before we start downloading all the necessary information cleanup any existing artwork and hashes CTextureDatabase textureDb; if (textureDb.Open()) { for (const auto& artwork : m_item->GetArt()) textureDb.InvalidateCachedTexture(artwork.second); textureDb.Close(); } m_item->ClearArt(); // put together the list of items to refresh std::string path = m_item->GetPath(); CFileItemList items; if (m_item->HasVideoInfoTag() && m_item->GetVideoInfoTag()->m_iDbId > 0) { // for a tvshow we need to handle all paths of it std::vector<std::string> tvshowPaths; if (CMediaTypes::IsMediaType(m_item->GetVideoInfoTag()->m_type, MediaTypeTvShow) && m_refreshAll && db.GetPathsLinkedToTvShow(m_item->GetVideoInfoTag()->m_iDbId, tvshowPaths)) { for (const auto& tvshowPath : tvshowPaths) { CFileItemPtr tvshowItem(new CFileItem(*m_item->GetVideoInfoTag())); tvshowItem->SetPath(tvshowPath); items.Add(tvshowItem); } } // otherwise just add a copy of the item else items.Add(CFileItemPtr(new CFileItem(*m_item->GetVideoInfoTag()))); // update the path to the real path (instead of a videodb:// one) path = m_item->GetVideoInfoTag()->m_strPath; } else items.Add(CFileItemPtr(new CFileItem(*m_item))); // set the proper path of the list of items to lookup items.SetPath(m_item->m_bIsFolder ? URIUtils::GetParentPath(path) : URIUtils::GetDirectory(path)); int headingLabel = 198; if (scraper->Content() == CONTENT_TVSHOWS) { if (m_item->m_bIsFolder) headingLabel = 20353; else headingLabel = 20361; } else if (scraper->Content() == CONTENT_MUSICVIDEOS) headingLabel = 20394; // prepare the progress dialog for downloading all the necessary information SetTitle(g_localizeStrings.Get(headingLabel)); SetText(scraperUrl.strTitle); SetProgress(0); // remove any existing data for the item we're going to refresh if (m_item->GetVideoInfoTag()->m_iDbId > 0) { int dbId = m_item->GetVideoInfoTag()->m_iDbId; if (scraper->Content() == CONTENT_MOVIES) db.DeleteMovie(dbId); else if (scraper->Content() == CONTENT_MUSICVIDEOS) db.DeleteMusicVideo(dbId); else if (scraper->Content() == CONTENT_TVSHOWS) { if (!m_item->m_bIsFolder) db.DeleteEpisode(dbId); else if (m_refreshAll) db.DeleteTvShow(dbId); else db.DeleteDetailsForTvShow(dbId); } } // finally download the information for the item if (!scanner.RetrieveVideoInfo(items, scanSettings.parent_name, scraper->Content(), !ignoreNfo, scraperUrl.m_url.empty() ? NULL : &scraperUrl, m_refreshAll, GetProgressDialog())) { // something went wrong MarkFinished(); // check if the user cancelled if (!IsCancelled() && IsModal()) CGUIDialogOK::ShowAndGetInput(195, itemTitle); return false; } // retrieve the updated information from the database if (scraper->Content() == CONTENT_MOVIES) db.GetMovieInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else if (scraper->Content() == CONTENT_MUSICVIDEOS) db.GetMusicVideoInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else if (scraper->Content() == CONTENT_TVSHOWS) { // update tvshow info to get updated episode numbers if (m_item->m_bIsFolder) db.GetTvShowInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else db.GetEpisodeInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); } // we're finally done MarkFinished(); break; } while (needsRefresh); if (failure && IsModal()) CGUIDialogOK::ShowAndGetInput(195, itemTitle); return true; }