aboutsummaryrefslogtreecommitdiff
path: root/backends/cloud
diff options
context:
space:
mode:
authorAlexander Tkachev2016-05-24 16:19:22 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commit5f4bbe6e9e08f5f76eada84497a7530ffb08fbf1 (patch)
treeca5ab83c41a254c68a816bc62599879bc0b1011e /backends/cloud
parentcaaa4c5a5d0bce7582cc6611d8bde53fbdb1f2d1 (diff)
downloadscummvm-rg350-5f4bbe6e9e08f5f76eada84497a7530ffb08fbf1.tar.gz
scummvm-rg350-5f4bbe6e9e08f5f76eada84497a7530ffb08fbf1.tar.bz2
scummvm-rg350-5f4bbe6e9e08f5f76eada84497a7530ffb08fbf1.zip
CLOUD: Add OneDrive Storage stub
Knows how to OAuth already. This commit also adds CloudManager::addStorage(), so OneDriveStorage can add newly created Storage and CloudManager can save it in the configuration file.
Diffstat (limited to 'backends/cloud')
-rw-r--r--backends/cloud/downloadrequest.cpp2
-rw-r--r--backends/cloud/manager.cpp19
-rw-r--r--backends/cloud/manager.h1
-rw-r--r--backends/cloud/onedrive/onedrivestorage.cpp151
-rw-r--r--backends/cloud/onedrive/onedrivestorage.h119
5 files changed, 289 insertions, 3 deletions
diff --git a/backends/cloud/downloadrequest.cpp b/backends/cloud/downloadrequest.cpp
index 8124fd67d7..e86b6552e9 100644
--- a/backends/cloud/downloadrequest.cpp
+++ b/backends/cloud/downloadrequest.cpp
@@ -45,7 +45,7 @@ bool DownloadRequest::handle() {
return true;
}
- const int kBufSize = 16 * 1024;
+ const int kBufSize = 640 * 1024; //640 KB is enough to everyone?..
char buf[kBufSize];
uint32 readBytes = _remoteFileStream->read(buf, kBufSize);
diff --git a/backends/cloud/manager.cpp b/backends/cloud/manager.cpp
index 1c11efbcef..a7e92dfe03 100644
--- a/backends/cloud/manager.cpp
+++ b/backends/cloud/manager.cpp
@@ -23,6 +23,7 @@
#include "backends/cloud/manager.h"
#include "backends/cloud/dropbox/dropboxstorage.h"
#include "common/config-manager.h"
+#include "onedrive/onedrivestorage.h"
namespace Cloud {
@@ -37,6 +38,7 @@ Manager::~Manager() {
void Manager::init() {
bool offerDropbox = false;
+ bool offerOneDrive = true;
if (ConfMan.hasKey("storages_number", "cloud")) {
int storages = ConfMan.getInt("storages_number", "cloud");
@@ -46,7 +48,10 @@ void Manager::init() {
if (ConfMan.hasKey(keyPrefix + "type", "cloud")) {
Common::String storageType = ConfMan.get(keyPrefix + "type", "cloud");
if (storageType == "Dropbox") loaded = Dropbox::DropboxStorage::loadFromConfig(keyPrefix);
- else warning("Unknown cloud storage type '%s' passed", storageType.c_str());
+ else if (storageType == "OneDrive") {
+ loaded = OneDrive::OneDriveStorage::loadFromConfig(keyPrefix);
+ offerOneDrive = false;
+ } else warning("Unknown cloud storage type '%s' passed", storageType.c_str());
} else {
warning("Cloud storage #%d (out of %d) is missing.", i, storages);
}
@@ -66,8 +71,11 @@ void Manager::init() {
}
if (offerDropbox) {
- //this is temporary console offer to auth with Dropbox (because there is no other storage type yet anyway)
+ //this is temporary console offer to auth with Dropbox
Dropbox::DropboxStorage::authThroughConsole();
+ } else if(offerOneDrive) {
+ //OneDrive time
+ OneDrive::OneDriveStorage::authThroughConsole();
}
}
@@ -79,6 +87,13 @@ void Manager::save() {
ConfMan.flushToDisk();
}
+void Manager::addStorage(Cloud::Storage *storage, bool makeCurrent, bool saveConfig) {
+ if (!storage) error("Cloud::Manager: NULL storage passed");
+ _storages.push_back(storage);
+ if (makeCurrent) _currentStorageIndex = _storages.size() - 1;
+ if (saveConfig) save();
+}
+
Storage *Manager::getCurrentStorage() {
if (_currentStorageIndex < _storages.size())
return _storages[_currentStorageIndex];
diff --git a/backends/cloud/manager.h b/backends/cloud/manager.h
index e531854ba9..08106e0513 100644
--- a/backends/cloud/manager.h
+++ b/backends/cloud/manager.h
@@ -38,6 +38,7 @@ public:
virtual void init();
virtual void save();
+ virtual void addStorage(Cloud::Storage *storage, bool makeCurrent = true, bool saveConfig = true);
virtual Storage *getCurrentStorage();
virtual void syncSaves(Storage::BoolCallback callback);
diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp
new file mode 100644
index 0000000000..b632c74580
--- /dev/null
+++ b/backends/cloud/onedrive/onedrivestorage.cpp
@@ -0,0 +1,151 @@
+/* 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.
+*
+*/
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+
+#include "backends/cloud/onedrive/onedrivestorage.h"
+#include "backends/networking/curl/connectionmanager.h"
+#include "backends/networking/curl/curljsonrequest.h"
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/json.h"
+#include <curl/curl.h>
+#include <common/file.h>
+#include "common/system.h"
+#include "common/cloudmanager.h"
+
+namespace Cloud {
+namespace OneDrive {
+
+Common::String OneDriveStorage::KEY; //can't use ConfMan there yet, loading it on instance creation/auth
+Common::String OneDriveStorage::SECRET; //TODO: hide these secrets somehow
+
+static void saveAccessTokenCallback(void *ptr) {
+ Common::JSONValue *json = (Common::JSONValue *)ptr;
+ if (json) {
+ debug("saveAccessTokenCallback:");
+ debug("%s", json->stringify(true).c_str());
+
+ //TODO: do something about refresh token
+ Common::JSONObject result = json->asObject();
+ if (!result.contains("access_token") || !result.contains("user_id")) {
+ warning("Bad response, no token/user_id passed");
+ } else {
+ OneDriveStorage::addStorage(result.getVal("access_token")->asString(), result.getVal("user_id")->asString());
+ ConfMan.removeKey("onedrive_code", "cloud");
+ debug("Done! You can use OneDrive now! Look:");
+ g_system->getCloudManager()->syncSaves();
+ }
+
+ delete json;
+ } else {
+ debug("saveAccessTokenCallback: got NULL instead of JSON!");
+ }
+}
+
+OneDriveStorage::OneDriveStorage(Common::String accessToken, Common::String userId): _token(accessToken), _uid(userId) {
+ curl_global_init(CURL_GLOBAL_ALL);
+}
+
+OneDriveStorage::~OneDriveStorage() {
+ curl_global_cleanup();
+}
+
+void OneDriveStorage::saveConfig(Common::String keyPrefix) {
+ ConfMan.set(keyPrefix + "type", "OneDrive", "cloud");
+ ConfMan.set(keyPrefix + "access_token", _token, "cloud");
+ ConfMan.set(keyPrefix + "user_id", _uid, "cloud");
+}
+
+void OneDriveStorage::syncSaves(BoolCallback callback) {
+ //this is not the real syncSaves() implementation
+}
+
+void OneDriveStorage::addStorage(Common::String token, Common::String uid) {
+ Storage *storage = new OneDriveStorage(token, uid);
+ g_system->getCloudManager()->addStorage(storage);
+}
+
+OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) {
+ KEY = ConfMan.get("ONEDRIVE_KEY", "cloud");
+ SECRET = ConfMan.get("ONEDRIVE_SECRET", "cloud");
+
+ if (!ConfMan.hasKey(keyPrefix + "access_token", "cloud")) {
+ warning("No access_token found");
+ return 0;
+ }
+
+ if (!ConfMan.hasKey(keyPrefix + "user_id", "cloud")) {
+ warning("No user_id found");
+ return 0;
+ }
+
+ Common::String accessToken = ConfMan.get(keyPrefix + "access_token", "cloud");
+ Common::String userId = ConfMan.get(keyPrefix + "user_id", "cloud");
+ return new OneDriveStorage(accessToken, userId);
+}
+
+Common::String OneDriveStorage::getAuthLink() {
+ Common::String url = "https://login.live.com/oauth20_authorize.srf";
+ url += "?response_type=code";
+ url += "&redirect_uri=http://localhost:12345/"; //that's for copy-pasting
+ //url += "&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F"; //that's "http://localhost:12345/" for automatic opening
+ url += "&client_id=" + KEY;
+ url += "&scope=onedrive.appfolder"; //TODO
+ return url;
+}
+
+void OneDriveStorage::authThroughConsole() {
+ if (!ConfMan.hasKey("ONEDRIVE_KEY", "cloud") || !ConfMan.hasKey("ONEDRIVE_SECRET", "cloud")) {
+ warning("No OneDrive keys available, cannot do auth");
+ return;
+ }
+
+ KEY = ConfMan.get("ONEDRIVE_KEY", "cloud");
+ SECRET = ConfMan.get("ONEDRIVE_SECRET", "cloud");
+
+ if (ConfMan.hasKey("onedrive_code", "cloud")) {
+ //phase 2: get access_token using specified code
+ getAccessToken(ConfMan.get("onedrive_code", "cloud"));
+ return;
+ }
+
+ debug("Navigate to this URL and press \"Allow\":");
+ debug("%s\n", getAuthLink().c_str());
+ debug("Then, add onedrive_code key in [cloud] section of configuration file. You should copy the <code> value from URL and put it as value for that key.\n");
+ debug("Navigate to this URL to get more information on ScummVM's configuration files:");
+ debug("http://wiki.scummvm.org/index.php/User_Manual/Configuring_ScummVM#Using_the_configuration_file_to_configure_ScummVM\n");
+}
+
+void OneDriveStorage::getAccessToken(Common::String code) {
+ Common::BaseCallback<> *callback = new Common::GlobalFunctionCallback(saveAccessTokenCallback);
+ Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, "https://login.live.com/oauth20_token.srf");
+ //Content-Type: application/x-www-form-urlencoded
+ request->addPostField("code=" + code);
+ request->addPostField("grant_type=authorization_code");
+ request->addPostField("client_id=" + KEY);
+ request->addPostField("client_secret=" + SECRET);
+ request->addPostField("&redirect_uri=http%3A%2F%2Flocalhost%3A12345%2F");
+ ConnMan.addRequest(request);
+}
+
+} //end of namespace OneDrive
+} //end of namespace Cloud
diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h
new file mode 100644
index 0000000000..99f8476bc1
--- /dev/null
+++ b/backends/cloud/onedrive/onedrivestorage.h
@@ -0,0 +1,119 @@
+/* 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_ONEDRIVE_ONEDRIVESTORAGE_H
+#define BACKENDS_CLOUD_ONEDRIVE_ONEDRIVESTORAGE_H
+
+#include "backends/cloud/storage.h"
+#include "common/callback.h"
+
+namespace Cloud {
+namespace OneDrive {
+
+class OneDriveStorage: public Cloud::Storage {
+ static Common::String KEY, SECRET;
+
+ Common::String _token, _uid;
+
+ /** This private constructor is called from loadFromConfig(). */
+ OneDriveStorage(Common::String token, Common::String uid);
+
+ static void getAccessToken(Common::String code);
+
+public:
+ virtual ~OneDriveStorage();
+
+ /**
+ * Storage methods, which are used by CloudManager to save
+ * storage in configuration file.
+ */
+
+ /**
+ * Save storage data using ConfMan.
+ * @param keyPrefix all saved keys must start with this prefix.
+ * @note every Storage must write keyPrefix + "type" key
+ * with common value (e.g. "Dropbox").
+ */
+
+ virtual void saveConfig(Common::String keyPrefix);
+
+ /** Public Cloud API comes down there. */
+
+ /** Returns Common::Array<StorageFile>. */
+ virtual void listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false) {} //TODO
+
+ /** Calls the callback when finished. */
+ virtual void upload(Common::String path, Common::ReadStream *contents, BoolCallback callback) {} //TODO
+
+ /** Returns pointer to Networking::NetworkReadStream. */
+ virtual Networking::NetworkReadStream *streamFile(Common::String path) { return 0; } //TODO
+
+ /** Calls the callback when finished. */
+ virtual void download(Common::String remotePath, Common::String localPath, BoolCallback callback) {} //TODO
+
+ /** Calls the callback when finished. */
+ virtual void remove(Common::String path, BoolCallback callback) {} //TODO
+
+ /** Calls the callback when finished. */
+ virtual void syncSaves(BoolCallback callback);
+
+ /** Calls the callback when finished. */
+ virtual void createDirectory(Common::String path, BoolCallback callback) {} //TODO
+
+ /** Calls the callback when finished. */
+ virtual void touch(Common::String path, BoolCallback callback) {} //TODO
+
+ /** Returns the StorageInfo struct. */
+ virtual void info(StorageInfoCallback callback) {} //TODO
+
+ /** Returns whether saves sync process is running. */
+ virtual bool isSyncing() { return false; } //TODO
+
+ /** Returns whether there are any requests running. */
+ virtual bool isWorking() { return false; } //TODO
+
+ /**
+ * Add OneDriveStorage with given token and uid into Cloud::Manager.
+ */
+ static void addStorage(Common::String token, Common::String uid);
+
+ /**
+ * Load token and user id from configs and return OneDriveStorage for those.
+ * @return pointer to the newly created OneDriveStorage or 0 if some problem occured.
+ */
+ static OneDriveStorage *loadFromConfig(Common::String keyPrefix);
+
+ /**
+ * Returns OneDrive auth link.
+ */
+ static Common::String getAuthLink();
+
+ /**
+ * Show message with OneDrive auth instructions. (Temporary)
+ */
+ static void authThroughConsole();
+};
+
+} //end of namespace OneDrive
+} //end of namespace Cloud
+
+#endif