bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */) { CSingleLock lock(m_critSection); addons.clear(); cp_status_t status; int num; CStdString ext_point(TranslateType(type)); cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); for(int i=0; i <num; i++) { const cp_extension_t *props = exts[i]; if (m_database.IsAddonDisabled(props->plugin->identifier) != enabled) { // get a pointer to a running pvrclient if it's already started, or we won't be able to change settings if (TranslateType(props->ext_point_id) == ADDON_PVRDLL && enabled && g_PVRManager.IsStarted()) { AddonPtr pvrAddon; if (g_PVRClients->GetClient(props->plugin->identifier, pvrAddon)) { addons.push_back(pvrAddon); continue; } } AddonPtr addon(Factory(props)); if (addon) addons.push_back(addon); } } m_cpluff->release_info(m_cp_context, exts); return addons.size() > 0; }
bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */, bool bGetDisabledPVRAddons /* = true */) { CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons"); CSingleLock lock(m_critSection); addons.clear(); cp_status_t status; int num; CStdString ext_point(TranslateType(type)); cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); for(int i=0; i <num; i++) { const cp_extension_t *props = exts[i]; bool bIsPVRAddon(TranslateType(props->ext_point_id) == ADDON_PVRDLL); if (((bGetDisabledPVRAddons && bIsPVRAddon) || m_database.IsAddonDisabled(props->plugin->identifier) != enabled)) { if (bIsPVRAddon && g_PVRManager.IsStarted()) { AddonPtr pvrAddon; if (g_PVRClients->GetClient(props->plugin->identifier, pvrAddon)) { addons.push_back(pvrAddon); continue; } } AddonPtr addon(Factory(props)); if (addon) addons.push_back(addon); } } m_cpluff->release_info(m_cp_context, exts); return addons.size() > 0; }
bool CAddonDatabase::GetAddons(VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS2.get()) return false; CStdString sql = PrepareSQL("select distinct addonID from addon"); m_pDS->query(sql.c_str()); while (!m_pDS->eof()) { sql = PrepareSQL("select id from addon where addonID='%s' order by version desc",m_pDS->fv(0).get_asString().c_str()); m_pDS2->query(sql.c_str()); AddonPtr addon; if (GetAddon(m_pDS2->fv(0).get_asInt(),addon)) addons.push_back(addon); m_pDS->next(); } m_pDS->close(); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonDatabase::SearchTitle(const CStdString& search, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; CStdString strSQL; strSQL=PrepareSQL("select idAddon from addon where name like '%s%%'", search.c_str()); if (!m_pDS->query(strSQL.c_str())) return false; if (m_pDS->num_rows() == 0) return false; while (!m_pDS->eof()) { AddonPtr addon; GetAddon(m_pDS->fv(0).get_asInt(),addon); if (addon->Type() >= ADDON_UNKNOWN+1 && addon->Type() < ADDON_SCRAPER_LIBRARY) addons.push_back(addon); m_pDS->next(); } m_pDS->close(); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonDatabase::Search(const std::string& search, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; std::string strSQL; strSQL=PrepareSQL("SELECT addonID FROM addon WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%'", search.c_str(), search.c_str(), search.c_str()); CLog::Log(LOGDEBUG, "%s query: %s", __FUNCTION__, strSQL.c_str()); if (!m_pDS->query(strSQL.c_str())) return false; if (m_pDS->num_rows() == 0) return false; while (!m_pDS->eof()) { AddonPtr addon; GetAddon(m_pDS->fv(0).get_asString(),addon); if (addon->Type() >= ADDON_UNKNOWN+1 && addon->Type() < ADDON_SCRAPER_LIBRARY) addons.push_back(addon); m_pDS->next(); } m_pDS->close(); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool enabled /*= true*/) { CSingleLock lock(m_critSection); for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i) { VECADDONS temp; if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) { AddonPtr repoAddon; for (unsigned int j = 0; j < temp.size(); j++) { // Ignore duplicates due to add-ons with multiple extension points bool found = false; for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++) { if ((*addonIt)->ID() == temp[j]->ID()) found = true; } if (found || !m_database.GetAddon(temp[j]->ID(), repoAddon)) continue; if (temp[j]->Version() < repoAddon->Version() && !m_database.IsAddonBlacklisted(temp[j]->ID(), repoAddon->Version().c_str())) addons.push_back(repoAddon); } } } return !addons.empty(); }
bool CAddonDatabase::GetAddons(VECADDONS& addons, const TYPE &type /* = ADDON_UNKNOWN */) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS2.get()) return false; CStdString sql; if (type == ADDON_UNKNOWN) sql = PrepareSQL("select distinct addonID from addon"); else { const string strType = TranslateType(type); sql = PrepareSQL("select distinct addonID from addon where type='%s'", strType.c_str()); } m_pDS->query(sql.c_str()); while (!m_pDS->eof()) { AddonPtr addon; if (GetAddon(m_pDS->fv(0).get_asString(),addon)) addons.push_back(addon); m_pDS->next(); } m_pDS->close(); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonMgr::AddonsFromRepoXML(const TiXmlElement *root, VECADDONS &addons) { // create a context for these addons cp_status_t status; cp_context_t *context = m_cpluff->create_context(&status); if (!root || !context) return false; // each addon XML should have a UTF-8 declaration TiXmlDeclaration decl("1.0", "UTF-8", ""); const TiXmlElement *element = root->FirstChildElement("addon"); while (element) { // dump the XML back to text std::string xml; xml << decl; xml << *element; cp_status_t status; cp_plugin_info_t *info = m_cpluff->load_plugin_descriptor_from_memory(context, xml.c_str(), xml.size(), &status); if (info) { AddonPtr addon = GetAddonFromDescriptor(info); if (addon.get()) addons.push_back(addon); m_cpluff->release_info(context, info); } element = element->NextSiblingElement("addon"); } m_cpluff->destroy_context(context); return true; }
bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */) { CSingleLock lock(m_critSection); addons.clear(); if (!m_cp_context) return false; cp_status_t status; int num; std::string ext_point(TranslateType(type)); cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); for(int i=0; i <num; i++) { const cp_extension_t *props = exts[i]; if (IsAddonDisabled(props->plugin->identifier) != enabled) { AddonPtr addon(Factory(props)); if (addon) { if (enabled) { // if the addon has a running instance, grab that AddonPtr runningAddon = addon->GetRunningInstance(); if (runningAddon) addon = runningAddon; } addons.push_back(addon); } } } m_cpluff->release_info(m_cp_context, exts); return addons.size() > 0; }
void CAddonInstallJob::OnPostInstall(bool reloadAddon) { if (m_addon->Type() < ADDON_VIZ_LIBRARY && CSettings::Get().GetBool("general.addonnotifications")) { CGUIDialogKaiToast::QueueNotification(m_addon->Icon(), m_addon->Name(), g_localizeStrings.Get(m_update ? 24065 : 24064), TOAST_DISPLAY_TIME,false, TOAST_DISPLAY_TIME); } if (m_addon->Type() == ADDON_SKIN) { if (reloadAddon || (!m_update && CGUIDialogYesNo::ShowAndGetInput(m_addon->Name(), g_localizeStrings.Get(24099),"",""))) { CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST); if (toast) { toast->ResetTimer(); toast->Close(true); } if (CSettings::Get().GetString("lookandfeel.skin") == m_addon->ID()) CApplicationMessenger::Get().ExecBuiltIn("ReloadSkin", true); else CSettings::Get().SetString("lookandfeel.skin",m_addon->ID().c_str()); } } if (m_addon->Type() == ADDON_SERVICE) { CAddonMgr::Get().DisableAddon(m_addon->ID(),!reloadAddon); //return it into state it was before OnPreInstall() if (reloadAddon) // reload/start it if it was running { // regrab from manager to have the correct path set AddonPtr addon; CAddonMgr::Get().GetAddon(m_addon->ID(), addon); boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(addon); if (service) service->Start(); } } if (m_addon->Type() == ADDON_REPOSITORY) { VECADDONS addons; addons.push_back(m_addon); CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(addons), &CAddonInstaller::Get()); } if (m_addon->Type() == ADDON_PVRDLL) { // (re)start the pvr manager PVR::CPVRManager::Get().Start(true); } }
void CBinaryAddonCache::GetAddons(VECADDONS& addons, const TYPE& type) { CSingleLock lock(m_critSection); auto it = m_addons.find(type); if (it != m_addons.end()) { for (auto &addon : it->second) { if (!CAddonMgr::GetInstance().IsAddonDisabled(addon->ID())) addons.push_back(addon); } } }
bool CAddonsDirectory::GetScriptsAndPlugins(const CStdString &content, VECADDONS &addons) { CPluginSource::Content type = CPluginSource::Translate(content); if (type == CPluginSource::UNKNOWN) return false; VECADDONS tempAddons; CAddonMgr::Get().GetAddons(ADDON_PLUGIN, tempAddons); for (unsigned i=0; i<tempAddons.size(); i++) { PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(tempAddons[i]); if (plugin && plugin->Provides(type)) addons.push_back(tempAddons[i]); } tempAddons.clear(); CAddonMgr::Get().GetAddons(ADDON_SCRIPT, tempAddons); for (unsigned i=0; i<tempAddons.size(); i++) { PluginPtr plugin = boost::dynamic_pointer_cast<CPluginSource>(tempAddons[i]); if (plugin && plugin->Provides(type)) addons.push_back(tempAddons[i]); } return true; }
bool CAddonDatabase::FindByAddonId(const std::string& addonId, ADDON::VECADDONS& result) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; std::string sql = PrepareSQL( "SELECT addons.version, addons.name, addons.summary, addons.description, addons.metadata, addons.news," "repo.addonID AS repoID FROM addons " "JOIN addonlinkrepo ON addonlinkrepo.idAddon=addons.id " "JOIN repo ON repo.id=addonlinkrepo.idRepo " "WHERE " "repo.checksum IS NOT NULL AND repo.checksum != '' " "AND EXISTS (SELECT * FROM installed WHERE installed.addonID=repoID AND installed.enabled=1) " "AND addons.addonID='%s'", addonId.c_str()); VECADDONS addons; m_pDS->query(sql.c_str()); while (!m_pDS->eof()) { CAddonBuilder builder; builder.SetId(addonId); builder.SetVersion(AddonVersion(m_pDS->fv(0).get_asString())); builder.SetName(m_pDS->fv(1).get_asString()); builder.SetSummary(m_pDS->fv(2).get_asString()); builder.SetDescription(m_pDS->fv(3).get_asString()); DeserializeMetadata(m_pDS->fv(4).get_asString(), builder); builder.SetChangelog(m_pDS->fv(5).get_asString()); builder.SetOrigin(m_pDS->fv(6).get_asString()); auto addon = builder.Build(); if (addon) addons.push_back(std::move(addon)); else CLog::Log(LOGERROR, "CAddonDatabase: failed to build %s", addonId.c_str()); m_pDS->next(); } m_pDS->close(); result = std::move(addons); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed on addon %s", __FUNCTION__, addonId.c_str()); } return false; }
void CGUIDialogContentSettings::FillContentTypes(const CONTENT_TYPE &content) { // grab all scrapers which support this content-type VECADDONS addons; TYPE type = ScraperTypeFromContent(content); if (!CAddonMgr::Get().GetAddons(type, addons)) return; AddonPtr addon; CStdString defaultID; if (CAddonMgr::Get().GetDefault(type, addon)) defaultID = addon->ID(); for (IVECADDONS it = addons.begin(); it != addons.end(); it++) { bool isDefault = ((*it)->ID() == defaultID); map<CONTENT_TYPE,VECADDONS>::iterator iter=m_scrapers.find(content); AddonPtr scraper = (*it)->Clone((*it)); if (m_scraper && m_scraper->ID() == (*it)->ID()) { // don't overwrite preconfigured scraper scraper = m_scraper; } if (iter != m_scrapers.end()) { if (isDefault) iter->second.insert(iter->second.begin(), scraper); else iter->second.push_back(scraper); } else { VECADDONS vec; vec.push_back(scraper); m_scrapers.insert(make_pair(content,vec)); } } // add CONTENT type to spinner CGUIMessage msg(GUI_MSG_LABEL_ADD,GetID(),CONTROL_CONTENT_TYPE); msg.SetLabel(TranslateContent(content, true)); msg.SetParam1((int) content); g_windowManager.SendMessage(msg); }
bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */) { CSingleLock lock(m_critSection); addons.clear(); cp_status_t status; int num; CStdString ext_point(TranslateType(type)); cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); for(int i=0; i <num; i++) { AddonPtr addon(Factory(exts[i])); if (addon && m_database.IsAddonDisabled(addon->ID()) != enabled) addons.push_back(addon); } m_cpluff->release_info(m_cp_context, exts); return addons.size() > 0; }
void CAddonInstaller::GetInstallList(VECADDONS &addons) const { CSingleLock lock(m_critSection); std::vector<std::string> addonIDs; for (JobMap::const_iterator i = m_downloadJobs.begin(); i != m_downloadJobs.end(); ++i) { if (i->second.jobID) addonIDs.push_back(i->first); } lock.Leave(); CAddonDatabase database; database.Open(); for (std::vector<std::string>::iterator it = addonIDs.begin(); it != addonIDs.end(); ++it) { AddonPtr addon; if (database.GetAddon(*it, addon)) addons.push_back(addon); } }
bool CAddonMgr::GetAllOutdatedAddons(VECADDONS &addons, bool enabled /*= true*/) { CSingleLock lock(m_critSection); for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i) { VECADDONS temp; if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) { AddonPtr repoAddon; for (unsigned int j = 0; j < temp.size(); j++) { if (!m_database.GetAddon(temp[j]->ID(), repoAddon)) continue; if (temp[j]->Version() < repoAddon->Version()) addons.push_back(repoAddon); } } } return !addons.empty(); }
bool CAddonDatabase::GetAddons(VECADDONS& addons, const ADDON::TYPE &type /* = ADDON::ADDON_UNKNOWN */) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS2.get()) return false; std::string sql = PrepareSQL("SELECT DISTINCT a.addonID FROM addon a, addonlinkrepo b WHERE b.idRepo > 0 AND a.id = b.idAddon AND " "NOT EXISTS (SELECT repo.id FROM repo, disabled WHERE repo.addonID=disabled.addonID AND repo.id=b.idRepo)"); if (type != ADDON_UNKNOWN) { std::string strType; if (type >= ADDON_VIDEO && type <= ADDON_EXECUTABLE) strType = TranslateType(ADDON_PLUGIN); else strType = TranslateType(type); if (!strType.empty()) sql += PrepareSQL(" AND a.type = '%s'", strType.c_str()); } m_pDS->query(sql.c_str()); while (!m_pDS->eof()) { AddonPtr addon; if (GetAddon(m_pDS->fv(0).get_asString(),addon)) addons.push_back(addon); m_pDS->next(); } m_pDS->close(); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonMgr::GetAddons(const TYPE &type, VECADDONS &addons, bool enabled /* = true */) { CStdString xbmcPath = _P("special://xbmc/addons"); CSingleLock lock(m_critSection); addons.clear(); cp_status_t status; int num; CStdString ext_point(TranslateType(type)); cp_extension_t **exts = m_cpluff->get_extensions_info(m_cp_context, ext_point.c_str(), &status, &num); for(int i=0; i <num; i++) { AddonPtr addon(Factory(exts[i])); if (addon && addon->Type() == ADDON_PVRDLL && addon->Path().Left(xbmcPath.size()).Equals(xbmcPath)) { if (m_database.IsSystemPVRAddonEnabled(addon->ID()) != enabled) addon->Disable(); } if (addon && m_database.IsAddonDisabled(addon->ID()) != enabled) addons.push_back(addon); } m_cpluff->release_info(m_cp_context, exts); return addons.size() > 0; }
bool CAddonDatabase::GetAddons(VECADDONS& addons, const ADDON::TYPE &type /* = ADDON::ADDON_UNKNOWN */) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS2.get()) return false; std::string sql = PrepareSQL("select distinct addonID from addon"); if (type != ADDON_UNKNOWN) { std::string strType; if (type >= ADDON_VIDEO && type <= ADDON_EXECUTABLE) strType = TranslateType(ADDON_PLUGIN); else strType = TranslateType(type); if (!strType.empty()) sql += PrepareSQL(" where type = '%s'", strType.c_str()); } m_pDS->query(sql.c_str()); while (!m_pDS->eof()) { AddonPtr addon; if (GetAddon(m_pDS->fv(0).get_asString(),addon)) addons.push_back(addon); m_pDS->next(); } m_pDS->close(); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonDatabase::GetRepository(int id, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; std::string strSQL = PrepareSQL("select * from addonlinkrepo where idRepo=%i",id); m_pDS->query(strSQL.c_str()); while (!m_pDS->eof()) { AddonPtr addon; if (GetAddon(m_pDS->fv("idAddon").get_asInt(),addon)) addons.push_back(addon); m_pDS->next(); } return true; } catch (...) { CLog::Log(LOGERROR, "%s failed on repo %i", __FUNCTION__, id); } return false; }
bool CActiveAEDSP::UpdateAndInitialiseAudioDSPAddons(bool bInitialiseAllAudioDSPAddons /* = false */) { bool bReturn(true); VECADDONS map; VECADDONS disableAddons; { CSingleLock lock(m_critUpdateSection); map = m_addons; } if (map.empty()) return false; for (unsigned iAddonPtr = 0; iAddonPtr < map.size(); ++iAddonPtr) { const AddonPtr dspAddon = map.at(iAddonPtr); bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(dspAddon->ID()); if (!bEnabled && IsKnownAudioDSPAddon(dspAddon)) { CSingleLock lock(m_critUpdateSection); /* stop the dsp addon and remove it from the db */ StopAudioDSPAddon(dspAddon, false); VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), dspAddon); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } else if (bEnabled && (bInitialiseAllAudioDSPAddons || !IsKnownAudioDSPAddon(dspAddon) || !IsReadyAudioDSPAddon(dspAddon))) { bool bDisabled(false); /* register the add-on in the audio dsp db, and create the CActiveAEDSPAddon instance */ int iAddonId = RegisterAudioDSPAddon(dspAddon); if (iAddonId < 0) { /* failed to register or create the add-on, disable it */ CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to register add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str()); disableAddons.push_back(dspAddon); bDisabled = true; } else { ADDON_STATUS status(ADDON_STATUS_UNKNOWN); AE_DSP_ADDON addon; { CSingleLock lock(m_critUpdateSection); if (!GetAudioDSPAddon(iAddonId, addon)) { CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to find add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str()); disableAddons.push_back(dspAddon); bDisabled = true; } } /* re-check the enabled status. newly installed dsps get disabled when they're added to the db */ if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()) && (status = addon->Create(iAddonId)) != ADDON_STATUS_OK) { CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to create add-on %s, status = %d", __FUNCTION__, dspAddon->Name().c_str(), status); if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE) { /* failed to load the dll of this add-on, disable it */ CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str()); disableAddons.push_back(dspAddon); bDisabled = true; } } } if (bDisabled && IsActivated()) CGUIDialogOK::ShowAndGetInput(24070, 24071, 16029, 0); } } /* disable add-ons that failed to initialise */ if (!disableAddons.empty()) { CSingleLock lock(m_critUpdateSection); for (VECADDONS::iterator itr = disableAddons.begin(); itr != disableAddons.end(); ++itr) { /* disable in the add-on db */ CAddonMgr::GetInstance().DisableAddon((*itr)->ID()); /* remove from the audio dsp add-on list */ VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *itr); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } } return bReturn; }
bool CAddonDatabase::GetRepositoryContent(const std::string& repoId, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; auto start = XbmcThreads::SystemClockMillis(); std::string commonConstraint = PrepareSQL( "JOIN addonlinkrepo ON addon.id=addonlinkrepo.idAddon " "JOIN repo ON addonlinkrepo.idRepo=repo.id " "WHERE repo.checksum IS NOT NULL AND repo.checksum != ''"); if (!repoId.empty()) commonConstraint += PrepareSQL(" AND repo.addonId='%s'", repoId.c_str()); commonConstraint += PrepareSQL(" ORDER BY addon.addonID"); std::vector<CAddonBuilder> result; // Read basic info from the `addon` table { std::string sql = PrepareSQL("SELECT addon.*, broken.reason FROM addon " "LEFT JOIN broken ON broken.addonID=addon.addonID ") + commonConstraint; auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); while (!m_pDS->eof()) { std::string addonId = m_pDS->fv(addon_addonID).get_asString(); AddonVersion version(m_pDS->fv(addon_version).get_asString()); if (!result.empty() && result.back().GetId() == addonId && result.back().GetVersion() >= version) { // We already have a version of this addon in our list which is newer. m_pDS->next(); continue; } CAddonBuilder builder; builder.SetId(addonId); builder.SetVersion(version); builder.SetType(TranslateType(m_pDS->fv(addon_type).get_asString())); builder.SetMinVersion(AddonVersion(m_pDS->fv(addon_minversion).get_asString())); builder.SetName(m_pDS->fv(addon_name).get_asString()); builder.SetSummary(m_pDS->fv(addon_summary).get_asString()); builder.SetDescription(m_pDS->fv(addon_description).get_asString()); builder.SetChangelog(m_pDS->fv(addon_changelog).get_asString()); builder.SetDisclaimer(m_pDS->fv(addon_disclaimer).get_asString()); builder.SetAuthor(m_pDS->fv(addon_author).get_asString()); builder.SetPath(m_pDS->fv(addon_path).get_asString()); builder.SetIcon(m_pDS->fv(addon_icon).get_asString()); builder.SetFanart(m_pDS->fv(addon_fanart).get_asString()); builder.SetBroken(m_pDS->fv(broken_reason).get_asString()); if (!result.empty() && result.back().GetId() == addonId) result.back() = std::move(builder); else result.push_back(std::move(builder)); m_pDS->next(); } } // Read extra info. { std::string sql = PrepareSQL( "SELECT addon.addonID as owner, addonextra.key, addonextra.value " "FROM addon JOIN addonextra ON addon.id=addonextra.id ") + commonConstraint; auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); for (auto& builder : result) { //move cursor to current or next addon while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId()) m_pDS->next(); InfoMap extraInfo; while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId()) { extraInfo.emplace(m_pDS->fv(1).get_asString(), m_pDS->fv(2).get_asString()); m_pDS->next(); } builder.SetExtrainfo(std::move(extraInfo)); } } // Read dependency info. { std::string sql = PrepareSQL( "SELECT addon.addonID as owner, dependencies.addon, dependencies.version, dependencies.optional " "FROM addon JOIN dependencies ON addon.id=dependencies.id ") + commonConstraint; auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); for (auto& builder : result) { //move cursor to the current or next addon while (!m_pDS->eof() && m_pDS->fv(0).get_asString() < builder.GetId()) m_pDS->next(); ADDONDEPS dependencies; while (!m_pDS->eof() && m_pDS->fv(0).get_asString() == builder.GetId()) { dependencies.emplace(m_pDS->fv(1).get_asString(), std::make_pair(AddonVersion(m_pDS->fv(2).get_asString()), m_pDS->fv(3).get_asBool())); m_pDS->next(); } builder.SetDependencies(std::move(dependencies)); } } m_pDS->close(); for (auto& builder : result) { auto addon = builder.Build(); if (addon) addons.push_back(std::move(addon)); } CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CAddonDatabase::GetRepositoryContent(const std::string& id, VECADDONS& addons) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; auto start = XbmcThreads::SystemClockMillis(); // Ensure that the repositories we fetch from are enabled and valid. std::vector<std::string> repoIds; { std::string sql = PrepareSQL( " SELECT repo.id FROM repo" " WHERE repo.checksum IS NOT NULL AND repo.checksum != ''" " AND EXISTS (SELECT * FROM installed WHERE installed.addonID=repo.addonID AND" " installed.enabled=1)"); if (!id.empty()) sql += PrepareSQL(" AND repo.addonId='%s'", id.c_str()); m_pDS->query(sql); while (!m_pDS->eof()) { repoIds.emplace_back(m_pDS->fv(0).get_asString()); m_pDS->next(); } } CLog::Log(LOGDEBUG, "CAddonDatabase: SELECT repo.id FROM repo .. took %d ms", XbmcThreads::SystemClockMillis() - start); if (repoIds.empty()) { CLog::Log(LOGDEBUG, "CAddonDatabase: no valid repository matching '%s'", id.c_str()); return false; } { std::string sql = PrepareSQL( " SELECT * FROM addons" " JOIN addonlinkrepo ON addons.id=addonlinkrepo.idAddon" " WHERE addonlinkrepo.idRepo IN (%s)" " ORDER BY addons.addonID", StringUtils::Join(repoIds, ",").c_str()); auto start = XbmcThreads::SystemClockMillis(); m_pDS->query(sql); CLog::Log(LOGDEBUG, "CAddonDatabase: query %s returned %d rows in %d ms", sql.c_str(), m_pDS->num_rows(), XbmcThreads::SystemClockMillis() - start); } VECADDONS result; while (!m_pDS->eof()) { std::string addonId = m_pDS->fv("addonID").get_asString(); AddonVersion version(m_pDS->fv("version").get_asString()); if (!result.empty() && result.back()->ID() == addonId && result.back()->Version() >= version) { // We already have a version of this addon in our list which is newer. m_pDS->next(); continue; } CAddonBuilder builder; builder.SetId(addonId); builder.SetVersion(version); builder.SetName(m_pDS->fv("name").get_asString()); builder.SetSummary(m_pDS->fv("summary").get_asString()); builder.SetDescription(m_pDS->fv("description").get_asString()); DeserializeMetadata(m_pDS->fv("metadata").get_asString(), builder); auto addon = builder.Build(); if (addon) { if (!result.empty() && result.back()->ID() == addonId) result.back() = std::move(addon); else result.push_back(std::move(addon)); } else CLog::Log(LOGWARNING, "CAddonDatabase: failed to build %s", addonId.c_str()); m_pDS->next(); } m_pDS->close(); addons = std::move(result); CLog::Log(LOGDEBUG, "CAddonDatabase::GetAddons took %i ms", XbmcThreads::SystemClockMillis() - start); return true; } catch (...) { CLog::Log(LOGERROR, "%s failed", __FUNCTION__); } return false; }
bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = false */) { bool bReturn(true); VECADDONS map; VECADDONS disableAddons; { CSingleLock lock(m_critSection); map = m_addons; } if (map.empty()) return false; for (VECADDONS::iterator it = map.begin(); it != map.end(); ++it) { bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled((*it)->ID()); if (!bEnabled && IsKnownClient(*it)) { CSingleLock lock(m_critSection); /* stop the client and remove it from the db */ StopClient(*it, false); disableAddons.push_back(*it); } else if (bEnabled && (bInitialiseAllClients || !IsKnownClient(*it) || !IsConnectedClient(*it))) { bool bDisabled(false); // register the add-on in the pvr db, and create the CPVRClient instance int iClientId = RegisterClient(*it); if (iClientId <= 0) { // failed to register or create the add-on, disable it CLog::Log(LOGWARNING, "%s - failed to register add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str()); disableAddons.push_back(*it); bDisabled = true; } else { ADDON_STATUS status(ADDON_STATUS_UNKNOWN); PVR_CLIENT addon; { CSingleLock lock(m_critSection); if (!GetClient(iClientId, addon)) { CLog::Log(LOGWARNING, "%s - failed to find add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str()); disableAddons.push_back(*it); bDisabled = true; } } // throttle connection attempts, no more than 1 attempt per 5 seconds if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID())) { time_t now; CDateTime::GetCurrentDateTime().GetAsTime(now); std::map<int, time_t>::iterator it = m_connectionAttempts.find(iClientId); if (it != m_connectionAttempts.end() && now < it->second) continue; m_connectionAttempts[iClientId] = now + 5; } // re-check the enabled status. newly installed clients get disabled when they're added to the db if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()) && (status = addon->Create(iClientId)) != ADDON_STATUS_OK) { CLog::Log(LOGWARNING, "%s - failed to create add-on %s, status = %d", __FUNCTION__, (*it)->Name().c_str(), status); if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE) { // failed to load the dll of this add-on, disable it CLog::Log(LOGWARNING, "%s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, (*it)->Name().c_str()); disableAddons.push_back(*it); bDisabled = true; } } } if (bDisabled && (g_PVRManager.IsStarted() || g_PVRManager.IsInitialising())) CGUIDialogOK::ShowAndGetInput(CVariant{24070}, CVariant{16029}); } } // disable add-ons that failed to initialise if (!disableAddons.empty()) { CSingleLock lock(m_critSection); for (VECADDONS::iterator it = disableAddons.begin(); it != disableAddons.end(); ++it) { // disable in the add-on db CAddonMgr::GetInstance().DisableAddon((*it)->ID()); // remove from the pvr add-on list VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *it); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } } return bReturn; }