diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/utils/RssManager.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/utils/RssManager.cpp')
-rw-r--r-- | xbmc/utils/RssManager.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/xbmc/utils/RssManager.cpp b/xbmc/utils/RssManager.cpp new file mode 100644 index 0000000..b8d350c --- /dev/null +++ b/xbmc/utils/RssManager.cpp @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "RssManager.h" + +#include "ServiceBroker.h" +#include "addons/AddonInstaller.h" +#include "addons/AddonManager.h" +#include "addons/addoninfo/AddonType.h" +#include "interfaces/builtins/Builtins.h" +#include "profiles/ProfileManager.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#include "settings/lib/Setting.h" +#include "utils/FileUtils.h" +#include "utils/RssReader.h" +#include "utils/StringUtils.h" +#include "utils/log.h" + +#include <mutex> +#include <utility> + +using namespace KODI::MESSAGING; + + +CRssManager::CRssManager() +{ + m_bActive = false; +} + +CRssManager::~CRssManager() +{ + Stop(); +} + +CRssManager& CRssManager::GetInstance() +{ + static CRssManager sRssManager; + return sRssManager; +} + +void CRssManager::OnSettingsLoaded() +{ + Load(); +} + +void CRssManager::OnSettingsUnloaded() +{ + Clear(); +} + +void CRssManager::OnSettingAction(const std::shared_ptr<const CSetting>& setting) +{ + if (setting == NULL) + return; + + const std::string &settingId = setting->GetId(); + if (settingId == CSettings::SETTING_LOOKANDFEEL_RSSEDIT) + { + ADDON::AddonPtr addon; + if (!CServiceBroker::GetAddonMgr().GetAddon("script.rss.editor", addon, + ADDON::OnlyEnabled::CHOICE_YES)) + { + if (!ADDON::CAddonInstaller::GetInstance().InstallModal( + "script.rss.editor", addon, ADDON::InstallModalPrompt::CHOICE_YES)) + return; + } + CBuiltins::GetInstance().Execute("RunScript(script.rss.editor)"); + } +} + +void CRssManager::Start() + { + m_bActive = true; +} + +void CRssManager::Stop() +{ + std::unique_lock<CCriticalSection> lock(m_critical); + m_bActive = false; + for (unsigned int i = 0; i < m_readers.size(); i++) + { + if (m_readers[i].reader) + delete m_readers[i].reader; + } + m_readers.clear(); +} + +bool CRssManager::Load() +{ + const std::shared_ptr<CProfileManager> profileManager = CServiceBroker::GetSettingsComponent()->GetProfileManager(); + + std::unique_lock<CCriticalSection> lock(m_critical); + + std::string rssXML = profileManager->GetUserDataItem("RssFeeds.xml"); + if (!CFileUtils::Exists(rssXML)) + return false; + + CXBMCTinyXML rssDoc; + if (!rssDoc.LoadFile(rssXML)) + { + CLog::Log(LOGERROR, "CRssManager: error loading {}, Line {}\n{}", rssXML, rssDoc.ErrorRow(), + rssDoc.ErrorDesc()); + return false; + } + + const TiXmlElement *pRootElement = rssDoc.RootElement(); + if (pRootElement == NULL || !StringUtils::EqualsNoCase(pRootElement->ValueStr(), "rssfeeds")) + { + CLog::Log(LOGERROR, "CRssManager: error loading {}, no <rssfeeds> node", rssXML); + return false; + } + + m_mapRssUrls.clear(); + const TiXmlElement* pSet = pRootElement->FirstChildElement("set"); + while (pSet != NULL) + { + int iId; + if (pSet->QueryIntAttribute("id", &iId) == TIXML_SUCCESS) + { + RssSet set; + set.rtl = pSet->Attribute("rtl") != NULL && + StringUtils::CompareNoCase(pSet->Attribute("rtl"), "true") == 0; + const TiXmlElement* pFeed = pSet->FirstChildElement("feed"); + while (pFeed != NULL) + { + int iInterval; + if (pFeed->QueryIntAttribute("updateinterval", &iInterval) != TIXML_SUCCESS) + { + iInterval = 30; // default to 30 min + CLog::Log(LOGDEBUG, "CRssManager: no interval set, default to 30!"); + } + + if (pFeed->FirstChild() != NULL) + { + //! @todo UTF-8: Do these URLs need to be converted to UTF-8? + //! What about the xml encoding? + std::string strUrl = pFeed->FirstChild()->ValueStr(); + set.url.push_back(strUrl); + set.interval.push_back(iInterval); + } + pFeed = pFeed->NextSiblingElement("feed"); + } + + m_mapRssUrls.insert(std::make_pair(iId,set)); + } + else + CLog::Log(LOGERROR, "CRssManager: found rss url set with no id in RssFeeds.xml, ignored"); + + pSet = pSet->NextSiblingElement("set"); + } + + return true; +} + +bool CRssManager::Reload() +{ + Stop(); + if (!Load()) + return false; + Start(); + + return true; +} + +void CRssManager::Clear() +{ + std::unique_lock<CCriticalSection> lock(m_critical); + m_mapRssUrls.clear(); +} + +// returns true if the reader doesn't need creating, false otherwise +bool CRssManager::GetReader(int controlID, int windowID, IRssObserver* observer, CRssReader *&reader) +{ + std::unique_lock<CCriticalSection> lock(m_critical); + // check to see if we've already created this reader + for (unsigned int i = 0; i < m_readers.size(); i++) + { + if (m_readers[i].controlID == controlID && m_readers[i].windowID == windowID) + { + reader = m_readers[i].reader; + reader->SetObserver(observer); + reader->UpdateObserver(); + return true; + } + } + // need to create a new one + READERCONTROL readerControl; + readerControl.controlID = controlID; + readerControl.windowID = windowID; + reader = readerControl.reader = new CRssReader; + m_readers.push_back(readerControl); + return false; +} |