diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/cloud/box/boxstorage.cpp | 47 | ||||
| -rw-r--r-- | backends/cloud/box/boxstorage.h | 5 | ||||
| -rw-r--r-- | backends/cloud/id/idcreatedirectoryrequest.cpp | 146 | ||||
| -rw-r--r-- | backends/cloud/id/idcreatedirectoryrequest.h | 65 | ||||
| -rw-r--r-- | backends/cloud/id/idstorage.cpp | 19 | ||||
| -rw-r--r-- | backends/cloud/id/idstorage.h | 4 | ||||
| -rw-r--r-- | backends/module.mk | 1 | 
7 files changed, 277 insertions, 10 deletions
diff --git a/backends/cloud/box/boxstorage.cpp b/backends/cloud/box/boxstorage.cpp index 3681cbfaa8..5bbe377163 100644 --- a/backends/cloud/box/boxstorage.cpp +++ b/backends/cloud/box/boxstorage.cpp @@ -205,6 +205,45 @@ Networking::Request *BoxStorage::listDirectoryById(Common::String id, ListDirect  	return addRequest(new BoxListDirectoryByIdRequest(this, id, callback, errorCallback));  } +void BoxStorage::createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse response) { +	Common::JSONValue *json = response.value; +	if (!json) { +		warning("NULL passed instead of JSON"); +		delete outerCallback; +		return; +	} + +	if (outerCallback) { +		Common::JSONObject info = json->asObject(); +		(*outerCallback)(BoolResponse(nullptr, info.contains("id"))); +		delete outerCallback; +	} + +	delete json; +} + +Networking::Request *BoxStorage::createDirectoryWithParentId(Common::String parentId, Common::String name, BoolCallback callback, Networking::ErrorCallback errorCallback) { +	if (!errorCallback) errorCallback = getErrorPrintingCallback(); + +	Common::String url = "https://api.box.com/2.0/folders"; +	Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, BoolResponse, Networking::JsonResponse>(this, &BoxStorage::createDirectoryInnerCallback, callback); +	Networking::CurlJsonRequest *request = new BoxTokenRefresher(this, innerCallback, errorCallback, url.c_str()); +	request->addHeader("Authorization: Bearer " + accessToken()); +	request->addHeader("Content-Type: application/json"); + +	Common::JSONObject parentObject; +	parentObject.setVal("id", new Common::JSONValue(parentId)); + +	Common::JSONObject jsonRequestParameters;	 +	jsonRequestParameters.setVal("name", new Common::JSONValue(name)); +	jsonRequestParameters.setVal("parent", new Common::JSONValue(parentObject)); + +	Common::JSONValue value(jsonRequestParameters); +	request->addPostField(Common::JSON::stringify(&value)); + +	return addRequest(request); +} +  Networking::Request *BoxStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) {  	//return addRequest(new BoxUploadRequest(this, path, contents, callback, errorCallback));  	return nullptr; //TODO @@ -226,12 +265,6 @@ void BoxStorage::fileDownloaded(BoolResponse response) {  	else debug("download failed!");  } -Networking::Request *BoxStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) { -	if (!errorCallback) errorCallback = getErrorPrintingCallback(); -	//return addRequest(new BoxCreateDirectoryRequest(this, path, callback, errorCallback)); -	return nullptr; //TODO -} -  Networking::Request *BoxStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {  	Networking::JsonCallback innerCallback = new Common::CallbackBridge<BoxStorage, StorageInfoResponse, Networking::JsonResponse>(this, &BoxStorage::infoInnerCallback, callback);  	Networking::CurlJsonRequest *request = new BoxTokenRefresher(this, innerCallback, errorCallback, "https://api.box.com/2.0/users/me"); @@ -239,7 +272,7 @@ Networking::Request *BoxStorage::info(StorageInfoCallback callback, Networking::  	return addRequest(request);  } -Common::String BoxStorage::savesDirectoryPath() { return "saves/"; } +Common::String BoxStorage::savesDirectoryPath() { return "scummvm/saves/"; }  BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) {  	loadKeyAndSecret(); diff --git a/backends/cloud/box/boxstorage.h b/backends/cloud/box/boxstorage.h index 865358c845..3b02f88212 100644 --- a/backends/cloud/box/boxstorage.h +++ b/backends/cloud/box/boxstorage.h @@ -49,6 +49,7 @@ class BoxStorage: public Id::IdStorage {  	void fileDownloaded(BoolResponse response);  	void fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response); +	void createDirectoryInnerCallback(BoolCallback outerCallback, Networking::JsonResponse response);  public:	  	/** This constructor uses OAuth code flow to get tokens. */  	BoxStorage(Common::String code); @@ -76,6 +77,7 @@ public:  	/** Public Cloud API comes down there. */  	virtual Networking::Request *listDirectoryById(Common::String id, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback); +	virtual Networking::Request *createDirectoryWithParentId(Common::String parentId, Common::String name, BoolCallback callback, Networking::ErrorCallback errorCallback);  	/** Returns UploadStatus struct with info about uploaded file. */  	virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback); @@ -86,9 +88,6 @@ public:  	/** Calls the callback when finished. */  	virtual Networking::Request *remove(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) { return nullptr; } //TODO -	/** Calls the callback when finished. */ -	virtual Networking::Request *createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback); -  	/** Returns the StorageInfo struct. */  	virtual Networking::Request *info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback); diff --git a/backends/cloud/id/idcreatedirectoryrequest.cpp b/backends/cloud/id/idcreatedirectoryrequest.cpp new file mode 100644 index 0000000000..7968a4b126 --- /dev/null +++ b/backends/cloud/id/idcreatedirectoryrequest.cpp @@ -0,0 +1,146 @@ +/* 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/id/idcreatedirectoryrequest.h" +#include "backends/cloud/id/idstorage.h" +#include "common/debug.h" + +namespace Cloud { +namespace Id { + +IdCreateDirectoryRequest::IdCreateDirectoryRequest(IdStorage *storage, Common::String parentPath, Common::String directoryName, Storage::BoolCallback cb, Networking::ErrorCallback ecb): +	Networking::Request(nullptr, ecb), +	_requestedParentPath(parentPath), _requestedDirectoryName(directoryName), _storage(storage), _boolCallback(cb), +	_workingRequest(nullptr), _ignoreCallback(false) { +	start(); +} + +IdCreateDirectoryRequest::~IdCreateDirectoryRequest() { +	_ignoreCallback = true; +	if (_workingRequest) _workingRequest->finish(); +	delete _boolCallback; +} + +void IdCreateDirectoryRequest::start() { +	//cleanup +	_ignoreCallback = true; +	if (_workingRequest) _workingRequest->finish(); +	_workingRequest = nullptr; +	_ignoreCallback = false; + +	//the only exception when we create parent folder - is when it's ScummVM/ base folder +	Common::String prefix = _requestedParentPath; +	if (prefix.size() > 7) prefix.erase(7); +	if (prefix.equalsIgnoreCase("ScummVM")) { +		Storage::BoolCallback callback = new Common::Callback<IdCreateDirectoryRequest, Storage::BoolResponse>(this, &IdCreateDirectoryRequest::createdBaseDirectoryCallback); +		Networking::ErrorCallback failureCallback = new Common::Callback<IdCreateDirectoryRequest, Networking::ErrorResponse>(this, &IdCreateDirectoryRequest::createdBaseDirectoryErrorCallback); +		_workingRequest = _storage->createDirectory("ScummVM", callback, failureCallback); +		return; +	} +	 +	resolveId(); +} + +void IdCreateDirectoryRequest::createdBaseDirectoryCallback(Storage::BoolResponse response) { +	_workingRequest = nullptr; +	if (_ignoreCallback) return; +	if (response.request) _date = response.request->date(); +	resolveId(); +} + +void IdCreateDirectoryRequest::createdBaseDirectoryErrorCallback(Networking::ErrorResponse error) { +	_workingRequest = nullptr; +	if (_ignoreCallback) return; +	if (error.request) _date = error.request->date(); +	finishError(error); +} + +void IdCreateDirectoryRequest::resolveId() { +	//check whether such folder already exists +	Storage::UploadCallback innerCallback = new Common::Callback<IdCreateDirectoryRequest, Storage::UploadResponse>(this, &IdCreateDirectoryRequest::idResolvedCallback); +	Networking::ErrorCallback innerErrorCallback = new Common::Callback<IdCreateDirectoryRequest, Networking::ErrorResponse>(this, &IdCreateDirectoryRequest::idResolveFailedCallback); +	Common::String path = _requestedParentPath; +	if (_requestedParentPath != "") path += "/"; +	path += _requestedDirectoryName; +	_workingRequest = _storage->resolveFileId(path, innerCallback, innerErrorCallback); +} + +void IdCreateDirectoryRequest::idResolvedCallback(Storage::UploadResponse response) { +	_workingRequest = nullptr; +	if (_ignoreCallback) return; +	if (response.request) _date = response.request->date(); + +	//resolved => folder already exists +	finishCreation(false); +} + +void IdCreateDirectoryRequest::idResolveFailedCallback(Networking::ErrorResponse error) { +	_workingRequest = nullptr; +	if (_ignoreCallback) return; +	if (error.request) _date = error.request->date(); +	 +	//not resolved => folder not exists +	if (error.response.contains("no such file found in its parent directory")) {		 +		//parent's id after the '\n' +		Common::String parentId = error.response; +		for (uint32 i = 0; i < parentId.size(); ++i) +			if (parentId[i] == '\n') { +				parentId.erase(0, i+1); +				break; +			} + +		Storage::BoolCallback callback = new Common::Callback<IdCreateDirectoryRequest, Storage::BoolResponse>(this, &IdCreateDirectoryRequest::createdDirectoryCallback); +		Networking::ErrorCallback failureCallback = new Common::Callback<IdCreateDirectoryRequest, Networking::ErrorResponse>(this, &IdCreateDirectoryRequest::createdDirectoryErrorCallback); +		_workingRequest = _storage->createDirectoryWithParentId(parentId, _requestedDirectoryName, callback, failureCallback); +		return; +	} + +	finishError(error); +} + +void IdCreateDirectoryRequest::createdDirectoryCallback(Storage::BoolResponse response) { +	_workingRequest = nullptr; +	if (_ignoreCallback) return; +	if (response.request) _date = response.request->date(); +	finishCreation(response.value); +} + +void IdCreateDirectoryRequest::createdDirectoryErrorCallback(Networking::ErrorResponse error) { +	_workingRequest = nullptr; +	if (_ignoreCallback) return; +	if (error.request) _date = error.request->date(); +	finishError(error); +} + +void IdCreateDirectoryRequest::handle() {} + +void IdCreateDirectoryRequest::restart() { start(); } + +Common::String IdCreateDirectoryRequest::date() const { return _date; } + +void IdCreateDirectoryRequest::finishCreation(bool success) { +	Request::finishSuccess(); +	if (_boolCallback) (*_boolCallback)(Storage::BoolResponse(this, success)); +} + +} // End of namespace Id +} // End of namespace Cloud diff --git a/backends/cloud/id/idcreatedirectoryrequest.h b/backends/cloud/id/idcreatedirectoryrequest.h new file mode 100644 index 0000000000..241bcd30be --- /dev/null +++ b/backends/cloud/id/idcreatedirectoryrequest.h @@ -0,0 +1,65 @@ +/* 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_ID_IDCREATEDIRECTORYREQUEST_H +#define BACKENDS_CLOUD_ID_IDCREATEDIRECTORYREQUEST_H + +#include "backends/cloud/storage.h" +#include "backends/networking/curl/request.h" +#include "common/callback.h" + +namespace Cloud { +namespace Id { + +class IdStorage; + +class IdCreateDirectoryRequest: public Networking::Request { +	Common::String _requestedParentPath; +	Common::String _requestedDirectoryName; +	IdStorage *_storage; +	Storage::BoolCallback _boolCallback; +	Request *_workingRequest; +	bool _ignoreCallback; +	Common::String _date; + +	void start(); +	void createdBaseDirectoryCallback(Storage::BoolResponse response); +	void createdBaseDirectoryErrorCallback(Networking::ErrorResponse error); +	void resolveId(); +	void idResolvedCallback(Storage::UploadResponse response); +	void idResolveFailedCallback(Networking::ErrorResponse error); +	void createdDirectoryCallback(Storage::BoolResponse response); +	void createdDirectoryErrorCallback(Networking::ErrorResponse error); +	void finishCreation(bool success); +public: +	IdCreateDirectoryRequest(IdStorage *storage, Common::String parentPath, Common::String directoryName, Storage::BoolCallback cb, Networking::ErrorCallback ecb); +	virtual ~IdCreateDirectoryRequest(); + +	virtual void handle(); +	virtual void restart(); +	virtual Common::String date() const; +}; + +} // End of namespace Id +} // End of namespace Cloud + +#endif diff --git a/backends/cloud/id/idstorage.cpp b/backends/cloud/id/idstorage.cpp index aed1738d4f..f26dee4692 100644 --- a/backends/cloud/id/idstorage.cpp +++ b/backends/cloud/id/idstorage.cpp @@ -22,6 +22,7 @@  #define FORBIDDEN_SYMBOL_ALLOW_ALL  #include "backends/cloud/id/idstorage.h" +#include "backends/cloud/id/idcreatedirectoryrequest.h"  #include "backends/cloud/id/idlistdirectoryrequest.h"  #include "backends/cloud/id/idresolveidrequest.h"  #include "common/debug.h" @@ -82,5 +83,23 @@ Networking::Request *IdStorage::listDirectory(Common::String path, ListDirectory  	return addRequest(new IdListDirectoryRequest(this, path, callback, errorCallback, recursive));  } +Networking::Request *IdStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) { +	if (!errorCallback) errorCallback = getErrorPrintingCallback(); +	if (!callback) callback = new Common::Callback<IdStorage, BoolResponse>(this, &IdStorage::printBool); + +	//find out the parent path and directory name +	Common::String parentPath = "", directoryName = path; +	for (uint32 i = path.size(); i > 0; --i) { +		if (path[i - 1] == '/' || path[i - 1] == '\\') { +			parentPath = path; +			parentPath.erase(i - 1); +			directoryName.erase(0, i); +			break; +		} +	} + +	return addRequest(new IdCreateDirectoryRequest(this, parentPath, directoryName, callback, errorCallback)); +} +  } // End of namespace Id  } // End of namespace Cloud diff --git a/backends/cloud/id/idstorage.h b/backends/cloud/id/idstorage.h index a5e1c1e22c..a657f5cd95 100644 --- a/backends/cloud/id/idstorage.h +++ b/backends/cloud/id/idstorage.h @@ -64,6 +64,10 @@ public:  	virtual Networking::Request *listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive = false);  	virtual Networking::Request *listDirectoryById(Common::String id, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback) = 0; +	/** Calls the callback when finished. */ +	virtual Networking::Request *createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback); +	virtual Networking::Request *createDirectoryWithParentId(Common::String parentId, Common::String name, BoolCallback callback, Networking::ErrorCallback errorCallback) = 0; +  	virtual Common::String getRootDirectoryId() = 0;  }; diff --git a/backends/module.mk b/backends/module.mk index 3c3b343e98..617611932e 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -45,6 +45,7 @@ MODULE_OBJS += \  	cloud/googledrive/googledrivetokenrefresher.o \  	cloud/googledrive/googledriveuploadrequest.o \  	cloud/id/idstorage.o \ +	cloud/id/idcreatedirectoryrequest.o \  	cloud/id/idlistdirectoryrequest.o \  	cloud/id/idresolveidrequest.o \  	cloud/onedrive/onedrivestorage.o \  | 
