2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "RssManager.h"
22 #include "addons/AddonInstaller.h"
23 #include "addons/AddonManager.h"
24 #include "dialogs/GUIDialogYesNo.h"
25 #include "filesystem/File.h"
26 #include "interfaces/Builtins.h"
27 #include "profiles/ProfilesManager.h"
28 #include "settings/lib/Setting.h"
29 #include "threads/SingleLock.h"
30 #include "utils/log.h"
31 #include "utils/RssReader.h"
32 #include "utils/StringUtils.h"
35 using namespace XFILE;
37 CRssManager::CRssManager()
42 CRssManager::~CRssManager()
47 CRssManager& CRssManager::Get()
49 static CRssManager sRssManager;
53 void CRssManager::OnSettingsLoaded()
58 void CRssManager::OnSettingsUnloaded()
63 void CRssManager::OnSettingAction(const CSetting *setting)
68 const std::string &settingId = setting->GetId();
69 if (settingId == "lookandfeel.rssedit")
71 ADDON::AddonPtr addon;
72 ADDON::CAddonMgr::Get().GetAddon("script.rss.editor",addon);
75 if (!CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(24076), g_localizeStrings.Get(24100), "RSS Editor", g_localizeStrings.Get(24101)))
77 CAddonInstaller::Get().Install("script.rss.editor", true, "", false);
79 CBuiltins::Execute("RunScript(script.rss.editor)");
83 void CRssManager::Start()
88 void CRssManager::Stop()
90 CSingleLock lock(m_critical);
92 for (unsigned int i = 0; i < m_readers.size(); i++)
94 if (m_readers[i].reader)
95 delete m_readers[i].reader;
100 bool CRssManager::Load()
102 CSingleLock lock(m_critical);
103 string rssXML = CProfilesManager::Get().GetUserDataItem("RssFeeds.xml");
104 if (!CFile::Exists(rssXML))
108 if (!rssDoc.LoadFile(rssXML))
110 CLog::Log(LOGERROR, "CRssManager: error loading %s, Line %d\n%s", rssXML.c_str(), rssDoc.ErrorRow(), rssDoc.ErrorDesc());
114 const TiXmlElement *pRootElement = rssDoc.RootElement();
115 if (pRootElement == NULL || !StringUtils::EqualsNoCase(pRootElement->ValueStr(), "rssfeeds"))
117 CLog::Log(LOGERROR, "CRssManager: error loading %s, no <rssfeeds> node", rssXML.c_str());
121 m_mapRssUrls.clear();
122 const TiXmlElement* pSet = pRootElement->FirstChildElement("set");
126 if (pSet->QueryIntAttribute("id", &iId) == TIXML_SUCCESS)
129 set.rtl = pSet->Attribute("rtl") != NULL && strcasecmp(pSet->Attribute("rtl"), "true") == 0;
130 const TiXmlElement* pFeed = pSet->FirstChildElement("feed");
131 while (pFeed != NULL)
134 if (pFeed->QueryIntAttribute("updateinterval", &iInterval) != TIXML_SUCCESS)
136 iInterval = 30; // default to 30 min
137 CLog::Log(LOGDEBUG, "CRssManager: no interval set, default to 30!");
140 if (pFeed->FirstChild() != NULL)
142 // TODO: UTF-8: Do these URLs need to be converted to UTF-8?
143 // What about the xml encoding?
144 string strUrl = pFeed->FirstChild()->ValueStr();
145 set.url.push_back(strUrl);
146 set.interval.push_back(iInterval);
148 pFeed = pFeed->NextSiblingElement("feed");
151 m_mapRssUrls.insert(make_pair(iId,set));
154 CLog::Log(LOGERROR, "CRssManager: found rss url set with no id in RssFeeds.xml, ignored");
156 pSet = pSet->NextSiblingElement("set");
162 bool CRssManager::Reload()
172 void CRssManager::Clear()
174 CSingleLock lock(m_critical);
175 m_mapRssUrls.clear();
178 // returns true if the reader doesn't need creating, false otherwise
179 bool CRssManager::GetReader(int controlID, int windowID, IRssObserver* observer, CRssReader *&reader)
181 CSingleLock lock(m_critical);
182 // check to see if we've already created this reader
183 for (unsigned int i = 0; i < m_readers.size(); i++)
185 if (m_readers[i].controlID == controlID && m_readers[i].windowID == windowID)
187 reader = m_readers[i].reader;
188 reader->SetObserver(observer);
189 reader->UpdateObserver();
193 // need to create a new one
194 READERCONTROL readerControl;
195 readerControl.controlID = controlID;
196 readerControl.windowID = windowID;
197 reader = readerControl.reader = new CRssReader;
198 m_readers.push_back(readerControl);