void CGUIDialogAddonInfo::OnInstall() { if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) return; if (m_localAddon || !m_item->HasAddonInfo()) return; std::string addonId = m_item->GetAddonInfo()->ID(); std::vector<std::pair<AddonVersion, std::string>> versions; CAddonDatabase database; if (!database.Open() || !database.GetAvailableVersions(addonId, versions) || versions.empty()) { CLog::Log(LOGERROR, "ADDON: no available versions of %s", addonId.c_str()); return; } int i = versions.size() == 1 ? 0 : AskForVersion(versions); if (i != -1) { Close(); CAddonInstaller::GetInstance().Install(addonId, versions[i].first, versions[i].second); } }
void CGUIDialogAddonInfo::GrabRollbackVersions() { CFileItemList items; XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS); items.Sort(SortByLabel, SortOrderAscending); CAddonDatabase db; db.Open(); for (int i=0;i<items.Size();++i) { if (items[i]->m_bIsFolder) continue; std::string ID, version; AddonVersion::SplitFileName(ID,version,items[i]->GetLabel()); if (ID == m_localAddon->ID()) { std::string hash, path(items[i]->GetPath()); if (db.GetPackageHash(m_localAddon->ID(), path, hash)) { std::string md5 = CUtil::GetFileMD5(path); if (md5 == hash) m_rollbackVersions.push_back(version); else /* The package has been corrupted */ { CLog::Log(LOGWARNING, "%s: Removing corrupt addon package %s.", __FUNCTION__, path.c_str()); CFile::Delete(path); db.RemovePackage(path); } } } } }
void CGUIDialogAddonInfo::OnRollback() { CGUIDialogContextMenu* dlg = (CGUIDialogContextMenu*)g_windowManager.GetWindow(WINDOW_DIALOG_CONTEXT_MENU); CAddonDatabase database; database.Open(); CContextButtons buttons; for (unsigned int i=0;i<m_rollbackVersions.size();++i) { CStdString label(m_rollbackVersions[i]); if (m_rollbackVersions[i].Equals(m_localAddon->Version().c_str())) label += " "+g_localizeStrings.Get(24094); if (database.IsAddonBlacklisted(m_localAddon->ID(),label)) label += " "+g_localizeStrings.Get(24095); buttons.Add(i,label); } int choice; if ((choice=dlg->ShowAndGetChoice(buttons)) > -1) { // blacklist everything newer for (unsigned int j=choice+1;j<m_rollbackVersions.size();++j) database.BlacklistAddon(m_localAddon->ID(),m_rollbackVersions[j]); CStdString path = "special://home/addons/packages/"; path += m_localAddon->ID()+"-"+m_rollbackVersions[choice]+".zip"; // needed as cpluff won't downgrade if (!m_localAddon->IsType(ADDON_SERVICE)) //we will handle this for service addons in CAddonInstallJob::OnPostInstall CAddonMgr::Get().RemoveAddon(m_localAddon->ID()); CAddonInstaller::Get().InstallFromZip(path); database.RemoveAddonFromBlacklist(m_localAddon->ID(),m_rollbackVersions[choice]); Close(); } }
void CAddonUnInstallJob::OnPostUnInstall() { if (m_addon->Type() == ADDON_REPOSITORY) { CAddonDatabase database; database.Open(); database.DeleteRepository(m_addon->ID()); } bool bSave(false); CFileItemList items; XFILE::CFavouritesDirectory::Load(items); for (int i=0; i < items.Size(); ++i) { if (items[i]->GetPath().find(m_addon->ID()) != std::string::npos) { items.Remove(items[i].get()); bSave = true; } } if (bSave) CFavouritesDirectory::Save(items); if (m_addon->Type() == ADDON_PVRDLL) { if (CSettings::Get().GetBool("pvrmanager.enabled")) PVR::CPVRManager::Get().Start(true); } }
bool CAddonUnInstallJob::DoWork() { ADDON::OnPreUnInstall(m_addon); //Unregister addon with the manager to ensure nothing tries //to interact with it while we are uninstalling. CAddonMgr::GetInstance().UnregisterAddon(m_addon->ID()); if (!DeleteAddon(m_addon->Path())) { CLog::Log(LOGERROR, "CAddonUnInstallJob[%s]: could not delete addon data.", m_addon->ID().c_str()); return false; } ClearFavourites(); AddonPtr addon; CAddonDatabase database; // try to get the addon object from the repository as the local one does not exist anymore // if that doesn't work fall back to the local one if (!database.Open() || !database.GetAddon(m_addon->ID(), addon) || addon == NULL) addon = m_addon; CEventLog::GetInstance().Add(EventPtr(new CAddonManagementEvent(addon, 24144))); CAddonMgr::GetInstance().OnPostUnInstall(m_addon->ID()); database.OnPostUnInstall(m_addon->ID()); ADDON::OnPostUnInstall(m_addon); return true; }
bool CAddonInstaller::Install(const std::string &addonID, bool force, const std::string &referer, bool background) { AddonPtr addon; bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false); if (addonInstalled && !force) return true; if (referer.empty()) { if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) return false; } // check whether we have it available in a repository CAddonDatabase database; database.Open(); if (database.GetAddon(addonID, addon)) { std::string repo; database.GetRepoForAddon(addonID,repo); AddonPtr ptr; CAddonMgr::Get().GetAddon(repo,ptr); RepositoryPtr therepo = boost::dynamic_pointer_cast<CRepository>(ptr); std::string hash; if (therepo) hash = therepo->GetAddonHash(addon); return DoInstall(addon, hash, addonInstalled, referer, background); } 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 CAddonInstaller::CheckDependencies(const AddonPtr &addon) { assert(addon.get()); ADDONDEPS deps = addon->GetDeps(); CAddonDatabase database; 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()); return false; } } // at this point we have our dep, so check that it's OK as well // TODO: should we assume that installed deps are OK? if (!CheckDependencies(dep)) return false; } return true; }
bool CAddonInstallJob::OnPreInstall() { // check whether this is an active skin - we need to unload it if so if (g_guiSettings.GetString("lookandfeel.skin") == m_addon->ID()) { CApplicationMessenger::Get().ExecBuiltIn("UnloadSkin", true); return true; } if (m_addon->Type() == ADDON_SERVICE) { CAddonDatabase database; database.Open(); bool running = !database.IsAddonDisabled(m_addon->ID()); //grab a current state database.DisableAddon(m_addon->ID(),false); // enable it so we can remove it?? // regrab from manager to have the correct path set AddonPtr addon; ADDON::CAddonMgr::Get().GetAddon(m_addon->ID(), addon); boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(addon); if (service) service->Stop(); CAddonMgr::Get().RemoveAddon(m_addon->ID()); // remove it return running; } if (m_addon->Type() == ADDON_PVRDLL) { // stop the pvr manager, so running pvr add-ons are stopped and closed PVR::CPVRManager::Get().Stop(); } return false; }
void CAddonsDirectory::GenerateListing(CURL &path, VECADDONS& addons, CFileItemList &items, bool reposAsFolders) { CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons"); items.ClearItems(); CAddonDatabase db; db.Open(); for (unsigned i=0; i < addons.size(); i++) { AddonPtr addon = addons[i]; CFileItemPtr pItem; if (reposAsFolders && addon->Type() == ADDON_REPOSITORY) pItem = FileItemFromAddon(addon, "addons://", true); else pItem = FileItemFromAddon(addon, path.Get(), false); AddonPtr addon2; if (CAddonMgr::Get().GetAddon(addon->ID(),addon2)) pItem->SetProperty("Addon.Status",g_localizeStrings.Get(305)); else if (db.IsOpen() && db.IsAddonDisabled(addon->ID())) pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24023)); if (!addon->Props().broken.IsEmpty()) pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24098)); if (addon2 && addon2->Version() < addon->Version()) { pItem->SetProperty("Addon.Status",g_localizeStrings.Get(24068)); pItem->SetProperty("Addon.UpdateAvail", true); } CAddonDatabase::SetPropertiesFromAddon(addon,pItem); items.Add(pItem); } db.Close(); }
void CAddonInstallJob::ReportInstallError(const CStdString& addonID, const CStdString& fileName) { AddonPtr addon; CAddonDatabase database; database.Open(); database.GetAddon(addonID, addon); if (addon) { AddonPtr addon2; CAddonMgr::Get().GetAddon(addonID, addon2); g_application.m_guiDialogKaiToast.QueueNotification( addon->Icon(), addon->Name(), g_localizeStrings.Get(addon2 ? 113 : 114), TOAST_DISPLAY_TIME, false); } else { g_application.m_guiDialogKaiToast.QueueNotification( CGUIDialogKaiToast::Error, fileName, g_localizeStrings.Get(114), TOAST_DISPLAY_TIME, false); } }
bool CRetroPlayerDialogs::InstallGameClient(const string &strId, const CFileItem &file, GameClientPtr &result) { // First, make sure the game client isn't installed CLog::Log(LOGDEBUG, "RetroPlayer: Trying to install game client %s", strId.c_str()); AddonPtr addon; bool installed = CAddonMgr::Get().GetAddon(strId, addon, ADDON_GAMEDLL, false); if (installed && addon) return false; // Now make sure it exists in a remote repository CAddonDatabase database; if (database.Open() && database.GetAddon(strId, addon)) { GameClientPtr gc = boost::dynamic_pointer_cast<CGameClient>(addon); if (gc && gc->CanOpen(file)) { CLog::Log(LOGDEBUG, "RetroPlayer: Installing game client %s", strId.c_str()); addon.reset(); if (CAddonInstaller::Get().PromptForInstall(strId, addon)) { gc = boost::dynamic_pointer_cast<CGameClient>(addon); if (gc) { result = gc; return true; } } } } return false; }
bool CAddonInstaller::InstallModal(const std::string &addonID, ADDON::AddonPtr &addon, bool promptForInstall /* = true */) { if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) return false; // we assume that addons that are enabled don't get to this routine (i.e. that GetAddon() has been called) if (CAddonMgr::GetInstance().GetAddon(addonID, addon, ADDON_UNKNOWN, false)) return false; // addon is installed but disabled, and the user has specifically activated something that needs // the addon - should we enable it? // check we have it available CAddonDatabase database; database.Open(); if (!database.GetAddon(addonID, addon)) return false; // if specified ask the user if he wants it installed if (promptForInstall) { if (HELPERS::ShowYesNoDialogLines(CVariant{24076}, CVariant{24100}, CVariant{addon->Name()}, CVariant{24101}) != DialogResponse::YES) { return false; } } if (!InstallOrUpdate(addonID, false, true)) return false; return CAddonMgr::GetInstance().GetAddon(addonID, addon); }
void CAddonUnInstallJob::OnPostUnInstall() { if (m_addon->Type() == ADDON_REPOSITORY) { CAddonDatabase database; database.Open(); database.DeleteRepository(m_addon->ID()); } }
VECSOURCES& CGUIViewStateAddonBrowser::GetSources() { m_sources.clear(); // we always have some enabled addons { CMediaSource share; share.strPath = "addons://enabled/"; share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; share.strName = g_localizeStrings.Get(24062); m_sources.push_back(share); } CAddonDatabase db; if (db.Open() && db.HasDisabledAddons()) { CMediaSource share; share.strPath = "addons://disabled/"; share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; share.strName = g_localizeStrings.Get(24039); m_sources.push_back(share); } if (CAddonMgr::Get().HasOutdatedAddons()) { CMediaSource share; share.strPath = "addons://outdated/"; share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; share.strName = g_localizeStrings.Get(24043); m_sources.push_back(share); } if (CAddonMgr::Get().HasAddons(ADDON_REPOSITORY,true)) { CMediaSource share; share.strPath = "addons://repos/"; share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; share.strName = g_localizeStrings.Get(24033); m_sources.push_back(share); } // add "install from zip" { CMediaSource share; share.strPath = "addons://install/"; share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; share.strName = g_localizeStrings.Get(24041); m_sources.push_back(share); } // add "search" { CMediaSource share; share.strPath = "addons://search/"; share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL; share.strName = g_localizeStrings.Get(137); m_sources.push_back(share); } return CGUIViewState::GetSources(); }
void CGUIDialogAddonInfo::OnUpdate() { if (!m_localAddon) return; std::vector<std::pair<AddonVersion, std::string>> versions; CAddonDatabase database; database.Open(); database.GetAvailableVersions(m_localAddon->ID(), versions); CFileItemList items; if (XFILE::CDirectory::GetDirectory("special://home/addons/packages/", items, ".zip", DIR_FLAG_NO_FILE_DIRS)) { for (int i = 0; i < items.Size(); ++i) { std::string packageId; std::string versionString; if (AddonVersion::SplitFileName(packageId, versionString, items[i]->GetLabel())) { if (packageId == m_localAddon->ID()) { std::string hash; std::string path(items[i]->GetPath()); if (database.GetPackageHash(m_localAddon->ID(), items[i]->GetPath(), hash)) { std::string md5 = CUtil::GetFileMD5(path); if (md5 == hash) versions.push_back(std::make_pair(AddonVersion(versionString), LOCAL_CACHE)); } } } } } if (versions.empty()) CGUIDialogOK::ShowAndGetInput(CVariant{21341}, CVariant{21342}); else { int i = AskForVersion(versions); if (i != -1) { Close(); //turn auto updating off if downgrading if (m_localAddon->Version() > versions[i].first) CAddonMgr::GetInstance().AddToUpdateBlacklist(m_localAddon->ID()); if (versions[i].second == LOCAL_CACHE) CAddonInstaller::GetInstance().InstallFromZip(StringUtils::Format( "special://home/addons/packages/%s-%s.zip", m_localAddon->ID().c_str(), versions[i].first.asString().c_str())); else CAddonInstaller::GetInstance().Install(m_localAddon->ID(), versions[i].first, versions[i].second); } } }
void CAddonInstallJob::OnPostInstall(bool reloadAddon) { if (m_addon->Type() < ADDON_VIZ_LIBRARY && g_settings.m_bAddonNotifications) { 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),"",""))) { g_guiSettings.SetString("lookandfeel.skin",m_addon->ID().c_str()); CGUIDialogKaiToast *toast = (CGUIDialogKaiToast *)g_windowManager.GetWindow(WINDOW_DIALOG_KAI_TOAST); if (toast) { toast->ResetTimer(); toast->Close(true); } CApplicationMessenger::Get().ExecBuiltIn("ReloadSkin"); } } if (m_addon->Type() == ADDON_SERVICE) { CAddonDatabase database; database.Open(); database.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 CPVRDatabase::UpdateTables(int iVersion) { if (iVersion < 13) m_pDS->exec("ALTER TABLE channels ADD idEpg integer;"); if (iVersion < 14) m_pDS->exec("ALTER TABLE channelsettings ADD fCustomVerticalShift float;"); if (iVersion < 15) { m_pDS->exec("ALTER TABLE channelsettings ADD bCustomNonLinStretch bool;"); m_pDS->exec("ALTER TABLE channelsettings ADD bPostProcess bool;"); m_pDS->exec("ALTER TABLE channelsettings ADD iScalingMethod integer;"); } if (iVersion < 16) { /* sqlite apparently can't delete columns from an existing table, so just leave the extra column alone */ } if (iVersion < 17) { m_pDS->exec("ALTER TABLE channelsettings ADD iDeinterlaceMode integer"); m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 2 WHERE iInterlaceMethod NOT IN (0,1)"); // anything other than none: method auto => mode force m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 1 WHERE iInterlaceMethod = 1"); // method auto => mode auto m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 0, iInterlaceMethod = 1 WHERE iInterlaceMethod = 0"); // method none => mode off, method auto } if (iVersion < 19) { // bit of a hack, but we need to keep the version/contents of the non-pvr databases the same to allow clean upgrades ADDON::VECADDONS addons; if (!CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__); else { CAddonDatabase database; database.Open(); for (IVECADDONS it = addons.begin(); it != addons.end(); it++) { if (!database.IsSystemPVRAddonEnabled(it->get()->ID())) CAddonMgr::Get().DisableAddon(it->get()->ID()); } database.Close(); } } 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"); }
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; }
void CGUIDialogAddonInfo::OnEnable(bool enable) { if (!m_localAddon.get()) return; CAddonDatabase database; database.Open(); database.DisableAddon(m_localAddon->ID(), !enable); SetItem(m_item); UpdateControls(); g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); }
void CAddonInstaller::PrunePackageCache() { std::map<std::string,CFileItemList*> packs; int64_t size = EnumeratePackageFolder(packs); int64_t limit = (int64_t)g_advancedSettings.m_addonPackageFolderSize * 1024 * 1024; if (size < limit) return; // Prune packages // 1. Remove the largest packages, leaving at least 2 for each add-on CFileItemList items; CAddonDatabase db; db.Open(); for (std::map<std::string,CFileItemList*>::const_iterator it = packs.begin(); it != packs.end(); ++it) { it->second->Sort(SortByLabel, SortOrderDescending); for (int j = 2; j < it->second->Size(); j++) items.Add(CFileItemPtr(new CFileItem(*it->second->Get(j)))); } items.Sort(SortBySize, SortOrderDescending); int i = 0; while (size > limit && i < items.Size()) { size -= items[i]->m_dwSize; db.RemovePackage(items[i]->GetPath()); CFileUtils::DeleteItem(items[i++], true); } if (size > limit) { // 2. Remove the oldest packages (leaving least 1 for each add-on) items.Clear(); for (std::map<std::string,CFileItemList*>::iterator it = packs.begin(); it != packs.end(); ++it) { if (it->second->Size() > 1) items.Add(CFileItemPtr(new CFileItem(*it->second->Get(1)))); } items.Sort(SortByDate, SortOrderAscending); i = 0; while (size > limit && i < items.Size()) { size -= items[i]->m_dwSize; db.RemovePackage(items[i]->GetPath()); CFileUtils::DeleteItem(items[i++],true); } } // clean up our mess for (std::map<std::string,CFileItemList*>::iterator it = packs.begin(); it != packs.end(); ++it) delete it->second; }
bool CGUIDialogAddonInfo::SetItem(const CFileItemPtr& item) { *m_item = *item; m_localAddon.reset(); m_addon.reset(); CAddonMgr::GetInstance().GetAddon(item->GetProperty("Addon.ID").asString(), m_localAddon, ADDON_UNKNOWN, false); CAddonDatabase database; database.Open(); database.GetAddon(item->GetProperty("Addon.ID").asString(), m_addon); return true; }
bool CAddonInstaller::CheckDependencies(const AddonPtr &addon, std::vector<std::string>& preDeps, CAddonDatabase &database, std::pair<std::string, std::string> &failedDep) { if (addon == NULL) return true; // a NULL addon has no dependencies if (!database.Open()) return false; ADDONDEPS deps = addon->GetDeps(); for (ADDONDEPS::const_iterator i = deps.begin(); i != deps.end(); ++i) { const std::string &addonID = i->first; const AddonVersion &version = i->second.first; bool optional = i->second.second; AddonPtr dep; bool haveAddon = CAddonMgr::GetInstance().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, "CAddonInstallJob[%s]: requires %s version %s which is not available", addon->ID().c_str(), addonID.c_str(), version.asString().c_str()); database.Close(); // fill in the details of the failed dependency failedDep.first = addon->ID(); failedDep.second = version.asString(); 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, failedDep)) { database.Close(); preDeps.push_back(dep->ID()); return false; } } } database.Close(); return true; }
bool CAddonInstaller::PromptForInstall(const std::string &addonID, AddonPtr &addon) { if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER)) return false; // we assume that addons that are enabled don't get to this routine (i.e. that GetAddon() has been called) if (CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false)) return false; // addon is installed but disabled, and the user has specifically activated something that needs // the addon - should we enable it? // check we have it available CAddonDatabase database; database.Open(); if (database.GetAddon(addonID, addon)) { // yes - ask user if they want it installed if (!CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(24076), g_localizeStrings.Get(24100), addon->Name().c_str(), g_localizeStrings.Get(24101))) return false; if (Install(addonID, true)) { CGUIDialogProgress *progress = (CGUIDialogProgress *)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); if (progress) { progress->SetHeading(13413); // Downloading progress->SetLine(0, ""); progress->SetLine(1, addon->Name()); progress->SetLine(2, ""); progress->SetPercentage(0); progress->StartModal(); while (true) { progress->Progress(); unsigned int percent; if (progress->IsCanceled()) { Cancel(addonID); break; } if (!GetProgress(addonID, percent)) break; progress->SetPercentage(percent); } progress->Close(); } return CAddonMgr::Get().GetAddon(addonID, addon); } } return false; }
CDateTime CAddonInstaller::LastRepoUpdate() const { CDateTime update; VECADDONS addons; CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons); for (unsigned int i=0;i<addons.size();++i) { CAddonDatabase database; database.Open(); CDateTime lastUpdate = database.GetRepoTimestamp(addons[i]->ID()); if (lastUpdate.IsValid() && lastUpdate > update) update = lastUpdate; } return update; }
bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, const std::string& repoID, ADDON::AddonPtr& addon, std::string& hash) { CAddonDatabase database; if (!database.Open()) return false; if (!database.GetAddon(addonID, addon)) return false; AddonPtr repo; if (!CAddonMgr::GetInstance().GetAddon(repoID, repo, ADDON_REPOSITORY)) return false; return std::static_pointer_cast<CRepository>(repo)->GetAddonHash(addon, hash); }
Addon::Addon(const char* cid, bool installed) throw (AddonException) { String id(cid ? cid : emptyString); // if the id wasn't passed then get the id from // the global dictionary if (id.empty()) id = getDefaultId(); // if we still don't have an id then bail if (id.empty()) throw AddonException("No valid addon id could be obtained. None was passed and the script wasn't executed in a normal xbmc manner."); bool success = ADDON::CAddonMgr::Get().GetAddon(id.c_str(), pAddon); if (!success && !installed) { CAddonDatabase addondb; addondb.Open(); success = addondb.GetAddon(id, pAddon); } // if we still fail we MAY be able to recover. if (!success) { // we need to check the version prior to trying a bw compatibility trick ADDON::AddonVersion version(getAddonVersion()); ADDON::AddonVersion allowable("1.0"); if (version <= allowable) { // try the default ... id = getDefaultId(); if (id.empty() || !ADDON::CAddonMgr::Get().GetAddon(id.c_str(), pAddon)) throw AddonException("Could not get AddonPtr!"); else CLog::Log(LOGERROR,"Use of deprecated functionality. Please to not assume that \"os.getcwd\" will return the script directory."); } else { throw AddonException("Could not get AddonPtr given a script id of %s." "If you are trying to use 'os.getcwd' to set the path, you cannot do that in a version %s plugin.", id.c_str(), version.asString().c_str()); } } CAddonMgr::Get().AddToUpdateableAddons(pAddon); }
void CGUIDialogAddonInfo::OnUninstall() { if (!m_localAddon.get()) return; // ensure the addon isn't disabled in our database CAddonDatabase database; database.Open(); database.DisableAddon(m_localAddon->ID(), false); CFileItemList list; list.Add(CFileItemPtr(new CFileItem(m_localAddon->Path(),true))); list[0]->Select(true); CJobManager::GetInstance().AddJob(new CFileOperationJob(CFileOperationJob::ActionDelete,list,""), &CAddonInstaller::Get()); CAddonMgr::Get().RemoveAddon(m_localAddon->ID()); Close(); }
bool CAddonInstaller::GetRepoForAddon(const std::string& addonId, RepositoryPtr& repoPtr) { CAddonDatabase database; if (!database.Open()) return false; auto repoId = database.GetAddonVersion(addonId).second; if (repoId.empty()) return false; AddonPtr tmp; if (!CAddonMgr::GetInstance().GetAddon(repoId, tmp, ADDON_REPOSITORY)) return false; repoPtr = std::static_pointer_cast<CRepository>(tmp); return true; }
void CAddonInstaller::Install(const CStdString &addonID, bool force, const CStdString &referer, bool background) { AddonPtr addon; bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon); if (addonInstalled && !force) return; // check whether we have it available in a repository CAddonDatabase database; database.Open(); if (database.GetAddon(addonID, addon)) { CStdString repo; database.GetRepoForAddon(addonID,repo); AddonPtr ptr; CAddonMgr::Get().GetAddon(repo,ptr); RepositoryPtr therepo = boost::dynamic_pointer_cast<CRepository>(ptr); CStdString hash; if (therepo) hash = therepo->GetAddonHash(addon); // check whether we already have the addon installing CSingleLock lock(m_critSection); if (m_downloadJobs.find(addonID) != m_downloadJobs.end()) return; // already installing this addon if (background) { unsigned int jobID = CJobManager::GetInstance().AddJob(new CAddonInstallJob(addon, hash, addonInstalled, 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, addonInstalled, referer); if (!job.DoWork()) { // TODO: dump something to debug log? } lock.Enter(); JobMap::iterator i = m_downloadJobs.find(addon->ID()); m_downloadJobs.erase(i); } } }