bool CAddonInstaller::CheckDependencies(const AddonPtr &addon, CAddonDatabase *database /* = NULL */) { std::vector<std::string> preDeps; preDeps.push_back(addon->ID()); CAddonDatabase localDB; if (!database) database = &localDB; return CheckDependencies(addon, preDeps, *database); }
bool CPVRClients::IsConnectedClient(const AddonPtr addon) { CSingleLock lock(m_critSection); for (PVR_CLIENTMAP_CITR itr = m_clientMap.begin(); itr != m_clientMap.end(); itr++) if (itr->second->ID() == addon->ID()) return itr->second->ReadyToUse(); return false; }
bool CPVRClients::IsCreatedClient(const AddonPtr addon) { CSingleLock lock(m_critSection); for (const auto &client : m_clientMap) if (client.second->ID() == addon->ID()) return client.second->ReadyToUse(); return false; }
int CActiveAEDSP::RegisterAudioDSPAddon(AddonPtr addon, bool* newRegistration/*=NULL*/) { int iAddonId(-1); if (newRegistration) *newRegistration = false; if (!addon->Enabled()) return -1; CLog::Log(LOGDEBUG, "ActiveAE DSP - %s - registering add-on '%s'", __FUNCTION__, addon->Name().c_str()); if (!m_databaseDSP.IsOpen()) { CLog::Log(LOGERROR, "ActiveAE DSP - %s - failed to get the database", __FUNCTION__); return -1; } /* check whether we already know this dsp addon */ iAddonId = m_databaseDSP.GetAudioDSPAddonId(addon->ID()); /* try to register the new dsp addon in the db */ if (iAddonId < 0) { if ((iAddonId = m_databaseDSP.Persist(addon)) < 0) { CLog::Log(LOGERROR, "ActiveAE DSP - %s - can't add dsp addon '%s' to the database", __FUNCTION__, addon->Name().c_str()); return -1; } else if (newRegistration) *newRegistration = true; } AE_DSP_ADDON dspAddon; /* load and initialise the dsp addon libraries */ { CSingleLock lock(m_critSection); AE_DSP_ADDONMAP_CITR existingAddon = m_addonMap.find(iAddonId); if (existingAddon != m_addonMap.end()) { /* return existing addon */ dspAddon = existingAddon->second; } else { /* create a new addon instance */ dspAddon = std::dynamic_pointer_cast<CActiveAEDSPAddon> (addon); m_addonMap.insert(std::make_pair(iAddonId, dspAddon)); } } if (iAddonId < 0) CLog::Log(LOGERROR, "ActiveAE DSP - %s - can't register dsp add-on '%s'", __FUNCTION__, addon->Name().c_str()); return iAddonId; }
CAddonInstallJob::CAddonInstallJob(const AddonPtr &addon, const AddonPtr &repo, const std::string &hash, bool isAutoUpdate) : m_addon(addon), m_repo(repo), m_hash(hash), m_isAutoUpdate(isAutoUpdate) { AddonPtr dummy; m_isUpdate = CAddonMgr::GetInstance().GetAddon(addon->ID(), dummy, ADDON_UNKNOWN, false); }
int CActiveAEDSPDatabase::Persist(const AddonPtr addon) { int iReturn(-1); /* invalid addon uid or name */ if (addon->Name().empty() || addon->ID().empty()) { CLog::Log(LOGERROR, "Audio DSP - %s - invalid add-on uid or name", __FUNCTION__); return iReturn; } string strQuery = PrepareSQL("REPLACE INTO addons (sName, sUid) VALUES ('%s', '%s');", addon->Name().c_str(), addon->ID().c_str()); if (ExecuteQuery(strQuery)) iReturn = (int) m_pDS->lastinsertid(); return iReturn; }
int CPVRClients::GetClientId(const AddonPtr client) const { CSingleLock lock(m_critSection); for (PVR_CLIENTMAP_CITR itr = m_clientMap.begin(); itr != m_clientMap.end(); itr++) if (itr->second->ID() == client->ID()) return itr->first; return -1; }
void OnPreInstall(const AddonPtr& addon) { //Before installing we need to stop/unregister any local addon //that have this id, regardless of what the 'new' addon is. AddonPtr localAddon; if (CAddonMgr::GetInstance().ServicesHasStarted()) { if (CAddonMgr::GetInstance().GetAddon(addon->ID(), localAddon, ADDON_SERVICE)) std::static_pointer_cast<CService>(localAddon)->Stop(); } if (CAddonMgr::GetInstance().GetAddon(addon->ID(), localAddon, ADDON_CONTEXT_ITEM)) CContextMenuManager::GetInstance().Unload(*std::static_pointer_cast<CContextMenuAddon>(localAddon)); //Fallback to the pre-install callback in the addon. //! @bug If primary extension point have changed we're calling the wrong method. addon->OnPreInstall(); }
int CPVRDatabase::Persist(const AddonPtr client) { int iReturn(-1); /* invalid client uid or name */ if (client->Name().empty() || client->ID().empty()) { CLog::Log(LOGERROR, "PVR - %s - invalid client uid or name", __FUNCTION__); return iReturn; } CStdString strQuery = PrepareSQL("REPLACE INTO clients (sName, sUid) VALUES ('%s', '%s');", client->Name().c_str(), client->ID().c_str()); if (ExecuteQuery(strQuery)) iReturn = (int) m_pDS->lastinsertid(); return iReturn; }
bool CPVRClients::IsKnownClient(const AddonPtr client) const { CSingleLock lock(m_critSection); for (CLIENTMAPCITR itr = m_clientMap.begin(); itr != m_clientMap.end(); itr++) if (itr->second->ID() == client->ID()) return true; return false; }
AddonPtr CAddonInstallJob::GetRepoForAddon(const AddonPtr& addon) { CAddonDatabase database; database.Open(); CStdString repo; database.GetRepoForAddon(addon->ID(), repo); AddonPtr repoPtr; CAddonMgr::Get().GetAddon(repo, repoPtr); return repoPtr; }
bool CAddonInstallJob::Install(const CStdString &installFrom) { CStdString addonFolder(installFrom); URIUtils::RemoveSlashAtEnd(addonFolder); addonFolder = URIUtils::AddFileToFolder("special://home/addons/", URIUtils::GetFileName(addonFolder)); CFileItemList install; install.Add(CFileItemPtr(new CFileItem(installFrom, true))); install[0]->Select(true); CFileOperationJob job(CFileOperationJob::ActionReplace, install, "special://home/addons/"); AddonPtr addon; if (!job.DoWork() || !CAddonMgr::Get().LoadAddonDescription(addonFolder, addon)) { // failed extraction or failed to load addon description CStdString addonID = URIUtils::GetFileName(addonFolder); ReportInstallError(addonID, addonID); CLog::Log(LOGERROR,"Could not read addon description of %s", addonID.c_str()); DeleteAddon(addonFolder); return false; } // resolve dependencies CAddonMgr::Get().FindAddons(); // needed as GetDeps() grabs directly from c-pluff via the addon manager ADDONDEPS deps = addon->GetDeps(); CStdString referer; referer.Format("Referer=%s-%s.zip",addon->ID().c_str(),addon->Version().c_str()); for (ADDONDEPS::iterator it = deps.begin(); it != deps.end(); ++it) { if (it->first.Equals("xbmc.metadata")) continue; AddonPtr dependency; if (!CAddonMgr::Get().GetAddon(it->first,dependency) || dependency->Version() < it->second.first) { bool force=(dependency != NULL); // dependency is already queued up for install - ::Install will fail // instead we wait until the Job has finished. note that we // recall install on purpose in case prior installation failed if (CAddonInstaller::Get().HasJob(it->first)) { while (CAddonInstaller::Get().HasJob(it->first)) Sleep(50); force = false; } // don't have the addon or the addon isn't new enough - grab it (no new job for these) if (!CAddonInstaller::Get().Install(it->first, force, referer, false)) { DeleteAddon(addonFolder); return false; } } } return true; }
int CPVRClients::RegisterClient(AddonPtr client, bool* newRegistration/*=NULL*/) { int iClientId(-1); if (newRegistration) *newRegistration = false; if (!client->Enabled()) return -1; CLog::Log(LOGDEBUG, "%s - registering add-on '%s'", __FUNCTION__, client->Name().c_str()); CPVRDatabase *database = GetPVRDatabase(); if (!database) return -1; // check whether we already know this client iClientId = database->GetClientId(client->ID()); // try to register the new client in the db if (iClientId < 0) { if ((iClientId = database->Persist(client)) < 0) { CLog::Log(LOGERROR, "PVR - %s - can't add client '%s' to the database", __FUNCTION__, client->Name().c_str()); return -1; } else if (newRegistration) *newRegistration = true; } PVR_CLIENT addon; // load and initialise the client libraries { CSingleLock lock(m_critSection); PVR_CLIENTMAP_CITR existingClient = m_clientMap.find(iClientId); if (existingClient != m_clientMap.end()) { // return existing client addon = existingClient->second; } else { // create a new client instance addon = boost::dynamic_pointer_cast<CPVRClient>(client); m_clientMap.insert(std::make_pair(iClientId, addon)); } } if (iClientId < 0) CLog::Log(LOGERROR, "PVR - %s - can't register add-on '%s'", __FUNCTION__, client->Name().c_str()); return iClientId; }
bool CActiveAEDSP::IsReadyAudioDSPAddon(const AddonPtr &addon) { CSingleLock lock(m_critUpdateSection); for (AE_DSP_ADDONMAP_CITR citr = m_addonMap.begin(); citr != m_addonMap.end(); ++citr) { if (citr->second->ID() == addon->ID()) return citr->second->ReadyToUse(); } return false; }
void CServiceAddonManager::Start(const AddonPtr& addon) { CSingleLock lock(m_criticalSection); if (m_services.find(addon->ID()) != m_services.end()) { CLog::Log(LOGDEBUG, "CServiceAddonManager: %s already started.", addon->ID().c_str()); return; } if (StringUtils::EndsWith(addon->LibPath(), ".py")) { CLog::Log(LOGDEBUG, "CServiceAddonManager: starting %s", addon->ID().c_str()); auto handle = CScriptInvocationManager::GetInstance().ExecuteAsync(addon->LibPath(), addon); if (handle == -1) { CLog::Log(LOGERROR, "CServiceAddonManager: %s failed to start", addon->ID().c_str()); return; } m_services[addon->ID()] = handle; } }
int CActiveAEDSP::GetAudioDSPAddonId(const AddonPtr &addon) const { CSingleLock lock(m_critUpdateSection); for (AE_DSP_ADDONMAP_CITR citr = m_addonMap.begin(); citr != m_addonMap.end(); ++citr) { if (citr->second->ID() == addon->ID()) return citr->first; } return -1; }
bool CAddonInstaller::DoInstall(const AddonPtr &addon, const RepositoryPtr& repo, const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */, bool autoUpdate /* = false*/) { // check whether we already have the addon installing CSingleLock lock(m_critSection); if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end()) return false; CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash, autoUpdate); if (background) { // Workaround: because CAddonInstallJob is blocking waiting for other jobs, it needs to be run // with priority dedicated. unsigned int jobID = CJobManager::GetInstance().AddJob(installJob, this, CJob::PRIORITY_DEDICATED); m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(jobID))); m_idle.Reset(); return true; } m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(0))); m_idle.Reset(); lock.Leave(); bool result = false; if (modal) result = installJob->DoModal(); else result = installJob->DoWork(); delete installJob; lock.Enter(); JobMap::iterator i = m_downloadJobs.find(addon->ID()); m_downloadJobs.erase(i); if (m_downloadJobs.empty()) m_idle.Set(); return result; }
bool CAddonInstaller::CheckDependencies(const AddonPtr &addon, std::vector<std::string>& preDeps, CAddonDatabase &database) { if (!addon.get()) return true; // a NULL addon has no dependencies ADDONDEPS deps = addon->GetDeps(); database.Open(); for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i) { const CStdString &addonID = i->first; const AddonVersion &version = i->second.first; bool optional = i->second.second; AddonPtr dep; bool haveAddon = CAddonMgr::Get().GetAddon(addonID, dep); if ((haveAddon && !dep->MeetsVersion(version)) || (!haveAddon && !optional)) { // we have it but our version isn't good enough, or we don't have it and we need it if (!database.GetAddon(addonID, dep) || !dep->MeetsVersion(version)) { // we don't have it in a repo, or we have it but the version isn't good enough, so dep isn't satisfied. CLog::Log(LOGDEBUG, "Addon %s requires %s version %s which is not available", addon->ID().c_str(), addonID.c_str(), version.c_str()); database.Close(); return false; } } // at this point we have our dep, or the dep is optional (and we don't have it) so check that it's OK as well // TODO: should we assume that installed deps are OK? if (dep && std::find(preDeps.begin(), preDeps.end(), dep->ID()) == preDeps.end()) { if (!CheckDependencies(dep, preDeps, database)) { database.Close(); return false; } preDeps.push_back(dep->ID()); } } database.Close(); return true; }
int CActiveAEDSP::GetAudioDSPAddonId(const AddonPtr &addon) const { CSingleLock lock(m_critUpdateSection); for (auto &entry : m_addonMap) { if (entry.second->ID() == addon->ID()) { return entry.first; } } return -1; }
int CPVRClients::GetClientId(const AddonPtr &client) const { CSingleLock lock(m_critSection); for (auto &entry : m_clientMap) { if (entry.second->ID() == client->ID()) { return entry.first; } } return -1; }
bool CAddonInstaller::DoInstall(const AddonPtr &addon, const CStdString &hash, bool update, const CStdString &referer, bool background) { // check whether we already have the addon installing CSingleLock lock(m_critSection); if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end()) return false; // check whether all the dependencies are available or not // TODO: we currently assume that dependencies will install correctly (and each of their dependencies and so on). // it may be better to install the dependencies first to minimise the chance of an addon becoming orphaned due to // missing deps. if (!CheckDependencies(addon)) { CGUIDialogKaiToast::QueueNotification(addon->Icon(), addon->Name(), g_localizeStrings.Get(24044), TOAST_DISPLAY_TIME, false); return false; } if (background) { unsigned int jobID = CJobManager::GetInstance().AddJob(new CAddonInstallJob(addon, hash, update, referer), this); m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(jobID))); } else { m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(0))); lock.Leave(); CAddonInstallJob job(addon, hash, update, referer); if (!job.DoWork()) { // TODO: dump something to debug log? return false; } lock.Enter(); JobMap::iterator i = m_downloadJobs.find(addon->ID()); m_downloadJobs.erase(i); } return true; }
int CPVRDatabase::Persist(const AddonPtr client) { int iReturn(-1); /* invalid client uid or name */ if (client->Name().IsEmpty() || client->ID().IsEmpty()) { CLog::Log(LOGERROR, "PVR - %s - invalid client uid or name", __FUNCTION__); return iReturn; } /* only add this client if it's not already in the database */ iReturn = GetClientId(client->ID()); if (iReturn <= 0) { CStdString strQuery = FormatSQL("INSERT INTO clients (sName, sUid) VALUES ('%s', '%s');", client->Name().c_str(), client->ID().c_str()); if (ExecuteQuery(strQuery)) iReturn = (int) m_pDS->lastinsertid(); } return iReturn; }
bool CAddonInstaller::DoInstall(const AddonPtr &addon, const RepositoryPtr& repo, const std::string &hash /* = "" */, bool background /* = true */, bool modal /* = false */) { // check whether we already have the addon installing CSingleLock lock(m_critSection); if (m_downloadJobs.find(addon->ID()) != m_downloadJobs.end()) return false; CAddonInstallJob* installJob = new CAddonInstallJob(addon, repo, hash); if (background) { unsigned int jobID = CJobManager::GetInstance().AddJob(installJob, this); m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(jobID))); m_idle.Reset(); return true; } m_downloadJobs.insert(make_pair(addon->ID(), CDownloadJob(0))); m_idle.Reset(); lock.Leave(); bool result = false; if (modal) result = installJob->DoModal(); else result = installJob->DoWork(); delete installJob; lock.Enter(); JobMap::iterator i = m_downloadJobs.find(addon->ID()); m_downloadJobs.erase(i); if (m_downloadJobs.empty()) m_idle.Set(); return result; }
bool CAddonMgr::CanAddonBeInstalled(const AddonPtr& addon) { if (addon == NULL) return false; CSingleLock lock(m_critSection); // can't install already installed addon if (IsAddonInstalled(addon->ID())) return false; // can't install broken addons if (!addon->Props().broken.empty()) return false; return true; }
int CAddonDatabase::AddAddon(const AddonPtr& addon, int idRepo) { try { if (NULL == m_pDB.get()) return -1; if (NULL == m_pDS.get()) return -1; std::string sql = PrepareSQL("insert into addon (id, type, name, summary," "description, stars, path, icon, changelog, " "fanart, addonID, version, author, disclaimer, minversion)" " values(NULL, '%s', '%s', '%s', '%s', %i," "'%s', '%s', '%s', '%s', '%s','%s','%s','%s','%s')", TranslateType(addon->Type(),false).c_str(), addon->Name().c_str(), addon->Summary().c_str(), addon->Description().c_str(),addon->Stars(), addon->Path().c_str(), addon->Props().icon.c_str(), addon->ChangeLog().c_str(),addon->FanArt().c_str(), addon->ID().c_str(), addon->Version().asString().c_str(), addon->Author().c_str(),addon->Disclaimer().c_str(), addon->MinVersion().asString().c_str()); m_pDS->exec(sql.c_str()); int idAddon = (int)m_pDS->lastinsertid(); sql = PrepareSQL("insert into addonlinkrepo (idRepo, idAddon) values (%i,%i)",idRepo,idAddon); m_pDS->exec(sql.c_str()); const InfoMap &info = addon->ExtraInfo(); for (InfoMap::const_iterator i = info.begin(); i != info.end(); ++i) { sql = PrepareSQL("insert into addonextra(id, key, value) values (%i, '%s', '%s')", idAddon, i->first.c_str(), i->second.c_str()); m_pDS->exec(sql.c_str()); } const ADDONDEPS &deps = addon->GetDeps(); for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i) { sql = PrepareSQL("insert into dependencies(id, addon, version, optional) values (%i, '%s', '%s', %i)", idAddon, i->first.c_str(), i->second.first.asString().c_str(), i->second.second ? 1 : 0); m_pDS->exec(sql.c_str()); } return idAddon; } catch (...) { CLog::Log(LOGERROR, "%s failed on addon '%s'", __FUNCTION__, addon->Name().c_str()); } return -1; }
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 CActiveAEDSP::StopAudioDSPAddon(AddonPtr addon, bool bRestart) { CSingleLock lock(m_critSection); int iId = GetAudioDSPAddonId(addon->ID()); AE_DSP_ADDON mappedAddon; if (GetReadyAudioDSPAddon(iId, mappedAddon)) { if (bRestart) mappedAddon->ReCreate(); else mappedAddon->Destroy(); return true; } return false; }
bool CAddonMgr::GetAddon(const CStdString &str, AddonPtr &addon, const TYPE &type/*=ADDON_UNKNOWN*/, bool enabledOnly /*= true*/) { CSingleLock lock(m_critSection); cp_status_t status; cp_plugin_info_t *cpaddon = m_cpluff->get_plugin_info(m_cp_context, str.c_str(), &status); if (status == CP_OK && cpaddon) { addon = GetAddonFromDescriptor(cpaddon); m_cpluff->release_info(m_cp_context, cpaddon); if (addon.get() && enabledOnly && m_database.IsAddonDisabled(addon->ID())) return false; return NULL != addon.get(); } if (cpaddon) m_cpluff->release_info(m_cp_context, cpaddon); return false; }
void CAddonInstaller::InstallFromXBMCRepo(const set<CStdString> &addonIDs) { // first check we have the main repository updated... AddonPtr addon; if (CAddonMgr::Get().GetAddon("repository.xbmc.org", addon)) { VECADDONS addons; CAddonDatabase database; database.Open(); if (!database.GetRepository(addon->ID(), addons)) { RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addon); addons = CRepositoryUpdateJob::GrabAddons(repo, false); } } // now install the addons for (set<CStdString>::const_iterator i = addonIDs.begin(); i != addonIDs.end(); ++i) CAddonInstaller::Get().Install(*i); }
void CAddonDatabase::SetPropertiesFromAddon(const AddonPtr& addon, CFileItemPtr& pItem) { pItem->SetProperty("Addon.ID", addon->ID()); pItem->SetProperty("Addon.Type", TranslateType(addon->Type(),true)); pItem->SetProperty("Addon.intType", TranslateType(addon->Type())); pItem->SetProperty("Addon.Name", addon->Name()); pItem->SetProperty("Addon.Version", addon->Version().c_str()); pItem->SetProperty("Addon.Summary", addon->Summary()); pItem->SetProperty("Addon.Description", addon->Description()); pItem->SetProperty("Addon.Creator", addon->Author()); pItem->SetProperty("Addon.Disclaimer", addon->Disclaimer()); pItem->SetProperty("Addon.Rating", addon->Stars()); CStdString starrating; starrating.Format("rating%d.png", addon->Stars()); pItem->SetProperty("Addon.StarRating",starrating); pItem->SetProperty("Addon.Path", addon->Path()); pItem->SetProperty("Addon.Broken", addon->Props().broken); }