JSONRPC_STATUS CAddonsOperations::GetAddons(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { vector<TYPE> addonTypes; TYPE addonType = TranslateType(parameterObject["type"].asString()); CVariant enabled = parameterObject["enabled"]; addonTypes.push_back(addonType); VECADDONS addons; for (vector<TYPE>::const_iterator typeIt = addonTypes.begin(); typeIt != addonTypes.end(); ++typeIt) { VECADDONS typeAddons; if (*typeIt == ADDON_UNKNOWN) { if (!enabled.isBoolean()) { CAddonMgr::GetInstance().GetAllAddons(typeAddons, false); CAddonMgr::GetInstance().GetAllAddons(typeAddons, true); } else CAddonMgr::GetInstance().GetAllAddons(typeAddons, enabled.asBoolean()); } else { if (!enabled.isBoolean()) { CAddonMgr::GetInstance().GetAddons(*typeIt, typeAddons, false); VECADDONS enabledAddons; CAddonMgr::GetInstance().GetAddons(*typeIt, enabledAddons, true); typeAddons.insert(typeAddons.end(), enabledAddons.begin(), enabledAddons.end()); } else CAddonMgr::GetInstance().GetAddons(*typeIt, typeAddons, enabled.asBoolean()); } addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } // remove library addons for (int index = 0; index < (int)addons.size(); index++) { if ((addons.at(index)->Type() <= ADDON_UNKNOWN || addons.at(index)->Type() >= ADDON_MAX)) { addons.erase(addons.begin() + index); index--; } } int start, end; HandleLimits(parameterObject, result, addons.size(), start, end); CAddonDatabase addondb; for (int index = start; index < end; index++) FillDetails(addons.at(index), parameterObject["properties"], result["addons"], addondb, true); return OK; }
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 CLanguageResource::FindLanguageAddonByName(const std::string &legacyLanguage, std::string &addonId, const VECADDONS &languageAddons /* = VECADDONS() */) { if (legacyLanguage.empty()) return false; VECADDONS addons; if (!languageAddons.empty()) addons = languageAddons; else if (!CAddonMgr::GetInstance().GetInstalledAddons(addons, ADDON_RESOURCE_LANGUAGE) || addons.empty()) return false; // try to find a language that matches the old language in name or id for (VECADDONS::const_iterator addon = addons.begin(); addon != addons.end(); ++addon) { const CLanguageResource* languageAddon = static_cast<CLanguageResource*>(addon->get()); // check if the old language matches the language addon id, the language // locale or the language addon name if (legacyLanguage.compare((*addon)->ID()) == 0 || languageAddon->GetLocale().Equals(legacyLanguage) || StringUtils::EqualsNoCase(legacyLanguage, languageAddon->Name())) { addonId = (*addon)->ID(); return true; } } return false; }
void CGUIDialogAddonInfo::OnUninstall() { if (!m_localAddon.get()) return; // ensure the addon is not a dependency of other installed addons VECADDONS addons; CStdStringArray deps; CAddonMgr::Get().GetAllAddons(addons); for (VECADDONS::iterator it = addons.begin(); it != addons.end();++it) { if ((*it)->GetDeps().find(m_localAddon->ID()) != (*it)->GetDeps().end()) deps.push_back((*it)->Name()); } if (!CAddonInstaller::Get().CheckDependencies(m_localAddon) && deps.size()) { CStdString strLine0, strLine1; StringUtils::JoinString(deps, ", ", strLine1); strLine0.Format(g_localizeStrings.Get(24046), m_localAddon->Name().c_str()); CGUIDialogOK::ShowAndGetInput(24037, strLine0, strLine1, 24047); return; } // ensure the addon isn't disabled in our database CAddonDatabase database; database.Open(); database.DisableAddon(m_localAddon->ID(), false); CJobManager::GetInstance().AddJob(new CAddonUnInstallJob(m_localAddon), &CAddonInstaller::Get()); CAddonMgr::Get().RemoveAddon(m_localAddon->ID()); Close(); }
bool CGUIDialogAddonInfo::PromptIfDependency(int heading, int line2) { if (!m_localAddon) return false; VECADDONS addons; vector<string> deps; CAddonMgr::Get().GetAllAddons(addons); for (VECADDONS::const_iterator it = addons.begin(); it != addons.end();++it) { ADDONDEPS::const_iterator i = (*it)->GetDeps().find(m_localAddon->ID()); if (i != (*it)->GetDeps().end() && !i->second.second) // non-optional dependency deps.push_back((*it)->Name()); } if (!deps.empty()) { string line0 = StringUtils::Format(g_localizeStrings.Get(24046), m_localAddon->Name().c_str()); string line1 = StringUtils::Join(deps, ", "); CGUIDialogOK::ShowAndGetInput(heading, line0, line1, line2); return true; } return false; }
CRepository::FetchStatus CRepository::FetchIfChanged(const std::string& oldChecksum, std::string& checksum, VECADDONS& addons) const { checksum = ""; std::vector<std::tuple<DirInfo const&, std::string>> dirChecksums; for (const auto& dir : m_dirs) { if (!dir.checksum.empty()) { std::string part; if (!FetchChecksum(dir.checksum, part)) { CLog::Log(LOGERROR, "CRepository: failed read '%s'", dir.checksum.c_str()); return STATUS_ERROR; } dirChecksums.emplace_back(dir, part); checksum += part; } } if (oldChecksum == checksum && !oldChecksum.empty()) return STATUS_NOT_MODIFIED; for (const auto& dirTuple : dirChecksums) { VECADDONS tmp; if (!FetchIndex(std::get<0>(dirTuple), std::get<1>(dirTuple), tmp)) return STATUS_ERROR; addons.insert(addons.end(), tmp.begin(), tmp.end()); } return STATUS_OK; }
bool CGUIDialogAddonInfo::PromptIfDependency(int heading, int line2) { if (!m_localAddon) return false; VECADDONS addons; std::vector<std::string> deps; CServiceBroker::GetAddonMgr().GetAddons(addons); for (VECADDONS::const_iterator it = addons.begin(); it != addons.end();++it) { auto i = std::find_if((*it)->GetDependencies().begin(), (*it)->GetDependencies().end(), [&](const DependencyInfo& other){return other.id == m_localAddon->ID();}); if (i != (*it)->GetDependencies().end() && !i->optional) // non-optional dependency deps.push_back((*it)->Name()); } if (!deps.empty()) { std::string line0 = StringUtils::Format(g_localizeStrings.Get(24046).c_str(), m_localAddon->Name().c_str()); std::string line1 = StringUtils::Join(deps, ", "); HELPERS::ShowOKDialogLines(CVariant{heading}, CVariant{std::move(line0)}, CVariant{std::move(line1)}, CVariant{line2}); return true; } return false; }
CRepository::FetchStatus CRepository::FetchIfChanged(const std::string& oldChecksum, std::string& checksum, VECADDONS& addons) const { checksum = ""; for (const auto& dir : m_dirs) { if (!dir.checksum.empty()) { std::string part; if (!FetchChecksum(dir.checksum, part)) { CLog::Log(LOGERROR, "CRepository: failed read '%s'", dir.checksum.c_str()); return STATUS_ERROR; } checksum += part; } } if (oldChecksum == checksum && !oldChecksum.empty()) return STATUS_NOT_MODIFIED; for (const auto& dir : m_dirs) { VECADDONS tmp; if (!FetchIndex(dir, tmp)) return STATUS_ERROR; addons.insert(addons.end(), tmp.begin(), tmp.end()); } return STATUS_OK; }
void CGUIDialogSubtitles::FillServices() { ClearServices(); VECADDONS addons; ADDON::CAddonMgr::Get().GetAddons(ADDON_SUBTITLE_MODULE, addons, true); if (addons.empty()) { UpdateStatus(NO_SERVICES); return; } for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://", false)); m_serviceItems->Add(item); } // Bind our services to the UI CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems); OnMessage(msg); // TODO: Default service support will need to check through the items to find the CFileItem in the loop above. SetService(m_serviceItems->Get(0)->GetProperty("Addon.ID").asString()); }
virtual void Run() { VECADDONS addons; CAddonMgr::Get().GetAllOutdatedAddons(addons, true); // get local for (VECADDONS::iterator i = addons.begin(); i != addons.end(); ++i) { std::string referer = StringUtils::Format("Referer=%s-%s.zip",(*i)->ID().c_str(),(*i)->Version().asString().c_str()); CAddonInstaller::Get().Install((*i)->ID(), true, referer); // force install } }
bool CPVRClients::UpdateAddons(void) { VECADDONS addons; PVR_CLIENT addon; bool bReturn(CAddonMgr::GetInstance().GetAddons(addons, ADDON_PVRDLL)); size_t usableClients; bool bDisable(false); if (bReturn) { CSingleLock lock(m_critSection); m_addons = addons; } usableClients = m_addons.size(); // handle "new" addons which aren't yet in the db - these have to be added first for (VECADDONS::const_iterator it = addons.begin(); it != addons.end(); ++it) { if (RegisterClient(*it) < 0) bDisable = true; else { addon = std::dynamic_pointer_cast<CPVRClient>(*it); bDisable = addon && addon->NeedsConfiguration() && addon->HasSettings() && !addon->HasUserSettings(); } if (bDisable) { CLog::Log(LOGDEBUG, "%s - disabling add-on '%s'", __FUNCTION__, (*it)->Name().c_str()); CAddonMgr::GetInstance().DisableAddon((*it)->ID()); usableClients--; } } if ((!bReturn || usableClients == 0) && !m_bNoAddonWarningDisplayed && !CAddonMgr::GetInstance().HasInstalledAddons(ADDON_PVRDLL) && (g_PVRManager.IsStarted() || g_PVRManager.IsInitialising())) { // No PVR add-ons could be found // You need a tuner, backend software, and an add-on for the backend to be able to use PVR. // Please visit http://kodi.wiki/view/PVR to learn more. m_bNoAddonWarningDisplayed = true; CGUIDialogOK::ShowAndGetInput(CVariant{19271}, CVariant{19272}); CSettings::GetInstance().SetBool(CSettings::SETTING_PVRMANAGER_ENABLED, false); CGUIMessage msg(GUI_MSG_UPDATE, WINDOW_SETTINGS_MYPVR, 0); g_windowManager.SendThreadMessage(msg, WINDOW_SETTINGS_MYPVR); } return bReturn; }
bool CAddonMgr::GetAllAddons(VECADDONS &addons, bool enabled /*= true*/, bool allowRepos /* = false */) { for (int i = ADDON_UNKNOWN+1; i < ADDON_VIZ_LIBRARY; ++i) { if (!allowRepos && ADDON_REPOSITORY == (TYPE)i) continue; VECADDONS temp; if (CAddonMgr::Get().GetAddons((TYPE)i, temp, enabled)) addons.insert(addons.end(), temp.begin(), temp.end()); } return !addons.empty(); }
void CAddonMgr::StopServices() { CLog::Log(LOGDEBUG, "ADDON: Stopping service addons."); VECADDONS services; if (!GetAddons(ADDON_SERVICE, services)) return; for (IVECADDONS it = services.begin(); it != services.end(); ++it) { boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(*it); if (service) service->Stop(); } }
int CHTTPWebinterfaceAddonsHandler::HandleHTTPRequest(const HTTPRequest &request) { m_response = ADDON_HEADER; VECADDONS addons; CAddonMgr::Get().GetAddons(ADDON_WEB_INTERFACE, addons); IVECADDONS addons_it; for (addons_it=addons.begin(); addons_it!=addons.end(); addons_it++) m_response += "<li><a href=/addons/"+ (*addons_it)->ID() + "/>" + (*addons_it)->Name() + "</a></li>\n"; m_response += "</ul>\n</body></html>"; m_responseType = HTTPMemoryDownloadNoFreeCopy; m_responseCode = MHD_HTTP_OK; return MHD_YES; }
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); }
std::vector<std::string> CAddonSystemSettings::MigrateAddons(std::function<void(void)> onMigrate) { auto getIncompatible = [](){ VECADDONS incompatible; CServiceBroker::GetAddonMgr().GetAddons(incompatible); incompatible.erase(std::remove_if(incompatible.begin(), incompatible.end(), [](const AddonPtr a){ return CServiceBroker::GetAddonMgr().IsCompatible(*a); }), incompatible.end()); return incompatible; }; if (getIncompatible().empty()) return std::vector<std::string>(); if (CServiceBroker::GetSettings().GetInt(CSettings::SETTING_ADDONS_AUTOUPDATES) == AUTO_UPDATES_ON) { onMigrate(); if (CServiceBroker::GetRepositoryUpdater().CheckForUpdates()) CServiceBroker::GetRepositoryUpdater().Await(); CLog::Log(LOGINFO, "ADDON: waiting for add-ons to update..."); CAddonInstaller::GetInstance().InstallUpdatesAndWait(); } auto incompatible = getIncompatible(); for (const auto& addon : incompatible) CLog::Log(LOGNOTICE, "ADDON: %s version %s is incompatible", addon->ID().c_str(), addon->Version().asString().c_str()); std::vector<std::string> changed; for (const auto& addon : incompatible) { if (!UnsetActive(addon)) { CLog::Log(LOGWARNING, "ADDON: failed to unset %s", addon->ID().c_str()); continue; } if (!CServiceBroker::GetAddonMgr().DisableAddon(addon->ID())) { CLog::Log(LOGWARNING, "ADDON: failed to disable %s", addon->ID().c_str()); } changed.push_back(addon->Name()); } return changed; }
bool CAddonMgr::StartServices() { CLog::Log(LOGDEBUG, "ADDON: Starting service addons."); VECADDONS services; if (!GetAddons(ADDON_SERVICE, services)) return false; bool ret = true; for (IVECADDONS it = services.begin(); it != services.end(); ++it) { boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(*it); if (service) ret &= service->Start(); } return ret; }
bool CActiveAEDSP::UpdateAddons(void) { VECADDONS addons; AE_DSP_ADDON dspAddon; bool bReturn(CAddonMgr::GetInstance().GetAddons(ADDON_ADSPDLL, addons, true)); size_t usableAddons; if (bReturn) { CSingleLock lock(m_critUpdateSection); m_addons = addons; } usableAddons = m_addons.size(); /* handle "new" addons which aren't yet in the db - these have to be added first */ for (VECADDONS::const_iterator itr = addons.begin(); itr != addons.end(); ++itr) { dspAddon = std::dynamic_pointer_cast<CActiveAEDSPAddon>(*itr); bool newRegistration = false; if (RegisterAudioDSPAddon(dspAddon, &newRegistration) < 0 || newRegistration) { CAddonMgr::GetInstance().DisableAddon(dspAddon->ID()); --usableAddons; } } if ((!bReturn || usableAddons == 0) && !m_noAddonWarningDisplayed && !CAddonMgr::GetInstance().HasAddons(ADDON_ADSPDLL, false) && IsActivated()) { // No audio DSP add-ons could be found // You need a add-on installed for the process of audio DSP signal. System becomes disabled. m_noAddonWarningDisplayed = true; CGUIDialogOK::ShowAndGetInput(CVariant{19273}, CVariant{19274}); CSettings::GetInstance().SetBool(CSettings::SETTING_AUDIOOUTPUT_DSPADDONSENABLED, false); CGUIMessage msg(GUI_MSG_UPDATE, WINDOW_SETTINGS_SYSTEM, 0); g_windowManager.SendThreadMessage(msg, WINDOW_SETTINGS_SYSTEM); CApplicationMessenger::GetInstance().SendMsg(TMSG_SETAUDIODSPSTATE, ACTIVE_AE_DSP_STATE_OFF); } return bReturn; }
void CAddonMgr::StopServices(const bool onlylogin) { CLog::Log(LOGDEBUG, "ADDON: Stopping service addons."); VECADDONS services; if (!GetAddons(ADDON_SERVICE, services)) return; for (IVECADDONS it = services.begin(); it != services.end(); ++it) { boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(*it); if (service) { if ( (onlylogin && service->GetStartOption() == CService::LOGIN) || (!onlylogin) ) service->Stop(); } } }
CDateTime CRepositoryUpdater::LastUpdated() const { VECADDONS repos; if (!CAddonMgr::GetInstance().GetAddons(repos, ADDON_REPOSITORY) || repos.empty()) return CDateTime(); CAddonDatabase db; db.Open(); std::vector<CDateTime> updateTimes; std::transform(repos.begin(), repos.end(), std::back_inserter(updateTimes), [&](const AddonPtr& repo) { auto lastCheck = db.LastChecked(repo->ID()); if (lastCheck.first.IsValid() && lastCheck.second == repo->Version()) return lastCheck.first; return CDateTime(); }); return *std::min_element(updateTimes.begin(), updateTimes.end()); }
void CGUIDialogSubtitles::FillServices() { std::string previousService = m_currentService; ClearServices(); VECADDONS addons; ADDON::CAddonMgr::GetInstance().GetAddons(addons, ADDON_SUBTITLE_MODULE); if (addons.empty()) { UpdateStatus(NO_SERVICES); return; } std::string defaultService; const CFileItem &item = g_application.CurrentUnstackedItem(); if (item.GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS || item.GetVideoContentType() == VIDEODB_CONTENT_EPISODES) // Set default service for tv shows defaultService = CSettings::GetInstance().GetString(CSettings::SETTING_SUBTITLES_TV); else // Set default service for filemode and movies defaultService = CSettings::GetInstance().GetString(CSettings::SETTING_SUBTITLES_MOVIE); std::string service = addons.front()->ID(); for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); ++addonIt) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://" + (*addonIt)->ID(), false)); m_serviceItems->Add(item); // If we don't have used a previous service use the default service, otherwise use the previous service if ((previousService.empty() && (*addonIt)->ID() == defaultService) || (*addonIt)->ID() == previousService) service = (*addonIt)->ID(); } // Bind our services to the UI CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems); OnMessage(msg); SetService(service); }
bool CAddonMgr::StartServices(const bool beforelogin) { CLog::Log(LOGDEBUG, "ADDON: Starting service addons."); VECADDONS services; if (!GetAddons(ADDON_SERVICE, services)) return false; bool ret = true; for (IVECADDONS it = services.begin(); it != services.end(); ++it) { boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(*it); if (service) { if ( (beforelogin && service->GetStartOption() == CService::STARTUP) || (!beforelogin && service->GetStartOption() == CService::LOGIN) ) ret &= service->Start(); } } return ret; }
void CGUIDialogSubtitles::FillServices() { ClearServices(); VECADDONS addons; ADDON::CAddonMgr::Get().GetAddons(ADDON_SUBTITLE_MODULE, addons, true); if (addons.empty()) { UpdateStatus(NO_SERVICES); return; } std::string defaultService; const CFileItem &item = g_application.CurrentUnstackedItem(); if (item.GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS || item.GetVideoContentType() == VIDEODB_CONTENT_EPISODES) // Set default service for tv shows defaultService = CSettings::Get().GetString("subtitles.tv"); else // Set default service for filemode and movies defaultService = CSettings::Get().GetString("subtitles.movie"); std::string service = addons.front()->ID(); for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://", false)); m_serviceItems->Add(item); if ((*addonIt)->ID() == defaultService) service = (*addonIt)->ID(); } // Bind our services to the UI CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems); OnMessage(msg); SetService(service); }
JSONRPC_STATUS CAddonsOperations::GetAddons(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { std::vector<TYPE> addonTypes; TYPE addonType = CAddonInfo::TranslateType(parameterObject["type"].asString()); CPluginSource::Content content = CPluginSource::Translate(parameterObject["content"].asString()); CVariant enabled = parameterObject["enabled"]; CVariant installed = parameterObject["installed"]; // ignore the "content" parameter if the type is specified but not a plugin or script if (addonType != ADDON_UNKNOWN && addonType != ADDON_PLUGIN && addonType != ADDON_SCRIPT) content = CPluginSource::UNKNOWN; if (addonType >= ADDON_VIDEO && addonType <= ADDON_EXECUTABLE) { addonTypes.push_back(ADDON_PLUGIN); addonTypes.push_back(ADDON_SCRIPT); switch (addonType) { case ADDON_VIDEO: content = CPluginSource::VIDEO; break; case ADDON_AUDIO: content = CPluginSource::AUDIO; break; case ADDON_IMAGE: content = CPluginSource::IMAGE; break; case ADDON_GAME: content = CPluginSource::GAME; break; case ADDON_EXECUTABLE: content = CPluginSource::EXECUTABLE; break; default: break; } } else addonTypes.push_back(addonType); VECADDONS addons; for (std::vector<TYPE>::const_iterator typeIt = addonTypes.begin(); typeIt != addonTypes.end(); ++typeIt) { VECADDONS typeAddons; if (*typeIt == ADDON_UNKNOWN) { if (!enabled.isBoolean()) //All { if (!installed.isBoolean() || installed.asBoolean()) CServiceBroker::GetAddonMgr().GetInstalledAddons(typeAddons); if (!installed.isBoolean() || (installed.isBoolean() && !installed.asBoolean())) CServiceBroker::GetAddonMgr().GetInstallableAddons(typeAddons); } else if (enabled.asBoolean() && (!installed.isBoolean() || installed.asBoolean())) //Enabled CServiceBroker::GetAddonMgr().GetAddons(typeAddons); else if (!installed.isBoolean() || installed.asBoolean()) CServiceBroker::GetAddonMgr().GetDisabledAddons(typeAddons); } else { if (!enabled.isBoolean()) //All { if (!installed.isBoolean() || installed.asBoolean()) CServiceBroker::GetAddonMgr().GetInstalledAddons(typeAddons, *typeIt); if (!installed.isBoolean() || (installed.isBoolean() && !installed.asBoolean())) CServiceBroker::GetAddonMgr().GetInstallableAddons(typeAddons, *typeIt); } else if (enabled.asBoolean() && (!installed.isBoolean() || installed.asBoolean())) //Enabled CServiceBroker::GetAddonMgr().GetAddons(typeAddons, *typeIt); else if (!installed.isBoolean() || installed.asBoolean()) CServiceBroker::GetAddonMgr().GetDisabledAddons(typeAddons, *typeIt); } addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } // remove library addons for (int index = 0; index < (int)addons.size(); index++) { PluginPtr plugin; if (content != CPluginSource::UNKNOWN) plugin = std::dynamic_pointer_cast<CPluginSource>(addons.at(index)); if ((addons.at(index)->Type() <= ADDON_UNKNOWN || addons.at(index)->Type() >= ADDON_MAX) || ((content != CPluginSource::UNKNOWN && plugin == NULL) || (plugin != NULL && !plugin->Provides(content)))) { addons.erase(addons.begin() + index); index--; } } int start, end; HandleLimits(parameterObject, result, addons.size(), start, end); CAddonDatabase addondb; for (int index = start; index < end; index++) FillDetails(addons.at(index), parameterObject["properties"], result["addons"], addondb, true); return OK; }
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString path1(strPath); URIUtils::RemoveSlashAtEnd(path1); CURL path(path1); items.ClearProperties(); items.SetContent("addons"); VECADDONS addons; // get info from repository bool reposAsFolders = true; if (path.GetHostName().Equals("enabled")) { CAddonMgr::Get().GetAllAddons(addons, true); items.SetProperty("reponame",g_localizeStrings.Get(24062)); items.SetLabel(g_localizeStrings.Get(24062)); } else if (path.GetHostName().Equals("disabled")) { // grab all disabled addons, including disabled repositories reposAsFolders = false; CAddonMgr::Get().GetAllAddons(addons, false, true); items.SetProperty("reponame",g_localizeStrings.Get(24039)); items.SetLabel(g_localizeStrings.Get(24039)); } else if (path.GetHostName().Equals("outdated")) { reposAsFolders = false; CAddonMgr::Get().GetAllOutdatedAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24043)); items.SetLabel(g_localizeStrings.Get(24043)); } else if (path.GetHostName().Equals("repos")) { CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true); items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons } else if (path.GetHostName().Equals("sources")) { return GetScriptsAndPlugins(path.GetFileName(), items); } else if (path.GetHostName().Equals("all")) { CAddonDatabase database; database.Open(); database.GetAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24032)); items.SetLabel(g_localizeStrings.Get(24032)); } else if (path.GetHostName().Equals("search")) { CStdString search(path.GetFileName()); if (search.IsEmpty() && !GetKeyboardInput(16017, search)) return false; items.SetProperty("reponame",g_localizeStrings.Get(283)); items.SetLabel(g_localizeStrings.Get(283)); CAddonDatabase database; database.Open(); database.Search(search, addons); GenerateListing(path, addons, items, true); path.SetFileName(search); items.SetPath(path.Get()); return true; } else { reposAsFolders = false; AddonPtr addon; CAddonMgr::Get().GetAddon(path.GetHostName(),addon); if (!addon) return false; // ensure our repos are up to date CAddonInstaller::Get().UpdateRepos(false, true); CAddonDatabase database; database.Open(); database.GetRepository(addon->ID(),addons); items.SetProperty("reponame",addon->Name()); items.SetLabel(addon->Name()); } if (path.GetFileName().IsEmpty()) { if (!path.GetHostName().Equals("repos")) { for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i) { for (unsigned int j=0;j<addons.size();++j) { if (addons[j]->IsType((TYPE)i)) { CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true))); item->SetPath(URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false))); item->m_bIsFolder = true; CStdString thumb = GetIcon((TYPE)i); if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb)) item->SetArt("thumb", thumb); items.Add(item); break; } } } items.SetPath(strPath); return true; } } else { TYPE type = TranslateType(path.GetFileName()); items.SetProperty("addoncategory",TranslateType(type, true)); items.SetLabel(TranslateType(type, true)); items.SetPath(strPath); // FIXME: Categorisation of addons needs adding here for (unsigned int j=0;j<addons.size();++j) { if (!addons[j]->IsType(type)) addons.erase(addons.begin()+j--); } } items.SetPath(strPath); GenerateListing(path, addons, items, reposAsFolders); // check for available updates if (path.GetHostName().Equals("enabled")) { CAddonDatabase database; database.Open(); for (int i=0;i<items.Size();++i) { AddonPtr addon2; database.GetAddon(items[i]->GetProperty("Addon.ID").asString(),addon2); if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version").asString()) && !database.IsAddonBlacklisted(addon2->ID(),addon2->Version().c_str())) { items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068)); items[i]->SetProperty("Addon.UpdateAvail", true); } } } if (path.GetHostName().Equals("repos") && items.Size() > 1) { CFileItemPtr item(new CFileItem("addons://all/",true)); item->SetLabel(g_localizeStrings.Get(24032)); items.Add(item); } return true; }
int CGUIWindowAddonBrowser::SelectAddonID(const std::vector<ADDON::TYPE> &types, std::vector<std::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 -1; // can't show the "Get More" button if we already show installable addons if (showInstallable) showMore = false; CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(); if (!dialog) return -1; // get rid of any invalid addon types std::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 -1; // get all addons to show VECADDONS addons; if (showInstalled) { for (std::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 if (*type == ADDON_GAME) CAddonsDirectory::GetScriptsAndPlugins("game", typeAddons); else CAddonMgr::GetInstance().GetAddons(typeAddons, *type); addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } } if (showInstallable || showMore) { VECADDONS installableAddons; if (CAddonMgr::GetInstance().GetInstallableAddons(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 (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (pAddon->IsType(*type)) { matchesType = true; break; } } if (matchesType) { ++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 -1; // 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())); item->SetLabel2((*addon)->Summary()); if (!items.Contains(item->GetPath())) { items.Add(item); addonMap.insert(std::make_pair(item->GetPath(), *addon)); } } if (items.IsEmpty() && !showNone) return -1; std::string heading; for (std::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.empty()) { for (std::vector<std::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->Open(); // 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(); for (int i : dialog->GetSelectedItems()) { const CFileItemPtr& item = items.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::GetInstance().IsAddonInstalled(addon->ID())) { AddonPtr installedAddon; if (!CAddonInstaller::GetInstance().InstallModal(addon->ID(), installedAddon, false)) continue; } // if the addon is disabled we need to enable it if (CAddonMgr::GetInstance().IsAddonDisabled(addon->ID())) CAddonMgr::GetInstance().EnableAddon(addon->ID()); } } addonIDs.push_back(item->GetPath()); } return 1; }
void CPVRDatabase::UpdateTables(int iVersion) { if (iVersion < 13) m_pDS->exec("ALTER TABLE channels ADD idEpg integer;"); if (iVersion < 20) m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool"); if (iVersion < 21) m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer"); if (iVersion < 22) m_pDS->exec("ALTER TABLE channels ADD bIsLocked bool"); if (iVersion < 23) m_pDS->exec("ALTER TABLE channelgroups ADD iLastWatched integer"); if (iVersion < 24) m_pDS->exec("ALTER TABLE channels ADD bIsUserSetName bool"); if (iVersion < 25) m_pDS->exec("DROP TABLE IF EXISTS channelsettings"); if (iVersion < 26) { m_pDS->exec("ALTER TABLE channels ADD iClientSubChannelNumber integer"); m_pDS->exec("UPDATE channels SET iClientSubChannelNumber = 0"); m_pDS->exec("ALTER TABLE map_channelgroups_channels ADD iSubChannelNumber integer"); m_pDS->exec("UPDATE map_channelgroups_channels SET iSubChannelNumber = 0"); } if (iVersion < 27) m_pDS->exec("ALTER TABLE channelgroups ADD bIsHidden bool"); if (iVersion < 28) { VECADDONS addons; CAddonDatabase database; if (database.Open() && CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) { /** find all old client IDs */ std::string strQuery(PrepareSQL("SELECT idClient, sUid FROM clients")); m_pDS->query(strQuery); while (!m_pDS->eof() && !addons.empty()) { /** try to find an add-on that matches the sUid */ for (VECADDONS::iterator it = addons.begin(); it != addons.end(); ++it) { if ((*it)->ID() == m_pDS->fv(1).get_asString()) { /** try to get the current ID from the database */ int iAddonId = database.GetAddonId(*it); /** register a new id if it didn't exist */ if (iAddonId <= 0) iAddonId = database.AddAddon(*it, 0); if (iAddonId > 0) { // this fails when an id becomes the id of one that's being replaced next iteration // but since almost everyone only has 1 add-on enabled... /** update the iClientId in the channels table */ strQuery = PrepareSQL("UPDATE channels SET iClientId = %u WHERE iClientId = %u", iAddonId, m_pDS->fv(0).get_asInt()); m_pDS->exec(strQuery); /** no need to check this add-on again */ it = addons.erase(it); break; } } } m_pDS->next(); } } m_pDS->exec("DROP TABLE clients"); } if (iVersion < 29) m_pDS->exec("ALTER TABLE channelgroups ADD iPosition integer"); }
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 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; }
bool CPVRClients::AutoconfigureClients(void) { bool bReturn(false); std::vector<PVR_CLIENT> autoConfigAddons; PVR_CLIENT addon; VECADDONS map; CAddonMgr::GetInstance().GetInstalledAddons(map, ADDON_PVRDLL); /** get the auto-configurable add-ons */ for (VECADDONS::iterator it = map.begin(); it != map.end(); ++it) { if (CAddonMgr::GetInstance().IsAddonDisabled((*it)->ID())) { addon = std::dynamic_pointer_cast<CPVRClient>(*it); if (addon->CanAutoconfigure()) autoConfigAddons.push_back(addon); } } /** no configurable add-ons found */ if (autoConfigAddons.empty()) return bReturn; /** display a progress bar while trying to auto-configure add-ons */ CGUIDialogExtendedProgressBar *loadingProgressDialog = (CGUIDialogExtendedProgressBar *)g_windowManager.GetWindow(WINDOW_DIALOG_EXT_PROGRESS); CGUIDialogProgressBarHandle* progressHandle = loadingProgressDialog->GetHandle(g_localizeStrings.Get(19688)); // Scanning for PVR services progressHandle->SetPercentage(0); progressHandle->SetText(g_localizeStrings.Get(19688)); //Scanning for PVR services /** start zeroconf and wait a second to get some responses */ CZeroconfBrowser::GetInstance()->Start(); for (std::vector<PVR_CLIENT>::iterator it = autoConfigAddons.begin(); !bReturn && it != autoConfigAddons.end(); ++it) (*it)->AutoconfigureRegisterType(); unsigned iIterations(0); float percentage(0.0f); float percentageStep(100.0f / PVR_CLIENT_AVAHI_SCAN_ITERATIONS); progressHandle->SetPercentage(percentage); /** while no add-ons were configured within 20 iterations */ while (!bReturn && iIterations++ < PVR_CLIENT_AVAHI_SCAN_ITERATIONS) { /** check each disabled add-on */ for (std::vector<PVR_CLIENT>::iterator it = autoConfigAddons.begin(); !bReturn && it != autoConfigAddons.end(); ++it) { if (addon->Autoconfigure()) { progressHandle->SetPercentage(100.0f); progressHandle->MarkFinished(); /** enable the add-on */ CAddonMgr::GetInstance().EnableAddon((*it)->ID()); CSingleLock lock(m_critSection); m_addons.push_back(*it); bReturn = true; } } /** wait a while and try again */ if (!bReturn) { percentage += percentageStep; progressHandle->SetPercentage(percentage); Sleep(PVR_CLIENT_AVAHI_SLEEP_TIME_MS); } } progressHandle->SetPercentage(100.0f); progressHandle->MarkFinished(); return bReturn; }