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 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 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 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 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(); }
void CGUIDialogAddonInfo::OnEnable(bool enable) { if (!m_localAddon.get()) return; CStdString xbmcPath = CSpecialProtocol::TranslatePath("special://xbmc/addons"); CAddonDatabase database; database.Open(); database.DisableAddon(m_localAddon->ID(), !enable); database.Close(); if (m_localAddon->Type() == ADDON_PVRDLL && enable) g_application.StartPVRManager(); SetItem(m_item); UpdateControls(); g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); }
void CGUIDialogAddonInfo::OnEnable(bool enable) { if (!m_localAddon.get()) return; CStdString xbmcPath = _P("special://xbmc/addons"); CAddonDatabase database; database.Open(); if (m_localAddon->Type() == ADDON_PVRDLL && m_localAddon->Path().Left(xbmcPath.size()).Equals(xbmcPath)) database.EnableSystemPVRAddon(m_localAddon->ID(), enable); else database.DisableAddon(m_localAddon->ID(), !enable); if (m_localAddon->Type() == ADDON_PVRDLL && enable) g_application.StartPVRManager(); SetItem(m_item); UpdateControls(); g_windowManager.SendMessage(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_UPDATE); }
bool CAddonInstallJob::DoWork() { SetTitle(StringUtils::Format(g_localizeStrings.Get(24057).c_str(), m_addon->Name().c_str())); SetProgress(0); // check whether all the dependencies are available or not SetText(g_localizeStrings.Get(24058)); std::pair<std::string, std::string> failedDep; if (!CAddonInstaller::GetInstance().CheckDependencies(m_addon, failedDep)) { std::string details = StringUtils::Format(g_localizeStrings.Get(24142).c_str(), failedDep.first.c_str(), failedDep.second.c_str()); CLog::Log(LOGERROR, "CAddonInstallJob[%s]: %s", m_addon->ID().c_str(), details.c_str()); ReportInstallError(m_addon->ID(), m_addon->ID(), details); return false; } std::string installFrom; if (!m_repo || m_repo->Props().libname.empty()) { // Addons are installed by downloading the .zip package on the server to the local // packages folder, then extracting from the local .zip package into the addons folder // Both these functions are achieved by "copying" using the vfs. std::string dest = "special://home/addons/packages/"; std::string package = URIUtils::AddFileToFolder("special://home/addons/packages/", URIUtils::GetFileName(m_addon->Path())); if (URIUtils::HasSlashAtEnd(m_addon->Path())) { // passed in a folder - all we need do is copy it across installFrom = m_addon->Path(); } else { CAddonDatabase db; if (!db.Open()) { CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to open database", m_addon->ID().c_str()); ReportInstallError(m_addon->ID(), m_addon->ID()); return false; } std::string md5; // check that we don't already have a valid copy if (!m_hash.empty() && CFile::Exists(package)) { if (db.GetPackageHash(m_addon->ID(), package, md5) && m_hash != md5) { db.RemovePackage(package); CFile::Delete(package); } } // zip passed in - download + extract if (!CFile::Exists(package)) { std::string path(m_addon->Path()); if (!DownloadPackage(path, dest)) { CFile::Delete(package); CLog::Log(LOGERROR, "CAddonInstallJob[%s]: failed to download %s", m_addon->ID().c_str(), package.c_str()); ReportInstallError(m_addon->ID(), URIUtils::GetFileName(package)); return false; } } // at this point we have the package - check that it is valid SetText(g_localizeStrings.Get(24077)); if (!m_hash.empty()) { md5 = CUtil::GetFileMD5(package); if (!StringUtils::EqualsNoCase(md5, m_hash)) { CFile::Delete(package); CLog::Log(LOGERROR, "CAddonInstallJob[%s]: MD5 mismatch after download %s", m_addon->ID().c_str(), package.c_str()); ReportInstallError(m_addon->ID(), URIUtils::GetFileName(package)); return false; } db.AddPackage(m_addon->ID(), package, md5); } // check the archive as well - should have just a single folder in the root CURL archive = URIUtils::CreateArchivePath("zip", CURL(package), ""); CFileItemList archivedFiles; CDirectory::GetDirectory(archive, archivedFiles); if (archivedFiles.Size() != 1 || !archivedFiles[0]->m_bIsFolder) { // invalid package db.RemovePackage(package); CFile::Delete(package); CLog::Log(LOGERROR, "CAddonInstallJob[%s]: invalid package %s", m_addon->ID().c_str(), package.c_str()); ReportInstallError(m_addon->ID(), URIUtils::GetFileName(package)); return false; } installFrom = archivedFiles[0]->GetPath(); } m_repo.reset(); } // run any pre-install functions ADDON::OnPreInstall(m_addon); // perform install if (!Install(installFrom, m_repo)) return false; CAddonMgr::GetInstance().UnregisterAddon(m_addon->ID()); CAddonMgr::GetInstance().FindAddons(); // run any post-install guff CEventLog::GetInstance().Add( EventPtr(new CAddonManagementEvent(m_addon, m_update ? 24065 : 24064)), !IsModal() && CSettings::GetInstance().GetBool(CSettings::SETTING_GENERAL_ADDONNOTIFICATIONS), false); ADDON::OnPostInstall(m_addon, m_update, IsModal()); //Clear addon from the disabled table CAddonDatabase database; database.Open(); database.DisableAddon(m_addon->ID(), false); // and we're done! MarkFinished(); return true; }
bool CPVRDatabase::CreateTables() { bool bReturn(false); try { if (!CDatabase::CreateTables()) return false; BeginTransaction(); CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'clients'", __FUNCTION__); m_pDS->exec( "CREATE TABLE clients (" "idClient integer primary key, " "sName varchar(64), " "sUid varchar(32)" ")" ); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channels (" "idChannel integer primary key, " "iUniqueId integer, " "bIsRadio bool, " "bIsHidden bool, " "bIsUserSetIcon bool, " "sIconPath varchar(255), " "sChannelName varchar(64), " "bIsVirtual bool, " "bEPGEnabled bool, " "sEPGScraper varchar(32), " "iLastWatched integer," // TODO use mapping table "iClientId integer, " "iClientChannelNumber integer, " "sInputFormat varchar(32), " "sStreamURL varchar(255), " "iEncryptionSystem integer, " "idEpg integer" ")" ); m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);"); // TODO use a mapping table so multiple backends per channel can be implemented // CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channels_clients'", __FUNCTION__); // m_pDS->exec( // "CREATE TABLE map_channels_clients (" // "idChannel integer primary key, " // "idClient integer, " // "iClientChannelNumber integer," // "sInputFormat string," // "sStreamURL string," // "iEncryptionSystem integer" // ");" // ); // m_pDS->exec("CREATE UNIQUE INDEX idx_idChannel_idClient on map_channels_clients(idChannel, idClient);"); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelgroups (" "idGroup integer primary key," "bIsRadio bool, " "iGroupType integer, " "sName varchar(64)" ")" ); m_pDS->exec("CREATE INDEX idx_channelgroups_bIsRadio on channelgroups(bIsRadio);"); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE map_channelgroups_channels (" "idChannel integer, " "idGroup integer, " "iChannelNumber integer" ")" ); m_pDS->exec("CREATE UNIQUE INDEX idx_idGroup_idChannel on map_channelgroups_channels(idGroup, idChannel);"); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelsettings'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelsettings (" "idChannel integer primary key, " "iInterlaceMethod integer, " "iViewMode integer, " "fCustomZoomAmount float, " "fPixelRatio float, " "iAudioStream integer, " "iSubtitleStream integer," "fSubtitleDelay float, " "bSubtitles bool, " "fBrightness float, " "fContrast float, " "fGamma float," "fVolumeAmplification float, " "fAudioDelay float, " "bOutputToAllSpeakers bool, " "bCrop bool, " "iCropLeft integer, " "iCropRight integer, " "iCropTop integer, " "iCropBottom integer, " "fSharpness float, " "fNoiseReduction float, " "fCustomVerticalShift float, " "bCustomNonLinStretch bool, " "bPostProcess bool, " "iScalingMethod integer, " "iDeinterlaceMode integer " ")" ); CommitTransaction(); bReturn = true; } catch (...) { CLog::Log(LOGERROR, "PVR - %s - unable to create PVR database tables (error %i)", __FUNCTION__, (int)GetLastError()); RollbackTransaction(); bReturn = false; } if (bReturn) { // disable all PVR add-on when started the first time ADDON::VECADDONS addons; if ((bReturn = CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true, false)) == false) 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++) database.DisableAddon(it->get()->ID()); database.Close(); } } return bReturn; }
bool CPVRDatabase::UpdateOldVersion(int iVersion) { bool bReturn = true; BeginTransaction(); try { if (iVersion < 11) { CLog::Log(LOGERROR, "PVR - %s - updating from table versions < 11 not supported. please delete '%s'", __FUNCTION__, GetBaseDBName()); bReturn = false; } else { if (iVersion < 12) m_pDS->exec("DROP VIEW vw_last_watched;"); 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 < 18) { m_pDS->exec("DROP INDEX idx_channels_iClientId;"); m_pDS->exec("DROP INDEX idx_channels_iLastWatched;"); m_pDS->exec("DROP INDEX idx_channels_bIsRadio;"); m_pDS->exec("DROP INDEX idx_channels_bIsHidden;"); m_pDS->exec("DROP INDEX idx_idChannel_idGroup;"); m_pDS->exec("DROP INDEX idx_idGroup_iChannelNumber;"); m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);"); m_pDS->exec("CREATE UNIQUE INDEX idx_idGroup_idChannel on map_channelgroups_channels(idGroup, idChannel);"); } 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 ((bReturn = CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true, false)) == false) 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())) database.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"); } } catch (...) { CLog::Log(LOGERROR, "PVR - %s - error attempting to update the database version!", __FUNCTION__); bReturn = false; } if (bReturn) CommitTransaction(); else RollbackTransaction(); return bReturn; }