MythTV  master
mythrssmanager.cpp
Go to the documentation of this file.
1 // qt
2 #include <QString>
3 #include <QFile>
4 #include <QDir>
5 
6 #include "mythdate.h"
7 #include "mythdirs.h"
8 #include "mythcontext.h"
9 #include "mythlogging.h"
10 
11 #include "mythrssmanager.h"
12 #include "netutils.h"
13 #include "rssparse.h"
14 #include "mythsorthelper.h"
15 
16 using namespace std;
17 
18 #define LOC QString("RSSSite: ")
19 
20 // ---------------------------------------------------
21 
23 {
24  m_updateFreq = (gCoreContext->GetNumSetting(
25  "rss.updateFreq", 6) * 3600 * 1000);
26 
27  m_timer = new QTimer();
28 
29  connect( m_timer, SIGNAL(timeout()),
30  this, SLOT(doUpdate()));
31 }
32 
34 {
35  delete m_timer;
36 }
37 
39 {
40  m_timer->start(m_updateFreq);
41 }
42 
44 {
45  m_timer->stop();
46 }
47 
49 {
50  m_sites = findAllDBRSS();
51 
52  for (RSSSite::rssList::iterator i = m_sites.begin();
53  i != m_sites.end(); ++i)
54  {
55  LOG(VB_GENERAL, LOG_INFO, LOC +
56  QString("Updating RSS Feed %1") .arg((*i)->GetTitle()));
57 
58  connect(*i, SIGNAL(finished(RSSSite*)),
59  this, SLOT(slotRSSRetrieved(RSSSite*)));
60  }
61 
62  slotRefreshRSS();
63 
64  m_timer->start(m_updateFreq);
65 }
66 
68 {
69  if (m_sites.empty())
70  {
71  emit finished();
72  return;
73  }
74 
75  RSSSite::rssList::iterator i = m_sites.begin();
76  for (; i != m_sites.end(); ++i)
77  {
78  (*i)->retrieve();
79  m_inprogress.append(*i);
80  }
81 }
82 
84 {
85  if (!site)
86  return;
87 
88  clearRSSArticles(site->GetTitle(), site->GetType());
89 
91  ResultItem::resultList::iterator it = rss.begin();
92  for (; it != rss.end(); ++it)
93  {
94  // Insert in the DB here.
95  insertRSSArticleInDB(site->GetTitle(), *it, site->GetType());
96  }
97 
98  m_inprogress.removeOne(site);
99  if (m_inprogress.isEmpty())
100  emit finished();
101 }
102 
104 {
105  markUpdated(site);
106  processAndInsertRSS(site);
107 }
108 
109 
110 RSSSite::RSSSite(const QString& title,
111  const QString& sortTitle,
112  const QString& image,
113  const ArticleType& type,
114  const QString& description,
115  const QString& url,
116  const QString& author,
117  const bool& download,
118  const QDateTime& updated) :
119  m_title(title), m_sortTitle(sortTitle), m_image(image), m_type(type),
120  m_description(description), m_url(url), m_author(author),
121  m_download(download), m_updated(updated)
122 {
123  std::shared_ptr<MythSortHelper>sh = getMythSortHelper();
124  if (m_sortTitle.isEmpty() and not m_title.isEmpty())
125  m_sortTitle = sh->doTitle(m_title);
126 }
127 
129 {
130  QMutexLocker locker(&m_lock);
131  m_articleList.append(item);
132 }
133 
135 {
136  QMutexLocker locker(&m_lock);
137  m_articleList.clear();
138 }
139 
141 {
142  QMutexLocker locker(&m_lock);
143  m_data.resize(0);
144  m_articleList.clear();
145  m_urlReq = QUrl(m_url);
146  if (!m_manager)
147  {
148  m_manager = new QNetworkAccessManager();
149  connect(m_manager, SIGNAL(finished(QNetworkReply*)), this,
150  SLOT(slotCheckRedirect(QNetworkReply*)));
151  }
152 
153  m_reply = m_manager->get(QNetworkRequest(m_urlReq));
154 }
155 
156 QUrl RSSSite::redirectUrl(const QUrl& possibleRedirectUrl,
157  const QUrl& oldRedirectUrl) const
158 {
159  QUrl redirectUrl;
160  if(!possibleRedirectUrl.isEmpty() && possibleRedirectUrl != oldRedirectUrl)
161  redirectUrl = possibleRedirectUrl;
162  return redirectUrl;
163 }
164 
165 void RSSSite::slotCheckRedirect(QNetworkReply* reply)
166 {
167  QVariant possibleRedirectUrl =
168  reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
169 
170  QUrl urlRedirectedTo;
171  urlRedirectedTo = redirectUrl(possibleRedirectUrl.toUrl(),
172  urlRedirectedTo);
173 
174  if(!urlRedirectedTo.isEmpty())
175  {
176  m_manager->get(QNetworkRequest(urlRedirectedTo));
177  }
178  else
179  {
180  m_data = m_reply->readAll();
181  process();
182  }
183 
184  reply->deleteLater();
185 }
186 
188 {
189  QMutexLocker locker(&m_lock);
190  return m_articleList;
191 }
192 
193 unsigned int RSSSite::timeSinceLastUpdate(void) const
194 {
195  QMutexLocker locker(&m_lock);
196 
197  QDateTime curTime(MythDate::current());
198  unsigned int min = m_updated.secsTo(curTime)/60;
199  return min;
200 }
201 
203 {
204  QMutexLocker locker(&m_lock);
205 
206  m_articleList.clear();
207 
208  if (!m_data.size())
209  {
210  emit finished(this);
211  return;
212  }
213 
214  QDomDocument domDoc;
215 
216  if (!domDoc.setContent(m_data, true))
217  {
218  LOG(VB_GENERAL, LOG_ERR, LOC +
219  "Failed to set content from downloaded XML");
220  emit finished(this);
221  return;
222  }
223 
224  //Check the type of the feed
225  QString rootName = domDoc.documentElement().nodeName();
226  if (rootName == "rss" || rootName == "rdf:RDF")
227  {
229  Parse parser;
230  items = parser.parseRSS(domDoc);
231 
232  for (ResultItem::resultList::iterator i = items.begin();
233  i != items.end(); ++i)
234  {
236  (*i)->GetTitle(), (*i)->GetSortTitle(),
237  (*i)->GetSubtitle(), (*i)->GetSortSubtitle(),
238  (*i)->GetDescription(), (*i)->GetURL(),
239  (*i)->GetThumbnail(), (*i)->GetMediaURL(),
240  (*i)->GetAuthor(), (*i)->GetDate(),
241  (*i)->GetTime(), (*i)->GetRating(),
242  (*i)->GetFilesize(), (*i)->GetPlayer(),
243  (*i)->GetPlayerArguments(),
244  (*i)->GetDownloader(),
245  (*i)->GetDownloaderArguments(),
246  (*i)->GetWidth(),
247  (*i)->GetHeight(),
248  (*i)->GetLanguage(),
249  (*i)->GetDownloadable(),
250  (*i)->GetCountries(),
251  (*i)->GetSeason(),
252  (*i)->GetEpisode(), false));
253  }
254  }
255  else
256  LOG(VB_GENERAL, LOG_ERR, LOC + "Data is not valid RSS-feed");
257 
258  emit finished(this);
259 }
void slotRSSRetrieved(RSSSite *)
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:607
bool clearRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:718
void insertRSSArticle(ResultItem *item)
void clearRSSArticles(void)
QString m_title
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QByteArray m_data
void finished(RSSSite *item)
QMutex m_lock
QString m_url
QString m_sortTitle
unsigned int timeSinceLastUpdate(void) const
QUrl redirectUrl(const QUrl &possibleRedirectUrl, const QUrl &oldRedirectUrl) const
const ArticleType & GetType() const
QNetworkAccessManager * m_manager
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
RSSSite(const QString &title, const QString &sortTitle, const QString &image, const ArticleType &type, const QString &description, const QString &url, const QString &author, const bool &download, const QDateTime &updated)
QNetworkReply * m_reply
void stopTimer()
int GetNumSetting(const QString &key, int defaultval=0)
void retrieve(void)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
const QString & GetTitle() const
ResultItem::resultList m_articleList
ResultItem::resultList GetVideoList(void) const
QDateTime m_updated
bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item, ArticleType type)
Definition: netutils.cpp:738
#define LOC
void slotCheckRedirect(QNetworkReply *reply)
void startTimer()
void slotRefreshRSS(void)
void markUpdated(RSSSite *site)
Definition: netutils.cpp:704
QUrl m_urlReq
QList< ResultItem * > resultList
Definition: rssparse.h:114
void processAndInsertRSS(RSSSite *site)
enum ArticleTypes ArticleType
void process(void)
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.