NOISSUE refactor *Download into more, smaller pieces

* Download is now Download.
* Download uses Sink subclasses to process various events.
* Validators can be used to further customize the Sink behaviour.
This commit is contained in:
Petr Mrázek
2016-05-28 19:54:17 +02:00
parent a750f6e63c
commit a1abbd9e05
51 changed files with 824 additions and 765 deletions

View File

@ -43,22 +43,19 @@ void DownloadTask::loadVersionInfo()
{
setStatus(tr("Loading version information..."));
m_currentVersionFileListDownload.reset();
m_newVersionFileListDownload.reset();
NetJob *netJob = new NetJob("Version Info");
// Find the index URL.
QUrl newIndexUrl = QUrl(m_status.newRepoUrl).resolved(QString::number(m_status.newVersionId) + ".json");
qDebug() << m_status.newRepoUrl << " turns into " << newIndexUrl;
netJob->addNetAction(m_newVersionFileListDownload = ByteArrayDownload::make(newIndexUrl));
netJob->addNetAction(m_newVersionFileListDownload = Net::Download::makeByteArray(newIndexUrl, &newVersionFileListData));
// If we have a current version URL, get that one too.
if (!m_status.currentRepoUrl.isEmpty())
{
QUrl cIndexUrl = QUrl(m_status.currentRepoUrl).resolved(QString::number(m_status.currentVersionId) + ".json");
netJob->addNetAction(m_currentVersionFileListDownload = ByteArrayDownload::make(cIndexUrl));
netJob->addNetAction(m_currentVersionFileListDownload = Net::Download::makeByteArray(cIndexUrl, &currentVersionFileListData));
qDebug() << m_status.currentRepoUrl << " turns into " << cIndexUrl;
}
@ -92,7 +89,7 @@ void DownloadTask::processDownloadedVersionInfo()
setStatus(tr("Reading file list for new version..."));
qDebug() << "Reading file list for new version...";
QString error;
if (!parseVersionInfo(m_newVersionFileListDownload->m_data, m_newVersionFileList, error))
if (!parseVersionInfo(newVersionFileListData, m_newVersionFileList, error))
{
qCritical() << error;
emitFailed(error);
@ -106,7 +103,7 @@ void DownloadTask::processDownloadedVersionInfo()
qDebug() << "Reading file list for current version...";
// if this fails, it's not a complete loss.
QString error;
if(!parseVersionInfo( m_currentVersionFileListDownload->m_data, m_currentVersionFileList, error))
if(!parseVersionInfo( currentVersionFileListData, m_currentVersionFileList, error))
{
qDebug() << error << "This is not a fatal error.";
}

View File

@ -64,8 +64,10 @@ protected:
void loadVersionInfo();
NetJobPtr m_vinfoNetJob;
ByteArrayDownloadPtr m_currentVersionFileListDownload;
ByteArrayDownloadPtr m_newVersionFileListDownload;
QByteArray currentVersionFileListData;
QByteArray newVersionFileListData;
Net::Download::Ptr m_currentVersionFileListDownload;
Net::Download::Ptr m_newVersionFileListDownload;
NetJobPtr m_filesNetJob;

View File

@ -4,6 +4,9 @@
#include <QFile>
#include <FileSystem.h>
#include "net/Download.h"
#include "net/ChecksumValidator.h"
namespace GoUpdate
{
@ -189,8 +192,9 @@ bool processFileLists
// We need to download the file to the updatefiles folder and add a task
// to copy it to its install path.
auto download = MD5EtagDownload::make(source.url, dlPath);
download->m_expected_md5 = entry.md5;
auto download = Net::Download::makeFile(source.url, dlPath);
auto rawMd5 = QByteArray::fromHex(entry.md5.toLatin1());
download->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
job->addNetAction(download);
ops.append(Operation::CopyOp(dlPath, entry.path, entry.mode));
}

View File

@ -28,11 +28,6 @@ UpdateChecker::UpdateChecker(QString channelListUrl, QString currentChannel, int
m_channelListUrl = channelListUrl;
m_currentChannel = currentChannel;
m_currentBuild = currentBuild;
m_updateChecking = false;
m_chanListLoading = false;
m_checkUpdateWaiting = false;
m_chanListLoaded = false;
}
QList<UpdateChecker::ChannelListEntry> UpdateChecker::getChannelList() const
@ -93,9 +88,8 @@ void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
QUrl indexUrl = QUrl(m_newRepoUrl).resolved(QUrl("index.json"));
auto job = new NetJob("GoUpdate Repository Index");
job->addNetAction(ByteArrayDownload::make(indexUrl));
connect(job, &NetJob::succeeded, [this, notifyNoUpdate]()
{ updateCheckFinished(notifyNoUpdate); });
job->addNetAction(Net::Download::makeByteArray(indexUrl, &indexData));
connect(job, &NetJob::succeeded, [this, notifyNoUpdate](){ updateCheckFinished(notifyNoUpdate); });
connect(job, &NetJob::failed, this, &UpdateChecker::updateCheckFailed);
indexJob.reset(job);
job->start();
@ -106,19 +100,15 @@ void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
qDebug() << "Finished downloading repo index. Checking for new versions.";
QJsonParseError jsonError;
QByteArray data;
{
ByteArrayDownloadPtr dl =
std::dynamic_pointer_cast<ByteArrayDownload>(indexJob->first());
data = dl->m_data;
indexJob.reset();
}
indexJob.reset();
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
QJsonDocument jsonDoc = QJsonDocument::fromJson(indexData, &jsonError);
indexData.clear();
if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject())
{
qCritical() << "Failed to parse GoUpdate repository index. JSON error"
<< jsonError.errorString() << "at offset" << jsonError.offset;
m_updateChecking = false;
return;
}
@ -130,6 +120,7 @@ void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
{
qCritical() << "Failed to check for updates. API version mismatch. We're using"
<< API_VERSION << "server has" << apiVersion;
m_updateChecking = false;
return;
}
@ -165,7 +156,6 @@ void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
{
emit noUpdateFound();
}
m_updateChecking = false;
}
@ -178,6 +168,12 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate)
{
qDebug() << "Loading the channel list.";
if (m_chanListLoading)
{
qDebug() << "Ignoring channel list update request. Already grabbing channel list.";
return;
}
if (m_channelListUrl.isEmpty())
{
qCritical() << "Failed to update channel list. No channel list URL set."
@ -188,9 +184,8 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate)
m_chanListLoading = true;
NetJob *job = new NetJob("Update System Channel List");
job->addNetAction(ByteArrayDownload::make(QUrl(m_channelListUrl)));
connect(job, &NetJob::succeeded, [this, notifyNoUpdate]()
{ chanListDownloadFinished(notifyNoUpdate); });
job->addNetAction(Net::Download::makeByteArray(QUrl(m_channelListUrl), &chanlistData));
connect(job, &NetJob::succeeded, [this, notifyNoUpdate]() { chanListDownloadFinished(notifyNoUpdate); });
QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
chanListJob.reset(job);
job->start();
@ -198,21 +193,16 @@ void UpdateChecker::updateChanList(bool notifyNoUpdate)
void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)
{
QByteArray data;
{
ByteArrayDownloadPtr dl =
std::dynamic_pointer_cast<ByteArrayDownload>(chanListJob->first());
data = dl->m_data;
chanListJob.reset();
}
chanListJob.reset();
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
QJsonDocument jsonDoc = QJsonDocument::fromJson(chanlistData, &jsonError);
chanlistData.clear();
if (jsonError.error != QJsonParseError::NoError)
{
// TODO: Report errors to the user.
qCritical() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at"
<< jsonError.offset;
qCritical() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at" << jsonError.offset;
m_chanListLoading = false;
return;
}
@ -225,6 +215,7 @@ void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)
qCritical()
<< "Failed to check for updates. Channel list format version mismatch. We're using"
<< CHANLIST_FORMAT << "server has" << formatVersion;
m_chanListLoading = false;
return;
}

