summaryrefslogtreecommitdiffstats
path: root/api/logic/net
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2016-08-14 02:33:31 +0200
committerPetr Mrázek <peterix@gmail.com>2016-08-14 23:22:54 +0200
commit042f3ef55c0b469f438542152c4eb02b0789ea3c (patch)
tree03e0c15b200786558babd0fe58edac88ed1bfd1e /api/logic/net
parent2f0441b3c1cd9fc3bcb176d2852da8f92a6e6777 (diff)
downloadMultiMC-042f3ef55c0b469f438542152c4eb02b0789ea3c.tar
MultiMC-042f3ef55c0b469f438542152c4eb02b0789ea3c.tar.gz
MultiMC-042f3ef55c0b469f438542152c4eb02b0789ea3c.tar.lz
MultiMC-042f3ef55c0b469f438542152c4eb02b0789ea3c.tar.xz
MultiMC-042f3ef55c0b469f438542152c4eb02b0789ea3c.zip
GH-352 Make OneSix instance update downloads cancellable
Diffstat (limited to 'api/logic/net')
-rw-r--r--api/logic/net/Download.cpp48
-rw-r--r--api/logic/net/Download.h14
-rw-r--r--api/logic/net/NetAction.h12
-rw-r--r--api/logic/net/NetJob.cpp49
-rw-r--r--api/logic/net/NetJob.h11
5 files changed, 119 insertions, 15 deletions
diff --git a/api/logic/net/Download.cpp b/api/logic/net/Download.cpp
index 70fe7608..7610cae3 100644
--- a/api/logic/net/Download.cpp
+++ b/api/logic/net/Download.cpp
@@ -65,6 +65,12 @@ void Download::addValidator(Validator * v)
void Download::start()
{
+ if(m_status == Job_Aborted)
+ {
+ qWarning() << "Attempt to start an aborted Download:" << m_url.toString();
+ emit aborted(m_index_within_job);
+ return;
+ }
QNetworkRequest request(m_url);
m_status = m_sink->init(request);
switch(m_status)
@@ -80,6 +86,8 @@ void Download::start()
case Job_Failed:
emit failed(m_index_within_job);
return;
+ case Job_Aborted:
+ return;
}
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0");
@@ -103,9 +111,17 @@ void Download::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
void Download::downloadError(QNetworkReply::NetworkError error)
{
- // error happened during download.
- qCritical() << "Failed " << m_url.toString() << " with reason " << error;
- m_status = Job_Failed;
+ if(error == QNetworkReply::OperationCanceledError)
+ {
+ qCritical() << "Aborted " << m_url.toString();
+ m_status = Job_Aborted;
+ }
+ else
+ {
+ // error happened during download.
+ qCritical() << "Failed " << m_url.toString() << " with reason " << error;
+ m_status = Job_Failed;
+ }
}
bool Download::handleRedirect()
@@ -154,6 +170,14 @@ void Download::downloadFinished()
emit failed(m_index_within_job);
return;
}
+ else if(m_status == Job_Aborted)
+ {
+ qDebug() << "Download aborted in previous step:" << m_url.toString();
+ m_sink->abort();
+ m_reply.reset();
+ emit aborted(m_index_within_job);
+ return;
+ }
// make sure we got all the remaining data, if any
auto data = m_reply->readAll();
@@ -197,3 +221,21 @@ void Download::downloadReadyRead()
}
}
+
+bool Net::Download::abort()
+{
+ if(m_reply)
+ {
+ m_reply->abort();
+ }
+ else
+ {
+ m_status = Job_Aborted;
+ }
+ return true;
+}
+
+bool Net::Download::canAbort()
+{
+ return true;
+}
diff --git a/api/logic/net/Download.h b/api/logic/net/Download.h
index 8e38dfc9..fab39ffe 100644
--- a/api/logic/net/Download.h
+++ b/api/logic/net/Download.h
@@ -38,25 +38,25 @@ public:
static Download::Ptr makeFile(QUrl url, QString path);
public: /* methods */
- // FIXME: remove this
QString getTargetFilepath()
{
return m_target_path;
}
- // FIXME: remove this
void addValidator(Validator * v);
+ bool abort() override;
+ bool canAbort() override;
private: /* methods */
bool handleRedirect();
protected slots:
- virtual void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- virtual void downloadError(QNetworkReply::NetworkError error);
- virtual void downloadFinished();
- virtual void downloadReadyRead();
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal) override;
+ void downloadError(QNetworkReply::NetworkError error) override;
+ void downloadFinished() override;
+ void downloadReadyRead() override;
public slots:
- virtual void start();
+ void start() override;
private: /* data */
// FIXME: remove this, it has no business being here.
diff --git a/api/logic/net/NetAction.h b/api/logic/net/NetAction.h
index 2b3f1b7b..07456ce1 100644
--- a/api/logic/net/NetAction.h
+++ b/api/logic/net/NetAction.h
@@ -28,7 +28,8 @@ enum JobStatus
Job_NotStarted,
Job_InProgress,
Job_Finished,
- Job_Failed
+ Job_Failed,
+ Job_Aborted
};
typedef std::shared_ptr<class NetAction> NetActionPtr;
@@ -54,6 +55,14 @@ public:
{
return m_failures;
}
+ virtual bool abort()
+ {
+ return false;
+ }
+ virtual bool canAbort()
+ {
+ return false;
+ }
public:
/// the network reply
@@ -79,6 +88,7 @@ signals:
void netActionProgress(int index, qint64 current, qint64 total);
void succeeded(int index);
void failed(int index);
+ void aborted(int index);
protected
slots:
diff --git a/api/logic/net/NetJob.cpp b/api/logic/net/NetJob.cpp
index ca86242a..2e375760 100644
--- a/api/logic/net/NetJob.cpp
+++ b/api/logic/net/NetJob.cpp
@@ -47,6 +47,15 @@ void NetJob::partFailed(int index)
startMoreParts();
}
+void NetJob::partAborted(int index)
+{
+ m_aborted = true;
+ m_doing.remove(index);
+ m_failed.insert(index);
+ downloads[index].get()->disconnect(this);
+ startMoreParts();
+}
+
void NetJob::partProgress(int index, qint64 bytesReceived, qint64 bytesTotal)
{
auto &slot = parts_progress[index];
@@ -85,6 +94,11 @@ void NetJob::startMoreParts()
qDebug() << m_job_name << "succeeded.";
emitSucceeded();
}
+ else if(m_aborted)
+ {
+ qDebug() << m_job_name << "aborted.";
+ emitFailed(tr("Job '%1' aborted.").arg(m_job_name));
+ }
else
{
qCritical() << m_job_name << "failed.";
@@ -104,6 +118,7 @@ void NetJob::startMoreParts()
// connect signals :D
connect(part.get(), SIGNAL(succeeded(int)), SLOT(partSucceeded(int)));
connect(part.get(), SIGNAL(failed(int)), SLOT(partFailed(int)));
+ connect(part.get(), SIGNAL(aborted(int)), SLOT(partAborted(int)));
connect(part.get(), SIGNAL(netActionProgress(int, qint64, qint64)),
SLOT(partProgress(int, qint64, qint64)));
part->start();
@@ -121,3 +136,37 @@ QStringList NetJob::getFailedFiles()
failed.sort();
return failed;
}
+
+bool NetJob::canAbort() const
+{
+ bool canFullyAbort = true;
+ // can abort the waiting?
+ for(auto index: m_todo)
+ {
+ auto part = downloads[index];
+ canFullyAbort &= part->canAbort();
+ }
+ // can abort the active?
+ for(auto index: m_doing)
+ {
+ auto part = downloads[index];
+ canFullyAbort &= part->canAbort();
+ }
+ return canFullyAbort;
+}
+
+bool NetJob::abort()
+{
+ bool fullyAborted = true;
+ // fail all waiting
+ m_failed.unite(m_todo.toSet());
+ m_todo.clear();
+ // abort active
+ auto toKill = m_doing.toList();
+ for(auto index: toKill)
+ {
+ auto part = downloads[index];
+ fullyAborted &= part->abort();
+ }
+ return fullyAborted;
+}
diff --git a/api/logic/net/NetJob.h b/api/logic/net/NetJob.h
index 3d16b21f..e1c266dd 100644
--- a/api/logic/net/NetJob.h
+++ b/api/logic/net/NetJob.h
@@ -75,24 +75,26 @@ public:
{
return downloads.size();
}
- virtual bool isRunning() const
+ virtual bool isRunning() const override
{
return m_running;
}
QStringList getFailedFiles();
+ bool canAbort() const override;
+
private slots:
void startMoreParts();
public slots:
- virtual void executeTask();
- // FIXME: implement
- virtual bool abort() {return false;};
+ virtual void executeTask() override;
+ virtual bool abort() override;
private slots:
void partProgress(int index, qint64 bytesReceived, qint64 bytesTotal);
void partSucceeded(int index);
void partFailed(int index);
+ void partAborted(int index);
private:
struct part_info
@@ -112,4 +114,5 @@ private:
qint64 current_progress = 0;
qint64 total_progress = 0;
bool m_running = false;
+ bool m_aborted = false;
};