CLOUD: Add OneDriveStorage::download()

Doesn't work when token is invalid, though.
This commit is contained in:
Alexander Tkachev 2016-05-26 23:56:29 +06:00
parent 8f6bcdf55d
commit 24007c029b
4 changed files with 42 additions and 10 deletions

View file

@ -22,16 +22,17 @@
#define FORBIDDEN_SYMBOL_ALLOW_ALL #define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/cloud/onedrive/onedrivestorage.h" #include "backends/cloud/onedrive/onedrivestorage.h"
#include "backends/cloud/onedrive/onedrivetokenrefresher.h"
#include "backends/cloud/downloadrequest.h"
#include "backends/networking/curl/connectionmanager.h" #include "backends/networking/curl/connectionmanager.h"
#include "backends/networking/curl/curljsonrequest.h" #include "backends/networking/curl/curljsonrequest.h"
#include "common/cloudmanager.h"
#include "common/config-manager.h" #include "common/config-manager.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/file.h"
#include "common/json.h" #include "common/json.h"
#include <curl/curl.h>
#include <common/file.h>
#include "common/system.h" #include "common/system.h"
#include "common/cloudmanager.h" #include <curl/curl.h>
#include "onedrivetokenrefresher.h"
namespace Cloud { namespace Cloud {
namespace OneDrive { namespace OneDrive {
@ -125,12 +126,42 @@ void OneDriveStorage::printJson(Networking::RequestJsonPair pair) {
delete json; delete json;
} }
Networking::NetworkReadStream *OneDriveStorage::streamFile(Common::String path) {
Common::String url = "https://api.onedrive.com/v1.0/drive/special/approot:/" + path + ":/content";
//NOT USING OneDriveTokenRefresher, because it's CurlJsonRequest, which saves all contents in memory to parse as JSON
//we actually don't even need a token if the download is "pre-authenticated" (whatever it means)
//still, we'd have to know direct URL (might be found in Item's "@content.downloadUrl", received from the server)
Networking::CurlRequest *request = new Networking::CurlRequest(0, url.c_str());
request->addHeader("Authorization: Bearer " + _token);
return request->execute();
}
int32 OneDriveStorage::download(Common::String remotePath, Common::String localPath, BoolCallback callback) {
Common::DumpFile *f = new Common::DumpFile();
if (!f->open(localPath, true)) {
warning("OneDriveStorage: unable to open file to download into");
if (callback) (*callback)(RequestBoolPair(-1, false));
delete f;
return -1;
}
return ConnMan.addRequest(new DownloadRequest(callback, streamFile(remotePath), f));
}
void OneDriveStorage::fileDownloaded(RequestBoolPair pair) {
if (pair.value) debug("file downloaded!");
else debug("download failed!");
}
int32 OneDriveStorage::syncSaves(BoolCallback callback) { int32 OneDriveStorage::syncSaves(BoolCallback callback) {
//this is not the real syncSaves() implementation //this is not the real syncSaves() implementation
/*
Networking::JsonCallback innerCallback = new Common::Callback<OneDriveStorage, Networking::RequestJsonPair>(this, &OneDriveStorage::printJson); Networking::JsonCallback innerCallback = new Common::Callback<OneDriveStorage, Networking::RequestJsonPair>(this, &OneDriveStorage::printJson);
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, "https://api.onedrive.com/v1.0/drives/"); Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, "https://api.onedrive.com/v1.0/drive/special/approot");
request->addHeader("Authorization: bearer " + _token); request->addHeader("Authorization: bearer " + _token);
return ConnMan.addRequest(request); return ConnMan.addRequest(request);
*/
return download("pic.jpg", "local/onedrive/2/doom.jpg", new Common::Callback<OneDriveStorage, RequestBoolPair>(this, &OneDriveStorage::fileDownloaded));
} }
OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) { OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) {

View file

@ -48,7 +48,7 @@ class OneDriveStorage: public Cloud::Storage {
void codeFlowComplete(RequestBoolPair pair); void codeFlowComplete(RequestBoolPair pair);
void printJson(Networking::RequestJsonPair pair); void printJson(Networking::RequestJsonPair pair);
void printJsonTokenReceived(RequestBoolPair pair); void fileDownloaded(RequestBoolPair pair);
public: public:
virtual ~OneDriveStorage(); virtual ~OneDriveStorage();
@ -75,10 +75,10 @@ public:
virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) { return -1; } //TODO virtual int32 upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) { return -1; } //TODO
/** Returns pointer to Networking::NetworkReadStream. */ /** Returns pointer to Networking::NetworkReadStream. */
virtual Networking::NetworkReadStream *streamFile(Common::String path) { return 0; } //TODO virtual int32 streamFile(Common::String path);
/** Calls the callback when finished. */ /** Calls the callback when finished. */
virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback) { return -1; } //TODO virtual int32 download(Common::String remotePath, Common::String localPath, BoolCallback callback);
/** Calls the callback when finished. */ /** Calls the callback when finished. */
virtual int32 remove(Common::String path, BoolCallback callback) { return -1; } //TODO virtual int32 remove(Common::String path, BoolCallback callback) { return -1; } //TODO

View file

@ -34,7 +34,7 @@ DECLARE_SINGLETON(Networking::ConnectionManager);
namespace Networking { namespace Networking {
ConnectionManager::ConnectionManager(): _multi(0), _timerStarted(false) { ConnectionManager::ConnectionManager(): _multi(0), _timerStarted(false), _nextId(0) {
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
_multi = curl_multi_init(); _multi = curl_multi_init();
} }

View file

@ -45,6 +45,7 @@ NetworkReadStream::NetworkReadStream(const char *url, curl_slist *headersList, C
curl_easy_setopt(_easy, CURLOPT_HEADER, 0L); curl_easy_setopt(_easy, CURLOPT_HEADER, 0L);
curl_easy_setopt(_easy, CURLOPT_URL, url); curl_easy_setopt(_easy, CURLOPT_URL, url);
curl_easy_setopt(_easy, CURLOPT_VERBOSE, 0L); curl_easy_setopt(_easy, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(_easy, CURLOPT_FOLLOWLOCATION, 1L); //probably it's OK to have it always on
curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList); curl_easy_setopt(_easy, CURLOPT_HTTPHEADER, headersList);
if (postFields.size() != 0) { if (postFields.size() != 0) {
curl_easy_setopt(_easy, CURLOPT_POSTFIELDSIZE, postFields.size()); curl_easy_setopt(_easy, CURLOPT_POSTFIELDSIZE, postFields.size());