View File

@ -18,8 +18,6 @@
#include "net/NetJob.h"
#include "GoUpdate.h"
#include <QUrl>
#include "multimc_logic_export.h"
class MULTIMC_LOGIC_EXPORT UpdateChecker : public QObject
@ -78,7 +76,9 @@ private:
friend class UpdateCheckerTest;
NetJobPtr indexJob;
QByteArray indexData;
NetJobPtr chanListJob;
QByteArray chanlistData;
QString m_channelListUrl;
@ -88,24 +88,24 @@ private:
* True while the system is checking for updates.
* If checkForUpdate is called while this is true, it will be ignored.
*/
bool m_updateChecking;
bool m_updateChecking = false;
/*!
* True if the channel list has loaded.
* If this is false, trying to check for updates will call updateChanList first.
*/
bool m_chanListLoaded;
bool m_chanListLoaded = false;
/*!
* Set to true while the channel list is currently loading.
*/
bool m_chanListLoading;
bool m_chanListLoading = false;
/*!
* Set to true when checkForUpdate is called while the channel list isn't loaded.
* When the channel list finishes loading, if this is true, the update checker will check for updates.
*/
bool m_checkUpdateWaiting;
bool m_checkUpdateWaiting = false;
/*!
* if m_checkUpdateWaiting, this is the last used update channel