ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

boxstorage.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00024 
00025 #include <curl/curl.h>
00026 #include "backends/cloud/box/boxstorage.h"
00027 #include "backends/cloud/box/boxlistdirectorybyidrequest.h"
00028 #include "backends/cloud/box/boxtokenrefresher.h"
00029 #include "backends/cloud/box/boxuploadrequest.h"
00030 #include "backends/cloud/cloudmanager.h"
00031 #include "backends/networking/curl/connectionmanager.h"
00032 #include "backends/networking/curl/curljsonrequest.h"
00033 #include "backends/networking/curl/networkreadstream.h"
00034 #include "common/config-manager.h"
00035 #include "common/debug.h"
00036 #include "common/json.h"
00037 
00038 namespace Cloud {
00039 namespace Box {
00040 
00041 #define BOX_API_FOLDERS "https://api.box.com/2.0/folders"
00042 #define BOX_API_FILES_CONTENT "https://api.box.com/2.0/files/%s/content"
00043 #define BOX_API_USERS_ME "https://api.box.com/2.0/users/me"
00044 
00045 BoxStorage::BoxStorage(Common::String token, Common::String refreshToken, bool enabled):
00046     IdStorage(token, refreshToken, enabled) {}
00047 
00048 BoxStorage::BoxStorage(Common::String code, Networking::ErrorCallback cb) {
00049     getAccessToken(code, cb);
00050 }
00051 
00052 BoxStorage::~BoxStorage() {}
00053 
00054 Common::String BoxStorage::cloudProvider() { return "box"; }
00055 
00056 uint32 BoxStorage::storageIndex() { return kStorageBoxId; }
00057 
00058 bool BoxStorage::needsRefreshToken() { return true; }
00059 
00060 bool BoxStorage::canReuseRefreshToken() { return false; }
00061 
00062 void BoxStorage::saveConfig(Common::String keyPrefix) {
00063     ConfMan.set(keyPrefix + "access_token", _token, ConfMan.kCloudDomain);
00064     ConfMan.set(keyPrefix + "refresh_token", _refreshToken, ConfMan.kCloudDomain);
00065     saveIsEnabledFlag(keyPrefix);
00066 }
00067 
00068 Common::String BoxStorage::name() const {
00069     return "Box";
00070 }
00071 
00072 void BoxStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse response) {
00073     Common::JSONValue *json = response.value;
00074     if (!json) {
00075         warning("BoxStorage::infoInnerCallback: NULL passed instead of JSON");
00076         delete outerCallback;
00077         return;
00078     }
00079 
00080     if (!Networking::CurlJsonRequest::jsonIsObject(json, "BoxStorage::infoInnerCallback")) {
00081         delete json;
00082         delete outerCallback;
00083         return;
00084     }
00085 
00086     Common::JSONObject jsonInfo = json->asObject();
00087 
00088     Common::String uid, displayName, email;
00089     uint64 quotaUsed = 0, quotaAllocated = 0;
00090 
00091     // can check that "type": "user"
00092     // there is also "max_upload_size", "phone" and "avatar_url"
00093 
00094     if (Networking::CurlJsonRequest::jsonContainsString(jsonInfo, "id", "BoxStorage::infoInnerCallback"))
00095         uid = jsonInfo.getVal("id")->asString();
00096 
00097     if (Networking::CurlJsonRequest::jsonContainsString(jsonInfo, "name", "BoxStorage::infoInnerCallback"))
00098         displayName = jsonInfo.getVal("name")->asString();
00099 
00100     if (Networking::CurlJsonRequest::jsonContainsString(jsonInfo, "login", "BoxStorage::infoInnerCallback"))
00101         email = jsonInfo.getVal("login")->asString();
00102 
00103     if (Networking::CurlJsonRequest::jsonContainsIntegerNumber(jsonInfo, "space_amount", "BoxStorage::infoInnerCallback"))
00104         quotaAllocated = jsonInfo.getVal("space_amount")->asIntegerNumber();
00105 
00106     if (Networking::CurlJsonRequest::jsonContainsIntegerNumber(jsonInfo, "space_used", "BoxStorage::infoInnerCallback"))
00107         quotaUsed = jsonInfo.getVal("space_used")->asIntegerNumber();
00108 
00109     Common::String username = email;
00110     if (username == "") username = displayName;
00111     if (username == "") username = uid;
00112     CloudMan.setStorageUsername(kStorageBoxId, username);
00113 
00114     if (outerCallback) {
00115         (*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, displayName, email, quotaUsed, quotaAllocated)));
00116         delete outerCallback;
00117     }
00118 
00119     delete json;
00120 }
00121 
00122 Networking::Request *BoxStorage::listDirectoryById(Common::String id, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback) {
00123     if (!errorCallback)
00124         errorCallback = getErrorPrintingCallback();
00125     if (!callback)
00126         callback = getPrintFilesCallback();
00127     return addRequest(new BoxListDirectoryByIdRequest(this, id, callback, errorCallback));
00128 }
00129 
00130 void BoxStorage::createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse response) {
00131     Common::JSONValue *json = response.value;
00132     if (!json) {
00133         warning("BoxStorage::createDirectoryInnerCallback: NULL passed instead of JSON");
00134         delete outerCallback;
00135         return;
00136     }
00137 
00138     if (outerCallback) {
00139         if (Networking::CurlJsonRequest::jsonIsObject(json, "BoxStorage::createDirectoryInnerCallback")) {
00140             Common::JSONObject jsonInfo = json->asObject();
00141             (*outerCallback)(BoolResponse(nullptr, jsonInfo.contains("id")));
00142         } else {
00143             (*outerCallback)(BoolResponse(nullptr, false));
00144         }
00145         delete outerCallback;
00146     }
00147 
00148     delete json;
00149 }
00150 
00151 Networking::Request *BoxStorage::createDirectoryWithParentId(Common::String parentId, Common::String directoryName, BoolCallback callback, Networking::ErrorCallback errorCallback) {
00152     if (!errorCallback)
00153         errorCallback = getErrorPrintingCallback();
00154 
00155     Common::String url = BOX_API_FOLDERS;
00156     Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, BoolResponse, Networking::JsonResponse>(this, &BoxStorage::createDirectoryInnerCallback, callback);
00157     Networking::CurlJsonRequest *request = new BoxTokenRefresher(this, innerCallback, errorCallback, url.c_str());
00158     request->addHeader("Authorization: Bearer " + accessToken());
00159     request->addHeader("Content-Type: application/json");
00160 
00161     Common::JSONObject parentObject;
00162     parentObject.setVal("id", new Common::JSONValue(parentId));
00163 
00164     Common::JSONObject jsonRequestParameters;
00165     jsonRequestParameters.setVal("name", new Common::JSONValue(directoryName));
00166     jsonRequestParameters.setVal("parent", new Common::JSONValue(parentObject));
00167 
00168     Common::JSONValue value(jsonRequestParameters);
00169     request->addPostField(Common::JSON::stringify(&value));
00170 
00171     return addRequest(request);
00172 }
00173 
00174 Networking::Request *BoxStorage::upload(Common::String remotePath, Common::String localPath, UploadCallback callback, Networking::ErrorCallback errorCallback) {
00175     if (!errorCallback)
00176         errorCallback = getErrorPrintingCallback();
00177     return addRequest(new BoxUploadRequest(this, remotePath, localPath, callback, errorCallback));
00178 }
00179 
00180 Networking::Request *BoxStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) {
00181     warning("BoxStorage::upload(ReadStream) not implemented");
00182     if (errorCallback)
00183         (*errorCallback)(Networking::ErrorResponse(nullptr, false, true, "BoxStorage::upload(ReadStream) not implemented", -1));
00184     delete callback;
00185     delete errorCallback;
00186     return nullptr;
00187 }
00188 
00189 bool BoxStorage::uploadStreamSupported() {
00190     return false;
00191 }
00192 
00193 Networking::Request *BoxStorage::streamFileById(Common::String id, Networking::NetworkReadStreamCallback callback, Networking::ErrorCallback errorCallback) {
00194     if (callback) {
00195         Common::String url = Common::String::format(BOX_API_FILES_CONTENT, id.c_str());
00196         Common::String header = "Authorization: Bearer " + _token;
00197         curl_slist *headersList = curl_slist_append(nullptr, header.c_str());
00198         Networking::NetworkReadStream *stream = new Networking::NetworkReadStream(url.c_str(), headersList, "");
00199         (*callback)(Networking::NetworkReadStreamResponse(nullptr, stream));
00200     }
00201     delete callback;
00202     delete errorCallback;
00203     return nullptr;
00204 }
00205 
00206 Networking::Request *BoxStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
00207     Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, StorageInfoResponse, Networking::JsonResponse>(this, &BoxStorage::infoInnerCallback, callback);
00208     Networking::CurlJsonRequest *request = new BoxTokenRefresher(this, innerCallback, errorCallback, BOX_API_USERS_ME);
00209     request->addHeader("Authorization: Bearer " + _token);
00210     return addRequest(request);
00211 }
00212 
00213 Common::String BoxStorage::savesDirectoryPath() { return "residualvm/saves/"; }
00214 
00215 BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) {
00216     if (!ConfMan.hasKey(keyPrefix + "access_token", ConfMan.kCloudDomain)) {
00217         warning("BoxStorage: no access_token found");
00218         return nullptr;
00219     }
00220 
00221     if (!ConfMan.hasKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain)) {
00222         warning("BoxStorage: no refresh_token found");
00223         return nullptr;
00224     }
00225 
00226     Common::String accessToken = ConfMan.get(keyPrefix + "access_token", ConfMan.kCloudDomain);
00227     Common::String refreshToken = ConfMan.get(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
00228     return new BoxStorage(accessToken, refreshToken, loadIsEnabledFlag(keyPrefix));
00229 }
00230 
00231 void BoxStorage::removeFromConfig(Common::String keyPrefix) {
00232     ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain);
00233     ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
00234     removeIsEnabledFlag(keyPrefix);
00235 }
00236 
00237 Common::String BoxStorage::getRootDirectoryId() {
00238     return "0";
00239 }
00240 
00241 } // End of namespace Box
00242 } // End of namespace Cloud


Generated on Sat Aug 15 2020 05:00:58 for ResidualVM by doxygen 1.7.1
curved edge   curved edge