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