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