MythTV  master
mythrssmanager.cpp
Go to the documentation of this file.
1 // qt
2 #include <QDir>
3 #include <QFile>
4 #include <QString>
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 #define LOC QString("RSSSite: ")
17 
18 // ---------------------------------------------------
19 
21 {
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 : qAsConst(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 : qAsConst(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 : qAsConst(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: mythrssmanager.cpp:162
RSSSite::insertRSSArticle
void insertRSSArticle(ResultItem *item)
Definition: mythrssmanager.cpp:125
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
RSSManager::doUpdate
void doUpdate()
Definition: mythrssmanager.cpp:45
RSSSite::m_reply
QNetworkReply * m_reply
Definition: mythrssmanager.h:106
getMythSortHelper
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
Definition: mythsorthelper.cpp:133
mythrssmanager.h
RSSManager::stopTimer
void stopTimer()
Definition: mythrssmanager.cpp:40
markUpdated
void markUpdated(RSSSite *site)
Definition: netutils.cpp:708
rssparse.h
RSSSite::GetType
const ArticleType & GetType() const
Definition: mythrssmanager.h:61
RSSSite::timeSinceLastUpdate
std::chrono::minutes timeSinceLastUpdate(void) const
Definition: mythrssmanager.cpp:190
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
RSSSite::finished
void finished(RSSSite *item)
RSSManager::m_inprogress
RSSSite::rssList m_inprogress
Definition: mythrssmanager.h:144
LOC
#define LOC
Definition: mythrssmanager.cpp:16
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: mythrssmanager.h:84
RSSManager::slotRefreshRSS
void slotRefreshRSS(void)
Definition: mythrssmanager.cpp:63
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
Parse
Definition: rssparse.h:188
RSSSite::m_urlReq
QUrl m_urlReq
Definition: mythrssmanager.h:90
RSSSite::m_url
QString m_url
Definition: mythrssmanager.h:89
mythdate.h
RSSSite::m_lock
QRecursiveMutex m_lock
Definition: mythrssmanager.h:98
RSSSite::m_data
QByteArray m_data
Definition: mythrssmanager.h:100
mythlogging.h
RSSSite::m_manager
QNetworkAccessManager * m_manager
Definition: mythrssmanager.h:107
RSSManager::startTimer
void startTimer()
Definition: mythrssmanager.cpp:35
RSSManager::~RSSManager
~RSSManager() override
Definition: mythrssmanager.cpp:30
MythCoreContext::GetDurSetting
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
Definition: mythcorecontext.h:170
RSSManager::finished
void finished()
RSSManager::m_sites
RSSSite::rssList m_sites
Definition: mythrssmanager.h:142
RSSSite::redirectUrl
static QUrl redirectUrl(const QUrl &possibleRedirectUrl, const QUrl &oldRedirectUrl)
Definition: mythrssmanager.cpp:153
netutils.h
RSSManager::processAndInsertRSS
void processAndInsertRSS(RSSSite *site)
Definition: mythrssmanager.cpp:79
RSSManager::m_updateFreq
std::chrono::hours m_updateFreq
Definition: mythrssmanager.h:143
RSSSite::RSSSite
RSSSite(QString title, QString sortTitle, QString image, ArticleType type, QString description, QString url, QString author, bool download, QDateTime updated)
Definition: mythrssmanager.cpp:105
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
ArticleType
ArticleType
Definition: rssparse.h:20
RSSManager::RSSManager
RSSManager()
Definition: mythrssmanager.cpp:20
RSSManager::m_timer
QTimer * m_timer
Definition: mythrssmanager.h:141
RSSSite::m_articleList
ResultItem::resultList m_articleList
Definition: mythrssmanager.h:104
findAllDBRSS
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:611
ResultItem
Definition: rssparse.h:109
RSSSite::retrieve
void retrieve(void)
Definition: mythrssmanager.cpp:137
std
Definition: mythchrono.h:23
RSSSite::GetTitle
const QString & GetTitle() const
Definition: mythrssmanager.h:58
RSSSite::m_updated
QDateTime m_updated
Definition: mythrssmanager.h:93
RSSSite::GetVideoList
ResultItem::resultList GetVideoList(void) const
Definition: mythrssmanager.cpp:184
mythcontext.h
ResultItem::resultList
QList< ResultItem * > resultList
Definition: rssparse.h:114
RSSManager::slotRSSRetrieved
void slotRSSRetrieved(RSSSite *site)
Definition: mythrssmanager.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:718
RSSSite::m_sortTitle
QString m_sortTitle
Definition: mythrssmanager.h:85
RSSSite::clearRSSArticles
void clearRSSArticles(void)
Definition: mythrssmanager.cpp:131
RSSSite::process
void process(void)
Definition: mythrssmanager.cpp:199
RSSSite
Definition: mythrssmanager.h:24