diff --git a/include/downloader.h b/include/downloader.h index 1fa439f25..b60e48136 100644 --- a/include/downloader.h +++ b/include/downloader.h @@ -54,6 +54,9 @@ class Download { m_status(K_UNKNOWN), m_did(did) {}; void updateStatus(bool follow=false); + void pauseDownload(); + void resumeDownload(); + void cancelDownload(); StatusResult getStatus() { return m_status; } std::string getDid() { return m_did; } std::string getFollowedBy() { return m_followedBy; } diff --git a/src/aria2.cpp b/src/aria2.cpp index 92c4095d1..0366beb90 100644 --- a/src/aria2.cpp +++ b/src/aria2.cpp @@ -171,7 +171,6 @@ std::vector Aria2::tellActive() MethodCall methodCall("aria2.tellActive", m_secret); auto statusArray = methodCall.newParamValue().getArray(); statusArray.addValue().set(std::string("gid")); - statusArray.addValue().set(std::string("following")); auto responseContent = doRequest(methodCall); MethodResponse response(responseContent); std::vector activeGID; @@ -186,6 +185,27 @@ std::vector Aria2::tellActive() return activeGID; } +std::vector Aria2::tellWaiting() +{ + MethodCall methodCall("aria2.tellWaiting", m_secret); + methodCall.newParamValue().set(0); + methodCall.newParamValue().set(99); // max number of downloads to be returned, don't know how to set this properly assumed that there will not be more than 99 paused downloads. + auto statusArray = methodCall.newParamValue().getArray(); + statusArray.addValue().set(std::string("gid")); + auto responseContent = doRequest(methodCall); + MethodResponse response(responseContent); + std::vector waitingGID; + int index = 0; + while(true) { + try { + auto structNode = response.getParamValue(0).getArray().getValue(index++).getStruct(); + auto gidNode = structNode.getMember("gid"); + waitingGID.push_back(gidNode.getValue().getAsS()); + } catch (InvalidRPCNode& e) { break; } + } + return waitingGID; +} + void Aria2::saveSession() { MethodCall methodCall("aria2.saveSession", m_secret); @@ -199,5 +219,25 @@ void Aria2::shutdown() doRequest(methodCall); } +void Aria2::pause(const std::string& gid) +{ + MethodCall methodCall("aria2.pause", m_secret); + methodCall.newParamValue().set(gid); + doRequest(methodCall); +} + +void Aria2::unpause(const std::string& gid) +{ + MethodCall methodCall("aria2.unpause", m_secret); + methodCall.newParamValue().set(gid); + doRequest(methodCall); +} + +void Aria2::remove(const std::string& gid) +{ + MethodCall methodCall("aria2.remove", m_secret); + methodCall.newParamValue().set(gid); + doRequest(methodCall); +} } // end namespace kiwix diff --git a/src/aria2.h b/src/aria2.h index 16b753ccf..898904a5d 100644 --- a/src/aria2.h +++ b/src/aria2.h @@ -37,8 +37,12 @@ class Aria2 std::string addUri(const std::vector& uri); std::string tellStatus(const std::string& gid, const std::vector& statusKey); std::vector tellActive(); + std::vector tellWaiting(); void saveSession(); void shutdown(); + void pause(const std::string& gid); + void unpause(const std::string& gid); + void remove(const std::string& gid); }; }; //end namespace kiwix diff --git a/src/downloader.cpp b/src/downloader.cpp index e962aabef..1eccf38b6 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -36,6 +36,8 @@ namespace kiwix void Download::updateStatus(bool follow) { + if (m_status == Download::K_REMOVED) + return; static std::vector statusKey = {"status", "files", "totalLength", "completedLength", "followedBy", "downloadSpeed", "verifiedLength"}; @@ -93,6 +95,33 @@ void Download::updateStatus(bool follow) } } +void Download::resumeDownload() +{ + if (!m_followedBy.empty()) + mp_aria->unpause(m_followedBy); + else + mp_aria->unpause(m_did); + updateStatus(true); +} + +void Download::pauseDownload() +{ + if (!m_followedBy.empty()) + mp_aria->pause(m_followedBy); + else + mp_aria->pause(m_did); + updateStatus(true); +} + +void Download::cancelDownload() +{ + if (!m_followedBy.empty()) + mp_aria->remove(m_followedBy); + else + mp_aria->remove(m_did); + m_status = Download::K_REMOVED; +} + /* Constructor */ Downloader::Downloader() : mp_aria(new Aria2()) @@ -101,6 +130,10 @@ Downloader::Downloader() : m_knownDownloads[gid] = std::unique_ptr(new Download(mp_aria, gid)); m_knownDownloads[gid]->updateStatus(); } + for (auto gid : mp_aria->tellWaiting()) { + m_knownDownloads[gid] = std::unique_ptr(new Download(mp_aria, gid)); + m_knownDownloads[gid]->updateStatus(); + } } @@ -139,14 +172,23 @@ Download* Downloader::startDownload(const std::string& uri) Download* Downloader::getDownload(const std::string& did) { try { + m_knownDownloads.at(did).get()->updateStatus(true); return m_knownDownloads.at(did).get(); } catch(exception& e) { for (auto gid : mp_aria->tellActive()) { if (gid == did) { m_knownDownloads[gid] = std::unique_ptr(new Download(mp_aria, gid)); + m_knownDownloads.at(gid).get()->updateStatus(true); return m_knownDownloads[gid].get(); } } + for (auto gid : mp_aria->tellWaiting()) { + if (gid == did) { + m_knownDownloads[gid] = std::unique_ptr(new Download(mp_aria, gid)); + m_knownDownloads.at(gid).get()->updateStatus(true); + return m_knownDownloads[gid].get(); + } + } throw e; } }