- Add the ability to parse the RSS feeds from reddit groups (in particular the image feed groups like EarthPorn) and display them
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
#include <QDirIterator>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QDomDocument>
|
||||
#include <QDomAttr>
|
||||
#include <iostream>
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
|
||||
@@ -108,5 +110,132 @@ ImageDisplayOptions ImageListPathTraverser::UpdateOptionsForImage(const std::str
|
||||
// no per file options modification supported
|
||||
Q_UNUSED(filename);
|
||||
Q_UNUSED(baseOptions);
|
||||
return ImageDisplayOptions();
|
||||
return baseOptions;
|
||||
}
|
||||
|
||||
|
||||
RedditRSSFeedPathTraverser::RedditRSSFeedPathTraverser(const std::string& rssFeedURLIn, QNetworkAccessManager& networkManager, bool debugModeIn) :
|
||||
PathTraverser("",debugModeIn), rssFeedURL(rssFeedURLIn), webCtrl(networkManager)
|
||||
{
|
||||
connect( &webCtrl, SIGNAL (finished(QNetworkReply*)), this, SLOT (fileDownloaded(QNetworkReply*)));
|
||||
RequestRSSFeed();
|
||||
}
|
||||
|
||||
RedditRSSFeedPathTraverser::~RedditRSSFeedPathTraverser()
|
||||
{
|
||||
}
|
||||
|
||||
void RedditRSSFeedPathTraverser::RequestRSSFeed()
|
||||
{
|
||||
if (pendingReply)
|
||||
{
|
||||
pendingReply->abort();
|
||||
}
|
||||
if (debugMode)
|
||||
{
|
||||
std::cout << "Requesting RSS feed:" << rssFeedURL << std::endl;
|
||||
}
|
||||
rssRequestedTime = QDateTime::currentDateTime();
|
||||
QNetworkRequest request(QUrl(rssFeedURL.c_str()));
|
||||
pendingReply = webCtrl.get(request);
|
||||
}
|
||||
|
||||
void RedditRSSFeedPathTraverser::fileDownloaded(QNetworkReply* netReply)
|
||||
{
|
||||
if (netReply != pendingReply)
|
||||
return;
|
||||
|
||||
pendingReply = nullptr;
|
||||
|
||||
QNetworkReply::NetworkError err = netReply->error();
|
||||
if (err != QNetworkReply::NoError)
|
||||
{
|
||||
std::cout << "Failed to load Reddit RSS URL: " << err << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
QString str (netReply->readAll());
|
||||
QVariant vt = netReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
netReply->deleteLater();
|
||||
if (!vt.isNull())
|
||||
{
|
||||
if (debugMode)
|
||||
{
|
||||
std::cout << "Redirected to:" << vt.toUrl().toString().toStdString() << std::endl;
|
||||
}
|
||||
webCtrl.get(QNetworkRequest(vt.toUrl()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QDomDocument doc;
|
||||
QString error;
|
||||
if (!doc.setContent(str, false, &error))
|
||||
{
|
||||
if (debugMode)
|
||||
{
|
||||
std::cout << "Failed to load page:" << error.toStdString() << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QDomElement docElem = doc.documentElement();
|
||||
QDomNodeList nodeList = docElem.elementsByTagName("entry");
|
||||
for (int iEntry = 0; iEntry < nodeList.length(); ++iEntry)
|
||||
{
|
||||
QDomNode node = nodeList.item(iEntry);
|
||||
QDomElement e = node.toElement();
|
||||
QDomNode contentNode = e.elementsByTagName("content").item(0).firstChild();
|
||||
QDomDocument docContent;
|
||||
if (!docContent.setContent(contentNode.nodeValue(), false, &error))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QDomNodeList addressEntries = docContent.documentElement().elementsByTagName("a");
|
||||
for (int iAddr = 0; iAddr < addressEntries.length(); ++iAddr)
|
||||
{
|
||||
QDomNode node = addressEntries.item(iAddr);
|
||||
/*QString output;
|
||||
QTextStream stream(&output);
|
||||
node.save(stream, 0);
|
||||
qDebug() << "nodeValue: " << output;*/
|
||||
if (node.toElement().text() == "[link]" && node.hasAttributes() )
|
||||
{
|
||||
QDomAttr a = node.toElement().attributeNode("href");
|
||||
// check if the URL matches one of our supported formats
|
||||
for ( const QString& format : supportedFormats )
|
||||
{
|
||||
if (a.value().endsWith(format))
|
||||
{
|
||||
imageURLS.append(a.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList RedditRSSFeedPathTraverser::getImages() const
|
||||
{
|
||||
// refresh the feed after 5 hours
|
||||
if (rssRequestedTime.secsTo(QDateTime::currentDateTime()) > 60*60*5 )
|
||||
{
|
||||
const_cast<RedditRSSFeedPathTraverser *>(this)->RequestRSSFeed();
|
||||
}
|
||||
return imageURLS;
|
||||
}
|
||||
|
||||
const std::string RedditRSSFeedPathTraverser::getImagePath(const std::string image) const
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
ImageDisplayOptions RedditRSSFeedPathTraverser::UpdateOptionsForImage(const std::string& filename, const ImageDisplayOptions& baseOptions) const
|
||||
{
|
||||
// no per file options modification supported
|
||||
Q_UNUSED(filename);
|
||||
return baseOptions;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user