GH-1670 Fix LWJGL list loading

Now it uses the standard Download class that supports redirects and SSL.
This commit is contained in:
Petr Mrázek 2016-11-27 01:43:20 +01:00
parent ef73a2bd32
commit 4ca6878743
2 changed files with 71 additions and 133 deletions

View File

@ -22,11 +22,10 @@
#include <QDebug> #include <QDebug>
#define RSS_URL "http://sourceforge.net/projects/java-game-lib/rss" #define RSS_URL "https://sourceforge.net/projects/java-game-lib/rss"
LWJGLVersionList::LWJGLVersionList(QObject *parent) : BaseVersionList(parent) LWJGLVersionList::LWJGLVersionList(QObject *parent) : BaseVersionList(parent)
{ {
setLoading(false);
} }
QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const
@ -72,21 +71,21 @@ int LWJGLVersionList::columnCount(const QModelIndex &parent) const
return 1; return 1;
} }
bool LWJGLVersionList::isLoading() const
{
return m_loading;
}
void LWJGLVersionList::loadList() void LWJGLVersionList::loadList()
{ {
Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)"); if(m_loading)
{
return;
}
m_loading = true;
setLoading(true); qDebug() << "Downloading LWJGL RSS...";
QNetworkRequest req(QUrl(RSS_URL)); m_rssDLJob.reset(new NetJob("LWJGL RSS"));
req.setRawHeader("Accept", "application/rss+xml, text/xml, */*"); m_rssDL = Net::Download::makeByteArray(QUrl(RSS_URL), &m_rssData);
req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)"); m_rssDLJob->addNetAction(m_rssDL);
reply = ENV.qnam().get(req); connect(m_rssDLJob.get(), &NetJob::failed, this, &LWJGLVersionList::rssFailed);
connect(reply, SIGNAL(finished()), SLOT(netRequestComplete())); connect(m_rssDLJob.get(), &NetJob::succeeded, this, &LWJGLVersionList::rssSucceeded);
m_rssDLJob->start();
} }
inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname) inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
@ -98,10 +97,14 @@ inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
return QDomElement(); return QDomElement();
} }
void LWJGLVersionList::netRequestComplete() void LWJGLVersionList::rssFailed(const QString& reason)
{
m_loading = false;
qWarning() << "Failed to load LWJGL list. Network error: " + reason;
}
void LWJGLVersionList::rssSucceeded()
{ {
if (reply->error() == QNetworkReply::NoError)
{
QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip"); QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip");
Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list", "LWJGL regex is invalid"); Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list", "LWJGL regex is invalid");
@ -109,14 +112,15 @@ void LWJGLVersionList::netRequestComplete()
QString xmlErrorMsg; QString xmlErrorMsg;
int errorLine; int errorLine;
auto rawData = reply->readAll();
if (!doc.setContent(rawData, false, &xmlErrorMsg, &errorLine)) if (!doc.setContent(m_rssData, false, &xmlErrorMsg, &errorLine))
{ {
failed("Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " + QString::number(errorLine)); qWarning() << "Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " + QString::number(errorLine);
setLoading(false); m_loading = false;
qDebug() << QString::fromUtf8(rawData); m_rssData.clear();
return; return;
} }
m_rssData.clear();
QDomNodeList items = doc.elementsByTagName("item"); QDomNodeList items = doc.elementsByTagName("item");
@ -124,8 +128,7 @@ void LWJGLVersionList::netRequestComplete()
for (int i = 0; i < items.length(); i++) for (int i = 0; i < items.length(); i++)
{ {
Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list", Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list", "XML element isn't an element... wat?");
"XML element isn't an element... wat?");
QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link"); QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link");
if (linkElement.isNull()) if (linkElement.isNull())
@ -159,30 +162,5 @@ void LWJGLVersionList::netRequestComplete()
endResetModel(); endResetModel();
qDebug() << "Loaded LWJGL list."; qDebug() << "Loaded LWJGL list.";
finished(); m_loading = false;
}
else
{
failed("Failed to load LWJGL list. Network error: " + reply->errorString());
}
setLoading(false);
reply->deleteLater();
}
void LWJGLVersionList::failed(QString msg)
{
qCritical() << msg;
emit loadListFailed(msg);
}
void LWJGLVersionList::finished()
{
emit loadListFinished();
}
void LWJGLVersionList::setLoading(bool loading)
{
m_loading = loading;
emit loadingStateUpdated(m_loading);
} }

View File

@ -25,6 +25,7 @@
#include "BaseVersionList.h" #include "BaseVersionList.h"
#include "multimc_logic_export.h" #include "multimc_logic_export.h"
#include <net/NetJob.h>
class LWJGLVersion; class LWJGLVersion;
typedef std::shared_ptr<LWJGLVersion> PtrLWJGLVersion; typedef std::shared_ptr<LWJGLVersion> PtrLWJGLVersion;
@ -99,58 +100,17 @@ public:
} }
virtual int columnCount(const QModelIndex &parent) const override; virtual int columnCount(const QModelIndex &parent) const override;
virtual bool isLoading() const; public slots:
virtual bool errored() const
{
return m_errored;
}
virtual QString lastErrorMsg() const
{
return m_lastErrorMsg;
}
public
slots:
/*!
* Loads the version list.
* This is done asynchronously. On success, the loadListFinished() signal will
* be emitted. The list model will be reset as well, resulting in the modelReset()
* signal being emitted. Note that the model will be reset before loadListFinished() is
* emitted.
* If loading the list failed, the loadListFailed(QString msg),
* signal will be emitted.
*/
virtual void loadList(); virtual void loadList();
signals: private slots:
/*! void rssFailed(const QString & reason);
* Emitted when the list either starts or finishes loading. void rssSucceeded();
* \param loading Whether or not the list is loading.
*/
void loadingStateUpdated(bool loading);
void loadListFinished();
void loadListFailed(QString msg);
private: private:
QList<PtrLWJGLVersion> m_vlist; QList<PtrLWJGLVersion> m_vlist;
Net::Download::Ptr m_rssDL;
QNetworkReply *m_netReply; NetJobPtr m_rssDLJob;
QNetworkReply *reply; QByteArray m_rssData;
bool m_loading = false;
bool m_loading;
bool m_errored;
QString m_lastErrorMsg;
void failed(QString msg);
void finished();
void setLoading(bool loading);
private
slots:
virtual void netRequestComplete();
}; };