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
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,
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);
101}
102
103
104RSSSite::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
152QUrl 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
161void 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
189std::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 QT_VERSION < QT_VERSION_CHECK(6,5,0)
213 bool success = domDoc.setContent(m_data, true);
214#else
215 auto parseResult = domDoc.setContent(m_data, QDomDocument::ParseOption::UseNamespaceProcessing);
216 bool success { parseResult };
217#endif
218 if (!success)
219 {
220 LOG(VB_GENERAL, LOG_ERR, LOC +
221 "Failed to set content from downloaded XML");
222 emit finished(this);
223 return;
224 }
225
226 //Check the type of the feed
227 QString rootName = domDoc.documentElement().nodeName();
228 if (rootName == "rss" || rootName == "rdf:RDF")
229 {
232 items = Parse::parseRSS(domDoc);
233
234 for (const auto *item : std::as_const(items))
235 {
237 item->GetTitle(), item->GetSortTitle(),
238 item->GetSubtitle(), item->GetSortSubtitle(),
239 item->GetDescription(), item->GetURL(),
240 item->GetThumbnail(), item->GetMediaURL(),
241 item->GetAuthor(), item->GetDate(),
242 item->GetTime(), item->GetRating(),
243 item->GetFilesize(), item->GetPlayer(),
244 item->GetPlayerArguments(),
245 item->GetDownloader(),
246 item->GetDownloaderArguments(),
247 item->GetWidth(),
248 item->GetHeight(),
249 item->GetLanguage(),
250 item->GetDownloadable(),
251 item->GetCountries(),
252 item->GetSeason(),
253 item->GetEpisode(), false));
254 }
255 }
256 else
257 {
258 LOG(VB_GENERAL, LOG_ERR, LOC + "Data is not valid RSS-feed");
259 }
260
261 emit finished(this);
262}
static ResultItem::resultList parseRSS(const QDomDocument &domDoc)
Definition: rssparse.cpp:711
void slotRSSRetrieved(RSSSite *site)
Definition: rssmanager.cpp:97
QTimer * m_timer
Definition: rssmanager.h:134
~RSSManager() override
Definition: rssmanager.cpp:29
std::chrono::hours m_updateFreq
Definition: rssmanager.h:136
void doUpdate()
Definition: rssmanager.cpp:44
RSSSite::rssList m_sites
Definition: rssmanager.h:135
void startTimer()
Definition: rssmanager.cpp:34
void slotRefreshRSS(void)
Definition: rssmanager.cpp:62
void processAndInsertRSS(RSSSite *site)
Definition: rssmanager.cpp:78
void finished()
void stopTimer()
Definition: rssmanager.cpp:39
RSSSite::rssList m_inprogress
Definition: rssmanager.h:137
QUrl m_urlReq
Definition: rssmanager.h:87
QDateTime m_updated
Definition: rssmanager.h:90
void slotCheckRedirect(QNetworkReply *reply)
Definition: rssmanager.cpp:161
QNetworkAccessManager * m_manager
Definition: rssmanager.h:100
static QUrl redirectUrl(const QUrl &possibleRedirectUrl, const QUrl &oldRedirectUrl)
Definition: rssmanager.cpp:152
QRecursiveMutex m_lock
Definition: rssmanager.h:92
QByteArray m_data
Definition: rssmanager.h:93
ResultItem::resultList GetVideoList(void) const
Definition: rssmanager.cpp:183
void retrieve(void)
Definition: rssmanager.cpp:136
QString m_url
Definition: rssmanager.h:86
QString m_title
Definition: rssmanager.h:81
void insertRSSArticle(ResultItem *item)
Definition: rssmanager.cpp:124
const ArticleType & GetType() const
Definition: rssmanager.h:58
const QString & GetTitle() const
Definition: rssmanager.h:55
void process(void)
Definition: rssmanager.cpp:198
void finished(RSSSite *item)
std::chrono::minutes timeSinceLastUpdate(void) const
Definition: rssmanager.cpp:189
QNetworkReply * m_reply
Definition: rssmanager.h:99
QString m_sortTitle
Definition: rssmanager.h:82
ResultItem::resultList m_articleList
Definition: rssmanager.h:97
void clearRSSArticles(void)
Definition: rssmanager.cpp:130
RSSSite(QString title, QString sortTitle, QString image, ArticleType type, QString description, QString url, QString author, bool download, QDateTime updated)
Definition: rssmanager.cpp:104
QList< ResultItem * > resultList
Definition: rssparse.h:114
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
STL namespace.
bool insertRSSArticleInDB(const QString &feedtitle, ResultItem *item, ArticleType type)
Definition: netutils.cpp:742
RSSSite::rssList findAllDBRSS()
Definition: netutils.cpp:610
void markUpdated(RSSSite *site)
Definition: netutils.cpp:708
bool clearRSSArticles(const QString &feedtitle, ArticleType type)
Definition: netutils.cpp:722
#define LOC
Definition: rssmanager.cpp:17
ArticleType
Definition: rssparse.h:20