bool CAddonUnInstallJob::DoWork() { if (m_addon->Type() == ADDON_PVRDLL) { // stop the pvr manager, so running pvr add-ons are stopped and closed PVR::CPVRManager::Get().Stop(); } if (m_addon->Type() == ADDON_SERVICE) { boost::shared_ptr<CService> service = boost::dynamic_pointer_cast<CService>(m_addon); if (service) service->Stop(); } AddonPtr repoPtr = CAddonInstallJob::GetRepoForAddon(m_addon); RepositoryPtr therepo = boost::dynamic_pointer_cast<CRepository>(repoPtr); if (therepo && !therepo->Props().libname.empty()) { CFileItemList dummy; CStdString s = StringUtils::Format("plugin://%s/?action=uninstall" "&package=%s", therepo->ID().c_str(), m_addon->ID().c_str()); if (!CDirectory::GetDirectory(s, dummy)) return false; } else { if (!CAddonInstallJob::DeleteAddon(m_addon->Path())) return false; } OnPostUnInstall(); 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; }
bool CAddonInstaller::InstallOrUpdate(const std::string &addonID, bool background /* = true */, bool modal /* = false */) { AddonPtr addon; CAddonMgr::GetInstance().GetAddon(addonID, addon, ADDON_UNKNOWN, false); // check whether we have it available in a repository RepositoryPtr repo; if (!GetRepoForAddon(addonID, repo)) return false; std::string hash; if (!CAddonInstallJob::GetAddonWithHash(addonID, repo->ID(), addon, hash)) return false; return DoInstall(addon, repo, hash, background, modal); }
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); } } }
void CAddonMgr::UpdateRepos(bool force) { CSingleLock lock(m_critSection); if (!force && m_watch.IsRunning() && m_watch.GetElapsedSeconds() < 600) return; m_watch.StartZero(); VECADDONS addons; GetAddons(ADDON_REPOSITORY,addons); for (unsigned int i=0;i<addons.size();++i) { RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addons[i]); CDateTime lastUpdate = m_database.GetRepoTimestamp(repo->ID()); if (force || !lastUpdate.IsValid() || lastUpdate + CDateTimeSpan(0,6,0,0) < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGDEBUG,"Checking repository %s for updates",repo->Name().c_str()); CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(repo), NULL); } } }
bool CAddonUnInstallJob::DoWork() { ADDON::OnPreUnInstall(m_addon); //TODO: looks broken. it just calls the repo with the most recent version, not the owner RepositoryPtr repoPtr; CAddonInstaller::GetRepoForAddon(m_addon->ID(), repoPtr); if (repoPtr != NULL && !repoPtr->Props().libname.empty()) { CFileItemList dummy; std::string s = StringUtils::Format("plugin://%s/?action=uninstall&package=%s", repoPtr->ID().c_str(), m_addon->ID().c_str()); if (!CDirectory::GetDirectory(s, dummy)) return false; } else { //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 CAddonInstallJob::GetAddonWithHash(const std::string& addonID, ADDON::AddonPtr& addon, std::string& hash) { CAddonDatabase database; if (!database.Open()) return false; if (!database.GetAddon(addonID, addon)) return false; AddonPtr ptr = GetRepoForAddon(addon); if (ptr == NULL) return false; RepositoryPtr repo = std::dynamic_pointer_cast<CRepository>(ptr); if (repo == NULL) return false; hash = repo->GetAddonHash(addon); return true; }
bool CAddonInstallJob::GetAddonWithHash(const std::string& addonID, RepositoryPtr& repo, ADDON::AddonPtr& addon, std::string& hash) { if (!CAddonMgr::GetInstance().FindInstallableById(addonID, addon)) return false; AddonPtr tmp; if (!CAddonMgr::GetInstance().GetAddon(addon->Origin(), tmp, ADDON_REPOSITORY)) return false; repo = std::static_pointer_cast<CRepository>(tmp); return repo->GetAddonHash(addon, hash); }
bool CAddonInstaller::Install(const CStdString &addonID, bool force, const CStdString &referer, bool background) { AddonPtr addon; bool addonInstalled = CAddonMgr::Get().GetAddon(addonID, addon, ADDON_UNKNOWN, false); if (addonInstalled && !force) return true; // 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); return DoInstall(addon, hash, addonInstalled, referer, background); } return false; }
bool CAddonUnInstallJob::DoWork() { m_addon->OnPreUnInstall(); AddonPtr repoPtr = CAddonInstallJob::GetRepoForAddon(m_addon); RepositoryPtr therepo = boost::dynamic_pointer_cast<CRepository>(repoPtr); if (therepo && !therepo->Props().libname.empty()) { CFileItemList dummy; std::string s = StringUtils::Format("plugin://%s/?action=uninstall" "&package=%s", therepo->ID().c_str(), m_addon->ID().c_str()); if (!CDirectory::GetDirectory(s, dummy)) return false; } else { if (!CAddonInstallJob::DeleteAddon(m_addon->Path())) return false; } OnPostUnInstall(); return true; }
bool CAddonInstallJob::Install(const std::string &installFrom, const AddonPtr& repo) { SetText(g_localizeStrings.Get(24079)); ADDONDEPS deps = m_addon->GetDeps(); unsigned int totalSteps = static_cast<unsigned int>(deps.size()); if (ShouldCancel(0, totalSteps)) return false; // The first thing we do is install dependencies for (ADDONDEPS::iterator it = deps.begin(); it != deps.end(); ++it) { if (it->first != "xbmc.metadata") { const std::string &addonID = it->first; const AddonVersion &version = it->second.first; bool optional = it->second.second; AddonPtr dependency; bool haveAddon = CAddonMgr::GetInstance().GetAddon(addonID, dependency, ADDON_UNKNOWN, false); if ((haveAddon && !dependency->MeetsVersion(version)) || (!haveAddon && !optional)) { // we have it but our version isn't good enough, or we don't have it and we need it // 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::GetInstance().HasJob(addonID)) { while (CAddonInstaller::GetInstance().HasJob(addonID)) Sleep(50); if (!CAddonMgr::GetInstance().IsAddonInstalled(addonID)) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to install dependency %s", m_addon->ID().c_str(), addonID.c_str()); ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); return false; } } // don't have the addon or the addon isn't new enough - grab it (no new job for these) else if (IsModal()) { RepositoryPtr repoForDep; AddonPtr addon; std::string hash; if (!CAddonInstaller::GetRepoForAddon(addonID, repoForDep) || !CAddonInstallJob::GetAddonWithHash(addonID, repoForDep->ID(), addon, hash)) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to find dependency %s", m_addon->ID().c_str(), addonID.c_str()); ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); return false; } CAddonInstallJob dependencyJob(addon, repoForDep, hash); // pass our progress indicators to the temporary job and don't allow it to // show progress or information updates (no progress, title or text changes) dependencyJob.SetProgressIndicators(GetProgressBar(), GetProgressDialog(), false, false); if (!dependencyJob.DoModal()) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to install dependency %s", m_addon->ID().c_str(), addonID.c_str()); ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); return false; } } else if (!CAddonInstaller::GetInstance().InstallOrUpdate(addonID, false)) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to install dependency %s", m_addon->ID().c_str(), addonID.c_str()); ReportInstallError(m_addon->ID(), m_addon->ID(), g_localizeStrings.Get(24085)); return false; } } } if (ShouldCancel(std::distance(deps.begin(), it), totalSteps)) return false; } SetText(g_localizeStrings.Get(24086)); SetProgress(0); // now that we have all our dependencies, we can install our add-on if (repo != NULL) { CFileItemList dummy; std::string s = StringUtils::Format("plugin://%s/?action=install&package=%s&version=%s", repo->ID().c_str(), m_addon->ID().c_str(), m_addon->Version().asString().c_str()); if (!CDirectory::GetDirectory(s, dummy)) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: installation of repository failed", m_addon->ID().c_str()); ReportInstallError(m_addon->ID(), m_addon->ID()); return false; } } else { std::string 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); AddonPtr addon; if (!DoFileOperation(CFileOperationJob::ActionReplace, install, "special://home/addons/", false) || !CAddonMgr::GetInstance().LoadAddonDescription(addonFolder, addon)) { // failed extraction or failed to load addon description DeleteAddon(addonFolder); std::string addonID = URIUtils::GetFileName(addonFolder); CLog::Log(LOGERROR, "CAddonInstallJob[%s]: could not read addon description of %s", addonID.c_str(), addonFolder.c_str()); ReportInstallError(addonID, addonID); return false; } } SetProgress(100); return true; }