diff options
author | Alexander Tkachev | 2016-07-19 15:27:26 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | 55568d757ce2990a285a6193a60242f9932d0797 (patch) | |
tree | 224cacf212e1f3c31f99eaea332af768e7156ecf | |
parent | 36b381e411f4e55ba9590a4102f5b84ce6b724ce (diff) | |
download | scummvm-rg350-55568d757ce2990a285a6193a60242f9932d0797.tar.gz scummvm-rg350-55568d757ce2990a285a6193a60242f9932d0797.tar.bz2 scummvm-rg350-55568d757ce2990a285a6193a60242f9932d0797.zip |
CLOUD: Move Dropbox to API v2
We had a few places where their deprecated API v1 was used.
-rw-r--r-- | backends/cloud/cloudmanager.cpp | 2 | ||||
-rw-r--r-- | backends/cloud/dropbox/dropboxinforequest.cpp | 143 | ||||
-rw-r--r-- | backends/cloud/dropbox/dropboxinforequest.h | 56 | ||||
-rw-r--r-- | backends/cloud/dropbox/dropboxstorage.cpp | 50 | ||||
-rw-r--r-- | backends/cloud/dropbox/dropboxstorage.h | 6 | ||||
-rw-r--r-- | backends/module.mk | 1 |
6 files changed, 206 insertions, 52 deletions
diff --git a/backends/cloud/cloudmanager.cpp b/backends/cloud/cloudmanager.cpp index 7156197368..b6a721be90 100644 --- a/backends/cloud/cloudmanager.cpp +++ b/backends/cloud/cloudmanager.cpp @@ -245,7 +245,7 @@ Networking::Request *CloudManager::downloadFolder(Common::String remotePath, Com Networking::Request *CloudManager::info(Storage::StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { Storage *storage = getCurrentStorage(); - if (storage) storage->info(callback, errorCallback); + if (storage) return storage->info(callback, errorCallback); else { delete callback; delete errorCallback; diff --git a/backends/cloud/dropbox/dropboxinforequest.cpp b/backends/cloud/dropbox/dropboxinforequest.cpp new file mode 100644 index 0000000000..f5a14abe1c --- /dev/null +++ b/backends/cloud/dropbox/dropboxinforequest.cpp @@ -0,0 +1,143 @@ +/* ScummVM - Graphic Adventure Engine +* +* ScummVM is the legal property of its developers, whose names +* are too numerous to list here. Please refer to the COPYRIGHT +* file distributed with this source distribution. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +*/ + +#include "backends/cloud/dropbox/dropboxinforequest.h" +#include "backends/cloud/cloudmanager.h" +#include "backends/cloud/storage.h" +#include "backends/networking/curl/connectionmanager.h" +#include "backends/networking/curl/curljsonrequest.h" +#include "backends/networking/curl/networkreadstream.h" +#include "common/json.h" + +namespace Cloud { +namespace Dropbox { + +DropboxInfoRequest::DropboxInfoRequest(Common::String token, Storage::StorageInfoCallback cb, Networking::ErrorCallback ecb): + Networking::Request(nullptr, ecb), _token(token), _infoCallback(cb), + _workingRequest(nullptr), _ignoreCallback(false) { + start(); +} + +DropboxInfoRequest::~DropboxInfoRequest() { + _ignoreCallback = true; + if (_workingRequest) _workingRequest->finish(); + delete _infoCallback; +} + +void DropboxInfoRequest::start() { + _ignoreCallback = true; + if (_workingRequest) _workingRequest->finish(); + _ignoreCallback = false; + + Networking::JsonCallback innerCallback = new Common::Callback<DropboxInfoRequest, Networking::JsonResponse>(this, &DropboxInfoRequest::userResponseCallback); + Networking::ErrorCallback errorCallback = new Common::Callback<DropboxInfoRequest, Networking::ErrorResponse>(this, &DropboxInfoRequest::errorCallback); + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, "https://api.dropboxapi.com/2/users/get_current_account"); + request->addHeader("Authorization: Bearer " + _token); + request->addHeader("Content-Type: application/json"); + request->addPostField("null"); //use POST + + _workingRequest = ConnMan.addRequest(request); +} + +void DropboxInfoRequest::userResponseCallback(Networking::JsonResponse response) { + Common::JSONValue *json = response.value; + _workingRequest = nullptr; + if (_ignoreCallback) { + delete json; + return; + } + + Networking::ErrorResponse error(this); + Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; + if (rq && rq->getNetworkReadStream()) + error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); + + if (!json) { + warning("NULL passed instead of JSON"); + finishError(error); + return; + } + + //Dropbox documentation states there are no errors for this API method + Common::JSONObject info = json->asObject(); + Common::JSONObject nameInfo = info.getVal("name")->asObject(); + _uid = info.getVal("account_id")->asString(); + _name = nameInfo.getVal("display_name")->asString(); + _email = info.getVal("email")->asString(); + CloudMan.setStorageUsername(kStorageDropboxId, _email); + delete json; + + Networking::JsonCallback innerCallback = new Common::Callback<DropboxInfoRequest, Networking::JsonResponse>(this, &DropboxInfoRequest::quotaResponseCallback); + Networking::ErrorCallback errorCallback = new Common::Callback<DropboxInfoRequest, Networking::ErrorResponse>(this, &DropboxInfoRequest::errorCallback); + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, "https://api.dropboxapi.com/2/users/get_space_usage"); + request->addHeader("Authorization: Bearer " + _token); + request->addHeader("Content-Type: application/json"); + request->addPostField("null"); //use POST + + _workingRequest = ConnMan.addRequest(request); +} + +void DropboxInfoRequest::quotaResponseCallback(Networking::JsonResponse response) { + Common::JSONValue *json = response.value; + _workingRequest = nullptr; + if (_ignoreCallback) { + delete json; + return; + } + + Networking::ErrorResponse error(this); + Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request; + if (rq && rq->getNetworkReadStream()) + error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); + + if (!json) { + warning("NULL passed instead of JSON"); + finishError(error); + return; + } + + //Dropbox documentation states there are no errors for this API method + Common::JSONObject info = json->asObject(); + Common::JSONObject allocation = info.getVal("allocation")->asObject(); + uint64 used = info.getVal("used")->asIntegerNumber(); + uint64 allocated = allocation.getVal("allocated")->asIntegerNumber(); + finishInfo(StorageInfo(_uid, _name, _email, used, allocated)); + delete json; +} + +void DropboxInfoRequest::errorCallback(Networking::ErrorResponse error) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishError(error); +} + +void DropboxInfoRequest::handle() {} + +void DropboxInfoRequest::restart() { start(); } + +void DropboxInfoRequest::finishInfo(StorageInfo info) { + Request::finishSuccess(); + if (_infoCallback) (*_infoCallback)(Storage::StorageInfoResponse(this, info)); +} + +} // End of namespace Dropbox +} // End of namespace Cloud diff --git a/backends/cloud/dropbox/dropboxinforequest.h b/backends/cloud/dropbox/dropboxinforequest.h new file mode 100644 index 0000000000..a91d016e60 --- /dev/null +++ b/backends/cloud/dropbox/dropboxinforequest.h @@ -0,0 +1,56 @@ +/* ScummVM - Graphic Adventure Engine +* +* ScummVM is the legal property of its developers, whose names +* are too numerous to list here. Please refer to the COPYRIGHT +* file distributed with this source distribution. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +*/ + +#ifndef BACKENDS_CLOUD_DROPBOX_DROPBOXINFOREQUEST_H +#define BACKENDS_CLOUD_DROPBOX_DROPBOXINFOREQUEST_H + +#include "backends/cloud/storage.h" +#include "backends/networking/curl/request.h" +#include "backends/networking/curl/curljsonrequest.h" + +namespace Cloud { +namespace Dropbox { + +class DropboxInfoRequest: public Networking::Request { + Common::String _token; + Common::String _uid, _name, _email; + Storage::StorageInfoCallback _infoCallback; + Request *_workingRequest; + bool _ignoreCallback; + + void start(); + void userResponseCallback(Networking::JsonResponse response); + void quotaResponseCallback(Networking::JsonResponse response); + void errorCallback(Networking::ErrorResponse error); + void finishInfo(StorageInfo info); +public: + DropboxInfoRequest(Common::String token, Storage::StorageInfoCallback cb, Networking::ErrorCallback ecb); + virtual ~DropboxInfoRequest(); + + virtual void handle(); + virtual void restart(); +}; + +} // End of namespace Dropbox +} // End of namespace Cloud + +#endif diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp index 8343b74aa0..e34912ed66 100644 --- a/backends/cloud/dropbox/dropboxstorage.cpp +++ b/backends/cloud/dropbox/dropboxstorage.cpp @@ -23,6 +23,7 @@ #include "backends/cloud/dropbox/dropboxstorage.h" #include "backends/cloud/dropbox/dropboxcreatedirectoryrequest.h" +#include "backends/cloud/dropbox/dropboxinforequest.h" #include "backends/cloud/dropbox/dropboxlistdirectoryrequest.h" #include "backends/cloud/dropbox/dropboxuploadrequest.h" #include "backends/cloud/cloudmanager.h" @@ -62,7 +63,7 @@ DropboxStorage::~DropboxStorage() {} void DropboxStorage::getAccessToken(Common::String code) { if (!KEY || !SECRET) loadKeyAndSecret(); Networking::JsonCallback callback = new Common::Callback<DropboxStorage, Networking::JsonResponse>(this, &DropboxStorage::codeFlowComplete); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, nullptr, "https://api.dropboxapi.com/1/oauth2/token"); + Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, nullptr, "https://api.dropboxapi.com/oauth2/token"); request->addPostField("code=" + code); request->addPostField("grant_type=authorization_code"); request->addPostField("client_id=" + Common::String(KEY)); @@ -133,54 +134,13 @@ Networking::Request *DropboxStorage::createDirectory(Common::String path, BoolCa return addRequest(new DropboxCreateDirectoryRequest(_token, path, callback, errorCallback)); } -Networking::Request *DropboxStorage::info(StorageInfoCallback outerCallback, Networking::ErrorCallback errorCallback) { - Networking::JsonCallback innerCallback = new Common::CallbackBridge<DropboxStorage, StorageInfoResponse, Networking::JsonResponse>(this, &DropboxStorage::infoInnerCallback, outerCallback); - Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, "https://api.dropboxapi.com/1/account/info"); - request->addHeader("Authorization: Bearer " + _token); - return addRequest(request); - //that callback bridge wraps the outerCallback (passed in arguments from user) into innerCallback - //so, when CurlJsonRequest is finished, it calls the innerCallback - //innerCallback (which is DropboxStorage::infoInnerCallback in this case) processes the void *ptr - //and then calls the outerCallback (which wants to receive StorageInfo, not void *) +Networking::Request *DropboxStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) { + if (!errorCallback) errorCallback = getErrorPrintingCallback(); + return addRequest(new DropboxInfoRequest(_token, callback, errorCallback)); } Common::String DropboxStorage::savesDirectoryPath() { return "/saves/"; } -void DropboxStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse response) { - Common::JSONValue *json = response.value; - if (!json) { - warning("NULL passed instead of JSON"); - delete outerCallback; - return; - } - - //Dropbox documentation states there is no errors for this API method - Common::JSONObject info = json->asObject(); - Common::String uid = Common::String::format("%d", (int)info.getVal("uid")->asIntegerNumber()); - Common::String name = info.getVal("display_name")->asString(); - Common::String email = info.getVal("email")->asString(); - Common::JSONObject quota = info.getVal("quota_info")->asObject(); - uint64 quotaNormal = quota.getVal("normal")->asIntegerNumber(); - uint64 quotaShared = quota.getVal("shared")->asIntegerNumber(); - uint64 quotaAllocated = quota.getVal("quota")->asIntegerNumber(); - - CloudMan.setStorageUsername(kStorageDropboxId, email); - - if (outerCallback) { - (*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, name, email, quotaNormal+quotaShared, quotaAllocated))); - delete outerCallback; - } - - delete json; -} - -void DropboxStorage::infoMethodCallback(StorageInfoResponse response) { - debug("\nStorage info:"); - debug("User name: %s", response.value.name().c_str()); - debug("Email: %s", response.value.email().c_str()); - debug("Disk usage: %u/%u", (uint32)response.value.used(), (uint32)response.value.available()); -} - DropboxStorage *DropboxStorage::loadFromConfig(Common::String keyPrefix) { loadKeyAndSecret(); diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h index b3dc64139c..2c9cf163ab 100644 --- a/backends/cloud/dropbox/dropboxstorage.h +++ b/backends/cloud/dropbox/dropboxstorage.h @@ -43,9 +43,6 @@ class DropboxStorage: public Cloud::Storage { void getAccessToken(Common::String code); void codeFlowComplete(Networking::JsonResponse response); - /** Constructs StorageInfo based on JSON response from cloud. */ - void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json); - public: /** This constructor uses OAuth code flow to get tokens. */ DropboxStorage(Common::String code); @@ -90,9 +87,6 @@ public: /** Returns the StorageInfo struct. */ virtual Networking::Request *info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback); - /** This method is passed into info(). (Temporary) */ - void infoMethodCallback(StorageInfoResponse response); - /** Returns storage's saves directory path with the trailing slash. */ virtual Common::String savesDirectoryPath(); diff --git a/backends/module.mk b/backends/module.mk index e74cf671a7..aea0f77d08 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -34,6 +34,7 @@ MODULE_OBJS += \ cloud/box/boxuploadrequest.o \ cloud/dropbox/dropboxstorage.o \ cloud/dropbox/dropboxcreatedirectoryrequest.o \ + cloud/dropbox/dropboxinforequest.o \ cloud/dropbox/dropboxlistdirectoryrequest.o \ cloud/dropbox/dropboxuploadrequest.o \ cloud/googledrive/googledrivelistdirectorybyidrequest.o \ |