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; }
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; }
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 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(); }
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; }
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; }