diff options
author | Alexander Tkachev | 2016-05-30 21:21:31 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | af37ecca3430c871ec8a03bcada90303e6bf9877 (patch) | |
tree | 228be82f1e2ff570d12507b1884ab2279f028c1f /backends | |
parent | cc4512e50b5489ec57adc05b3c2277c132bed767 (diff) | |
download | scummvm-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.cpp | 16 | ||||
-rw-r--r-- | backends/cloud/savessyncrequest.cpp | 132 | ||||
-rw-r--r-- | backends/cloud/savessyncrequest.h | 6 |
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(); |