aboutsummaryrefslogtreecommitdiff
path: root/backends/cloud
diff options
context:
space:
mode:
authorAlexander Tkachev2016-05-30 13:35:53 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commitb9e3730ccd9a76101ef0cb8812f41c371a24d0d6 (patch)
treeac5d34f780c7fbdaae297f8ac5217b46d064a786 /backends/cloud
parentd917592099381402c2681b291d379bda78a1c3f7 (diff)
downloadscummvm-rg350-b9e3730ccd9a76101ef0cb8812f41c371a24d0d6.tar.gz
scummvm-rg350-b9e3730ccd9a76101ef0cb8812f41c371a24d0d6.tar.bz2
scummvm-rg350-b9e3730ccd9a76101ef0cb8812f41c371a24d0d6.zip
CLOUD: Add UploadStatus struct
It contains not just "success" flag, but also "file" struct, so the caller can find out some information about uploaded file - like timestamp.
Diffstat (limited to 'backends/cloud')
-rw-r--r--backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp4
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp50
-rw-r--r--backends/cloud/dropbox/dropboxstorage.h4
-rw-r--r--backends/cloud/dropbox/dropboxuploadrequest.cpp49
-rw-r--r--backends/cloud/dropbox/dropboxuploadrequest.h6
-rw-r--r--backends/cloud/onedrive/onedrivestorage.h3
-rw-r--r--backends/cloud/savessyncrequest.cpp23
-rw-r--r--backends/cloud/savessyncrequest.h2
-rw-r--r--backends/cloud/storage.h25
9 files changed, 124 insertions, 42 deletions
diff --git a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
index 6ea90c150d..89e92facb8 100644
--- a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
+++ b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp
@@ -76,11 +76,11 @@ void DropboxListDirectoryRequest::responseCallback(Networking::JsonResponse pair
Common::JSONArray items = response.getVal("entries")->asArray();
for (uint32 i = 0; i < items.size(); ++i) {
Common::JSONObject item = items[i]->asObject();
- Common::String path = item.getVal("path_lower")->asString();
+ Common::String path = item.getVal("path_lower")->asString();
bool isDirectory = (item.getVal(".tag")->asString() == "folder");
uint32 size = 0, timestamp = 0;
if (!isDirectory) {
- size = item.getVal("size")->asNumber();
+ size = item.getVal("size")->asIntegerNumber();
timestamp = ISO8601::convertToTimestamp(item.getVal("server_modified")->asString());
}
_files.push_back(StorageFile(path, size, timestamp, isDirectory));
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index 1220a99035..1f983cec67 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -104,14 +104,46 @@ void DropboxStorage::printBool(BoolResponse pair) {
debug("bool: %s", (pair.value?"true":"false"));
}
+void DropboxStorage::printUploadStatus(UploadResponse pair) {
+ UploadStatus status = pair.value;
+ if (status.interrupted) {
+ debug("upload interrupted by user");
+ return;
+ }
+ if (status.failed) {
+ debug("upload failed with following response:");
+ debug("%s", status.response.c_str());
+ return;
+ }
+ debug("upload HTTP response code = %ld", status.httpResponseCode);
+ if (!status.failed) {
+ debug("uploaded file info:");
+ debug("path: %s", status.file.path().c_str());
+ debug("size: %u", status.file.size());
+ debug("timestamp: %u", status.file.timestamp());
+ }
+}
+
Networking::Request *DropboxStorage::listDirectory(Common::String path, FileArrayCallback outerCallback, bool recursive) {
return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, recursive));
}
-Networking::Request *DropboxStorage::upload(Common::String path, Common::SeekableReadStream *contents, BoolCallback callback) {
+Networking::Request *DropboxStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) {
return ConnMan.addRequest(new DropboxUploadRequest(_token, path, contents, callback));
}
+Networking::Request *DropboxStorage::upload(Common::String remotePath, Common::String localPath, UploadCallback callback) {
+ Common::File *f = new Common::File();
+ if (!f->open(localPath)) {
+ warning("DropboxStorage: unable to open file to upload from");
+ UploadStatus status(false, true, StorageFile(), "", -1);
+ if (callback) (*callback)(UploadResponse(nullptr, status));
+ delete f;
+ return nullptr;
+ }
+ return upload(remotePath, f, callback);
+}
+
Networking::Request *DropboxStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback callback) {
Common::JSONObject jsonRequestParameters;
jsonRequestParameters.setVal("path", new Common::JSONValue(path));
@@ -155,13 +187,7 @@ Networking::Request *DropboxStorage::syncSaves(BoolCallback callback) {
false
);
*/
- Common::File *file = new Common::File();
- if (!file->open("final.bmp")) {
- warning("no such file");
- delete file;
- return nullptr;
- }
- return upload("/remote/test3.bmp", file, new Common::Callback<DropboxStorage, BoolResponse>(this, &DropboxStorage::printBool));
+ return upload("/remote/test4.bmp", "final.bmp", new Common::Callback<DropboxStorage, UploadResponse>(this, &DropboxStorage::printUploadStatus));
}
Networking::Request *DropboxStorage::info(StorageInfoCallback outerCallback) {
@@ -186,13 +212,13 @@ void DropboxStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networ
if (outerCallback) {
//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")->asNumber());
+ 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();
- uint32 quotaNormal = quota.getVal("normal")->asNumber();
- uint32 quotaShared = quota.getVal("shared")->asNumber();
- uint32 quotaAllocated = quota.getVal("quota")->asNumber();
+ uint32 quotaNormal = quota.getVal("normal")->asIntegerNumber();
+ uint32 quotaShared = quota.getVal("shared")->asIntegerNumber();
+ uint32 quotaAllocated = quota.getVal("quota")->asIntegerNumber();
(*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, name, email, quotaNormal+quotaShared, quotaAllocated)));
delete outerCallback;
}
diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h
index cc515fef41..ca285802a4 100644
--- a/backends/cloud/dropbox/dropboxstorage.h
+++ b/backends/cloud/dropbox/dropboxstorage.h
@@ -47,6 +47,7 @@ class DropboxStorage: public Cloud::Storage {
void printFiles(FileArrayResponse pair);
void printBool(BoolResponse pair);
+ void printUploadStatus(UploadResponse pair);
public:
virtual ~DropboxStorage();
@@ -70,7 +71,8 @@ public:
virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false);
/** Calls the callback when finished. */
- virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, BoolCallback callback);
+ virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback);
+ virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback);
/** Returns pointer to Networking::NetworkReadStream. */
virtual Networking::Request *streamFile(Common::String path, Networking::NetworkReadStreamCallback callback);
diff --git a/backends/cloud/dropbox/dropboxuploadrequest.cpp b/backends/cloud/dropbox/dropboxuploadrequest.cpp
index d068078502..18e1173eef 100644
--- a/backends/cloud/dropbox/dropboxuploadrequest.cpp
+++ b/backends/cloud/dropbox/dropboxuploadrequest.cpp
@@ -21,17 +21,19 @@
*/
#include "backends/cloud/dropbox/dropboxuploadrequest.h"
+#include "backends/cloud/iso8601.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"
#include "common/debug.h"
namespace Cloud {
namespace Dropbox {
-DropboxUploadRequest::DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::BoolCallback callback):
- Networking::Request(0), _token(token), _savePath(path), _contentsStream(contents), _boolCallback(callback),
+DropboxUploadRequest::DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback):
+ Networking::Request(0), _token(token), _savePath(path), _contentsStream(contents), _uploadCallback(callback),
_workingRequest(nullptr), _ignoreCallback(false) {
start();
}
@@ -40,7 +42,7 @@ DropboxUploadRequest::~DropboxUploadRequest() {
_ignoreCallback = true;
if (_workingRequest) _workingRequest->finish();
delete _contentsStream;
- delete _boolCallback;
+ delete _uploadCallback;
}
@@ -105,6 +107,11 @@ void DropboxUploadRequest::partUploadedCallback(Networking::JsonResponse pair) {
if (_ignoreCallback) return;
_workingRequest = nullptr;
+ UploadStatus status;
+ Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)pair.request;
+ if (rq && rq->getNetworkReadStream())
+ status.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode();
+
Common::JSONValue *json = pair.value;
if (json) {
bool needsFinishRequest = false;
@@ -117,13 +124,19 @@ void DropboxUploadRequest::partUploadedCallback(Networking::JsonResponse pair) {
if (response.contains("error") || response.contains("error_summary")) {
warning("Dropbox returned error: %s", response.getVal("error_summary")->asString().c_str());
delete json;
- finish();
+ status.failed = true;
+ status.response = json->stringify(true);
+ finishUpload(status);
return;
}
if (response.contains("server_modified")) {
//finished
- finishBool(true);
+ Common::String path = response.getVal("path_lower")->asString();
+ uint32 size = response.getVal("size")->asIntegerNumber();
+ uint32 timestamp = ISO8601::convertToTimestamp(response.getVal("server_modified")->asString());
+ status.file = StorageFile(path, size, timestamp, false);
+ finishUpload(status);
return;
}
@@ -136,13 +149,19 @@ void DropboxUploadRequest::partUploadedCallback(Networking::JsonResponse pair) {
}
}
- if (!needsFinishRequest && (_contentsStream->eos() || _contentsStream->pos() >= _contentsStream->size() - 1))
- finishBool(true);
- else
+ if (!needsFinishRequest && (_contentsStream->eos() || _contentsStream->pos() >= _contentsStream->size() - 1)) {
+ if (status.file.name() == "") {
+ status.file = StorageFile(_savePath, 0, 0, false);
+ warning("no file info to put into status");
+ }
+ finishUpload(status);
+ } else {
uploadNextPart();
+ }
} else {
- warning("null, not json");
- finish();
+ warning("null, not json");
+ status.failed = true;
+ finishUpload(status);
}
delete json;
@@ -152,11 +171,15 @@ void DropboxUploadRequest::handle() {}
void DropboxUploadRequest::restart() { start(); }
-void DropboxUploadRequest::finish() { finishBool(false); }
+void DropboxUploadRequest::finish() {
+ UploadStatus status;
+ status.interrupted = true;
+ finishUpload(status);
+}
-void DropboxUploadRequest::finishBool(bool success) {
+void DropboxUploadRequest::finishUpload(UploadStatus status) {
Request::finish();
- if (_boolCallback) (*_boolCallback)(Storage::BoolResponse(this, success));
+ if (_uploadCallback) (*_uploadCallback)(Storage::UploadResponse(this, status));
}
} // End of namespace Dropbox
diff --git a/backends/cloud/dropbox/dropboxuploadrequest.h b/backends/cloud/dropbox/dropboxuploadrequest.h
index a7d7a6c581..9b68995969 100644
--- a/backends/cloud/dropbox/dropboxuploadrequest.h
+++ b/backends/cloud/dropbox/dropboxuploadrequest.h
@@ -35,7 +35,7 @@ class DropboxUploadRequest: public Networking::Request {
Common::String _token;
Common::String _savePath;
Common::SeekableReadStream *_contentsStream;
- Storage::BoolCallback _boolCallback;
+ Storage::UploadCallback _uploadCallback;
Request *_workingRequest;
bool _ignoreCallback;
Common::String _sessionId;
@@ -43,10 +43,10 @@ class DropboxUploadRequest: public Networking::Request {
void start();
void uploadNextPart();
void partUploadedCallback(Networking::JsonResponse pair);
- void finishBool(bool success);
+ void finishUpload(UploadStatus status);
public:
- DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::BoolCallback callback);
+ DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback);
virtual ~DropboxUploadRequest();
virtual void handle();
diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h
index 41d84f9770..7028667819 100644
--- a/backends/cloud/onedrive/onedrivestorage.h
+++ b/backends/cloud/onedrive/onedrivestorage.h
@@ -76,7 +76,8 @@ public:
virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false);
/** Calls the callback when finished. */
- virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, BoolCallback callback) { return nullptr; } //TODO
+ virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) { return nullptr; } //TODO
+ virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback) { return nullptr; }
/** Returns pointer to Networking::NetworkReadStream. */
virtual Networking::Request *streamFile(Common::String path, Networking::NetworkReadStreamCallback callback);
diff --git a/backends/cloud/savessyncrequest.cpp b/backends/cloud/savessyncrequest.cpp
index d48ec6ba45..be1075cb4d 100644
--- a/backends/cloud/savessyncrequest.cpp
+++ b/backends/cloud/savessyncrequest.cpp
@@ -23,6 +23,8 @@
#include "backends/cloud/savessyncrequest.h"
#include "common/debug.h"
#include "common/file.h"
+#include "common/system.h"
+#include "common/savefile.h"
namespace Cloud {
@@ -85,6 +87,8 @@ void SavesSyncRequest::directoryListedCallback(Storage::FileArrayResponse pair)
}
}
+ //TODO: upload files which are added to local directory (not available on cloud), but have no timestamp
+
//upload files with invalid timestamp (the ones we've added - means they might not have any remote version)
for (Common::HashMap<Common::String, uint32>::iterator i = _localFilesTimestamps.begin(); i != _localFilesTimestamps.end(); ++i) {
if (i->_value == INVALID_TIMESTAMP)
@@ -104,7 +108,7 @@ void SavesSyncRequest::downloadNextFile() {
_currentDownloadingFile = _filesToDownload.back();
_filesToDownload.pop_back();
- _workingRequest = _storage->download(_currentDownloadingFile.path(), "saves/" + _currentDownloadingFile.name(),
+ _workingRequest = _storage->download(_currentDownloadingFile.path(), "saves/" + _currentDownloadingFile.name(), //TODO: real saves folder here
new Common::Callback<SavesSyncRequest, Storage::BoolResponse>(this, &SavesSyncRequest::fileDownloadedCallback)
);
}
@@ -133,23 +137,24 @@ void SavesSyncRequest::uploadNextFile() {
_currentUploadingFile = _filesToUpload.back();
_filesToUpload.pop_back();
-
- _workingRequest = _storage->upload("saves/" + _currentUploadingFile, nullptr, //TODO: pass save's read stream
- new Common::Callback<SavesSyncRequest, Storage::BoolResponse>(this, &SavesSyncRequest::fileUploadedCallback)
+
+ _workingRequest = _storage->upload("saves/" + _currentUploadingFile, g_system->getSavefileManager()->openForLoading(_currentUploadingFile),
+ new Common::Callback<SavesSyncRequest, Storage::UploadResponse>(this, &SavesSyncRequest::fileUploadedCallback)
);
}
-void SavesSyncRequest::fileUploadedCallback(Storage::BoolResponse pair) {
+void SavesSyncRequest::fileUploadedCallback(Storage::UploadResponse pair) {
if (_ignoreCallback) return;
+ UploadStatus status = pair.value;
//stop syncing if upload failed
- if (!pair.value) {
+ if (status.interrupted || status.failed) {
finish();
return;
}
- //TODO: update local timestamp for the uploaded file
- //_localFilesTimestamps[_currentUploadingFile] = pair.request.<what?>;
+ //update local timestamp for the uploaded file
+ _localFilesTimestamps[_currentUploadingFile] = status.file.timestamp();
//continue uploading files
uploadNextFile();
@@ -172,6 +177,7 @@ void SavesSyncRequest::finishBool(bool success) {
void SavesSyncRequest::loadTimestamps() {
Common::File f;
+ //TODO: real saves folder here
if (!f.open("saves/timestamps"))
error("SavesSyncRequest: failed to open 'saves/timestamps' file to load timestamps");
@@ -215,6 +221,7 @@ void SavesSyncRequest::loadTimestamps() {
void SavesSyncRequest::saveTimestamps() {
Common::DumpFile f;
+ //TODO: real saves folder here
if (!f.open("saves/timestamps", true))
error("SavesSyncRequest: failed to open 'saves/timestamps' file to save timestamps");
Common::String data;
diff --git a/backends/cloud/savessyncrequest.h b/backends/cloud/savessyncrequest.h
index dd43cab2a0..dca1fb750b 100644
--- a/backends/cloud/savessyncrequest.h
+++ b/backends/cloud/savessyncrequest.h
@@ -44,7 +44,7 @@ class SavesSyncRequest: public Networking::Request {
void start();
void directoryListedCallback(Storage::FileArrayResponse pair);
void fileDownloadedCallback(Storage::BoolResponse pair);
- void fileUploadedCallback(Storage::BoolResponse pair);
+ void fileUploadedCallback(Storage::UploadResponse pair);
void downloadNextFile();
void uploadNextFile();
void finishBool(bool success);
diff --git a/backends/cloud/storage.h b/backends/cloud/storage.h
index dbd862822b..1749881a7d 100644
--- a/backends/cloud/storage.h
+++ b/backends/cloud/storage.h
@@ -34,15 +34,37 @@
namespace Cloud {
+/** Struct to represent upload() resulting status. */
+struct UploadStatus {
+ /** true if Request was interrupted (finished by user with finish()) */
+ bool interrupted;
+ /** true if Request has failed (bad server response or some other error occurred) */
+ bool failed;
+ /** Contains uploaded file description (empty if failed) */
+ StorageFile file;
+ /** Server's original response (empty if not failed) */
+ Common::String response;
+ /** Server's HTTP response code. */
+ long httpResponseCode;
+
+ UploadStatus():
+ interrupted(false), failed(false), file(), response(), httpResponseCode(-1) {}
+
+ UploadStatus(bool interrupt, bool failure, StorageFile f, Common::String resp, long code):
+ interrupted(interrupt), failed(failure), file(f), response(resp), httpResponseCode(code) {}
+};
+
class Storage {
public:
typedef Networking::Response<Common::Array<StorageFile>&> FileArrayResponse;
typedef Networking::Response<StorageInfo> StorageInfoResponse;
typedef Networking::Response<bool> BoolResponse;
+ typedef Networking::Response<UploadStatus> UploadResponse;
typedef Common::BaseCallback<FileArrayResponse> *FileArrayCallback;
typedef Common::BaseCallback<StorageInfoResponse> *StorageInfoCallback;
typedef Common::BaseCallback<BoolResponse> *BoolCallback;
+ typedef Common::BaseCallback<UploadResponse> *UploadCallback;
Storage() {}
virtual ~Storage() {}
@@ -72,7 +94,8 @@ public:
virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false) = 0;
/** Calls the callback when finished. */
- virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, BoolCallback callback) = 0;
+ virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) = 0;
+ virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback) = 0;
/** Returns pointer to Networking::NetworkReadStream. */
virtual Networking::Request *streamFile(Common::String path, Networking::NetworkReadStreamCallback callback) = 0;