aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorAlexander Tkachev2016-05-30 21:21:31 +0600
committerAlexander Tkachev2016-08-24 16:07:55 +0600
commitaf37ecca3430c871ec8a03bcada90303e6bf9877 (patch)
tree228be82f1e2ff570d12507b1884ab2279f028c1f /backends
parentcc4512e50b5489ec57adc05b3c2277c132bed767 (diff)
downloadscummvm-rg350-af37ecca3430c871ec8a03bcada90303e6bf9877.tar.gz
scummvm-rg350-af37ecca3430c871ec8a03bcada90303e6bf9877.tar.bz2
scummvm-rg350-af37ecca3430c871ec8a03bcada90303e6bf9877.zip
CLOUD: Make SavesSyncRequest work
It now actually read the "timestamps" file, loads and saves files as it should, ignores Dropbox's "not_found" error.
Diffstat (limited to 'backends')
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp16
-rw-r--r--backends/cloud/savessyncrequest.cpp132
-rw-r--r--backends/cloud/savessyncrequest.h6
3 files changed, 121 insertions, 33 deletions
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index 4a17afe6c6..b33e2b6776 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -33,6 +33,9 @@
#include "common/file.h"
#include "common/json.h"
#include <curl/curl.h>
+#include "common/system.h"
+#include "common/savefile.h"
+#include "../savessyncrequest.h"
namespace Cloud {
namespace Dropbox {
@@ -188,7 +191,18 @@ Networking::Request *DropboxStorage::syncSaves(BoolCallback callback) {
false
);
*/
- return upload("/remote/test4.bmp", "final.bmp", new Common::Callback<DropboxStorage, UploadResponse>(this, &DropboxStorage::printUploadStatus));
+ /*
+ debug("%s", ConfMan.get("savepath").c_str());
+ Common::StringArray arr = g_system->getSavefileManager()->listSavefiles("*");
+ for (uint32 i = 0; i < arr.size(); ++i) {
+ debug("%s", arr[i].c_str());
+ }
+ debug("EOL");
+ */
+ //return upload("/remote/backslash", "C:\\Users\\Tkachov\\AppData\\Roaming\\ScummVM\\Saved games\\sword25.000", new Common::Callback<DropboxStorage, UploadResponse>(this, &DropboxStorage::printUploadStatus));
+ //return upload("/remote/slash", "C:/Users/Tkachov/AppData/Roaming/ScummVM/Saved games/sword25.000", new Common::Callback<DropboxStorage, UploadResponse>(this, &DropboxStorage::printUploadStatus));
+ return ConnMan.addRequest(new SavesSyncRequest(this, 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) {
diff --git a/backends/cloud/savessyncrequest.cpp b/backends/cloud/savessyncrequest.cpp
index 96386ee62c..e632bfff84 100644
--- a/backends/cloud/savessyncrequest.cpp
+++ b/backends/cloud/savessyncrequest.cpp
@@ -21,13 +21,17 @@
*/
#include "backends/cloud/savessyncrequest.h"
+#include "common/config-manager.h"
#include "common/debug.h"
#include "common/file.h"
-#include "common/system.h"
#include "common/savefile.h"
+#include "common/system.h"
+#include <common/json.h>
namespace Cloud {
+const char *SavesSyncRequest::TIMESTAMPS_FILENAME = "timestamps";
+
SavesSyncRequest::SavesSyncRequest(Storage *storage, Storage::BoolCallback callback):
Request(nullptr), _storage(storage), _boolCallback(callback),
_workingRequest(nullptr), _ignoreCallback(false) {
@@ -55,25 +59,44 @@ void SavesSyncRequest::start() {
loadTimestamps();
//list saves directory
- _workingRequest = _storage->listDirectory("saves", new Common::Callback<SavesSyncRequest, Storage::ListDirectoryResponse>(this, &SavesSyncRequest::directoryListedCallback));
+ _workingRequest = _storage->listDirectory("/saves", new Common::Callback<SavesSyncRequest, Storage::ListDirectoryResponse>(this, &SavesSyncRequest::directoryListedCallback));
}
void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse pair) {
+ _workingRequest = nullptr;
if (_ignoreCallback) return;
ListDirectoryStatus status = pair.value;
- if (status.interrupted || status.failed) {
+ bool irrecoverable = status.interrupted || status.failed;
+ if (status.failed) {
+ Common::JSONValue *value = Common::JSON::parse(status.response.c_str());
+ if (value) {
+ if (value->isObject()) {
+ Common::JSONObject object = value->asObject();
+ //Dropbox-related error:
+ if (object.contains("error_summary")) {
+ Common::String summary = object.getVal("error_summary")->asString();
+ if (summary.contains("not_found")) {
+ //oh how lucky we are! It's just user don't have /cloud/ folder yet!
+ irrecoverable = false;
+ }
+ }
+ }
+ delete value;
+ }
+ }
+
+ if (irrecoverable) {
finishBool(false);
return;
}
-
- const uint32 INVALID_TIMESTAMP = UINT_MAX;
//determine which files to download and which files to upload
Common::Array<StorageFile> &remoteFiles = status.files;
for (uint32 i = 0; i < remoteFiles.size(); ++i) {
StorageFile &file = remoteFiles[i];
if (file.isDirectory()) continue;
+ if (file.name() == TIMESTAMPS_FILENAME) continue;
Common::String name = file.name();
if (!_localFilesTimestamps.contains(name))
_filesToDownload.push_back(file);
@@ -92,14 +115,24 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse pa
}
}
- //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->_key == TIMESTAMPS_FILENAME) continue;
if (i->_value == INVALID_TIMESTAMP)
_filesToUpload.push_back(i->_key);
}
+ ///////
+ debug("\ndownload files:");
+ for (uint32 i = 0; i < _filesToDownload.size(); ++i) {
+ debug("%s", _filesToDownload[i].name().c_str());
+ }
+ debug("\nupload files:");
+ for (uint32 i = 0; i < _filesToUpload.size(); ++i) {
+ debug("%s", _filesToUpload[i].c_str());
+ }
+ ///////
+
//start downloading files
downloadNextFile();
}
@@ -113,12 +146,16 @@ void SavesSyncRequest::downloadNextFile() {
_currentDownloadingFile = _filesToDownload.back();
_filesToDownload.pop_back();
- _workingRequest = _storage->download(_currentDownloadingFile.path(), "saves/" + _currentDownloadingFile.name(), //TODO: real saves folder here
+ ///////
+ debug("downloading %s", _currentDownloadingFile.name().c_str());
+ ///////
+ _workingRequest = _storage->download(_currentDownloadingFile.path(), concatWithSavesPath(_currentDownloadingFile.name()),
new Common::Callback<SavesSyncRequest, Storage::BoolResponse>(this, &SavesSyncRequest::fileDownloadedCallback)
);
}
void SavesSyncRequest::fileDownloadedCallback(Storage::BoolResponse pair) {
+ _workingRequest = nullptr;
if (_ignoreCallback) return;
//stop syncing if download failed
@@ -143,12 +180,16 @@ void SavesSyncRequest::uploadNextFile() {
_currentUploadingFile = _filesToUpload.back();
_filesToUpload.pop_back();
- _workingRequest = _storage->upload("saves/" + _currentUploadingFile, g_system->getSavefileManager()->openForLoading(_currentUploadingFile),
+ ///////
+ debug("uploading %s", _currentUploadingFile.c_str());
+ ///////
+ _workingRequest = _storage->upload("/saves/" + _currentUploadingFile, g_system->getSavefileManager()->openRawFile(_currentUploadingFile),
new Common::Callback<SavesSyncRequest, Storage::UploadResponse>(this, &SavesSyncRequest::fileUploadedCallback)
);
}
void SavesSyncRequest::fileUploadedCallback(Storage::UploadResponse pair) {
+ _workingRequest = nullptr;
if (_ignoreCallback) return;
UploadStatus status = pair.value;
@@ -181,16 +222,24 @@ 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");
+ //start with listing all the files in saves/ directory and setting invalid timestamp to them
+ Common::StringArray localFiles = g_system->getSavefileManager()->listSavefiles("*");
+ for (uint32 i = 0; i < localFiles.size(); ++i)
+ _localFilesTimestamps[localFiles[i]] = INVALID_TIMESTAMP;
+
+ //now actually load timestamps from file
+ Common::InSaveFile *file = g_system->getSavefileManager()->openRawFile(TIMESTAMPS_FILENAME);
+ if (!file) {
+ warning("SavesSyncRequest: failed to open '%s' file to load timestamps", TIMESTAMPS_FILENAME);
+ return;
+ }
+
- while (!f.eos()) {
+ while (!file->eos()) {
//read filename into buffer (reading until the first ' ')
Common::String buffer;
- while (!f.eos()) {
- byte b = f.readByte();
+ while (!file->eos()) {
+ byte b = file->readByte();
if (b == ' ') break;
buffer += (char)b;
}
@@ -199,8 +248,8 @@ void SavesSyncRequest::loadTimestamps() {
Common::String filename = buffer;
bool lineEnded = false;
buffer = "";
- while (!f.eos()) {
- byte b = f.readByte();
+ while (!file->eos()) {
+ byte b = file->readByte();
if (b == ' ' || b == '\n' || b == '\r') {
lineEnded = (b == '\n');
break;
@@ -210,32 +259,53 @@ void SavesSyncRequest::loadTimestamps() {
//parse timestamp
uint timestamp = atol(buffer.c_str());
+ if (buffer == "" || timestamp == 0) break;
_localFilesTimestamps[filename] = timestamp;
//read until the end of the line
if (!lineEnded) {
- while (!f.eos()) {
- byte b = f.readByte();
+ while (!file->eos()) {
+ byte b = file->readByte();
if (b == '\n') break;
}
}
}
-
- f.close();
+
+ delete file;
}
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;
- for (Common::HashMap<Common::String, uint32>::iterator i = _localFilesTimestamps.begin(); i != _localFilesTimestamps.end(); ++i)
- data += i->_key + Common::String::format(" %u\n", i->_value);
- if (f.write(data.c_str(), data.size()) != data.size())
- error("SavesSyncRequest: failed to write timestamps data into 'saves/timestamps'");
+ Common::DumpFile f;
+ Common::String filename = concatWithSavesPath(TIMESTAMPS_FILENAME);
+ if (!f.open(filename, true)) {
+ warning("SavesSyncRequest: failed to open '%s' file to save timestamps", filename.c_str());
+ return;
+ }
+
+ for (Common::HashMap<Common::String, uint32>::iterator i = _localFilesTimestamps.begin(); i != _localFilesTimestamps.end(); ++i) {
+ Common::String data = i->_key + Common::String::format(" %u\n", i->_value);
+ if (f.write(data.c_str(), data.size()) != data.size()) {
+ warning("SavesSyncRequest: failed to write timestamps data into '%s'", filename.c_str());
+ return;
+ }
+ }
+
f.close();
}
+Common::String SavesSyncRequest::concatWithSavesPath(Common::String name) {
+ Common::String path = ConfMan.get("savepath");
+ if (path.size() > 0 && (path.lastChar() == '/' || path.lastChar() == '\\'))
+ return path + name;
+
+ //simple heuristic to determine which path separator to use
+ int backslashes = 0;
+ for (uint32 i = 0; i < path.size(); ++i)
+ if (path[i] == '/') --backslashes;
+ else if (path[i] == '\\') ++backslashes;
+
+ if (backslashes) return path + '\\' + name;
+ return path + '/' + name;
+}
} // End of namespace Cloud
diff --git a/backends/cloud/savessyncrequest.h b/backends/cloud/savessyncrequest.h
index f2f2aba403..da7b27e9b6 100644
--- a/backends/cloud/savessyncrequest.h
+++ b/backends/cloud/savessyncrequest.h
@@ -31,6 +31,9 @@
namespace Cloud {
class SavesSyncRequest: public Networking::Request {
+ const uint32 INVALID_TIMESTAMP = UINT_MAX;
+ static const char *TIMESTAMPS_FILENAME;
+
Storage *_storage;
Storage::BoolCallback _boolCallback;
Common::HashMap<Common::String, uint32> _localFilesTimestamps;
@@ -49,7 +52,8 @@ class SavesSyncRequest: public Networking::Request {
void uploadNextFile();
void finishBool(bool success);
void loadTimestamps();
- void saveTimestamps();
+ void saveTimestamps();
+ Common::String concatWithSavesPath(Common::String name);
public:
SavesSyncRequest(Storage *storage, Storage::BoolCallback callback);
virtual ~SavesSyncRequest();