aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp15
-rw-r--r--backends/cloud/dropbox/dropboxstorage.h5
-rw-r--r--backends/cloud/folderdownloadrequest.cpp111
-rw-r--r--backends/cloud/folderdownloadrequest.h59
-rw-r--r--backends/cloud/storagefile.cpp8
-rw-r--r--backends/cloud/storagefile.h1
-rw-r--r--backends/module.mk1
7 files changed, 197 insertions, 3 deletions
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index a1a97e00dd..379d7bb611 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -24,6 +24,7 @@
#include "backends/cloud/dropbox/dropboxstorage.h"
#include "backends/cloud/dropbox/dropboxlistdirectoryrequest.h"
#include "backends/cloud/downloadrequest.h"
+#include "backends/cloud/folderdownloadrequest.h"
#include "backends/networking/curl/connectionmanager.h"
#include "backends/networking/curl/curljsonrequest.h"
#include "common/config-manager.h"
@@ -79,8 +80,9 @@ void DropboxStorage::saveConfig(Common::String keyPrefix) {
ConfMan.set(keyPrefix + "user_id", _uid, "cloud");
}
-void DropboxStorage::printFiles(Common::Array<StorageFile> files) {
+void DropboxStorage::printFiles(FileArrayResponse pair) {
debug("files:");
+ Common::Array<StorageFile> &files = pair.value;
for (uint32 i = 0; i < files.size(); ++i)
debug("\t%s", files[i].name().c_str());
}
@@ -116,11 +118,20 @@ Networking::Request *DropboxStorage::download(Common::String remotePath, Common:
return ConnMan.addRequest(new DownloadRequest(this, callback, remotePath, f));
}
+Networking::Request *DropboxStorage::downloadFolder(Common::String remotePath, Common::String localPath, FileArrayCallback callback, bool recursive) {
+ return ConnMan.addRequest(new FolderDownloadRequest(this, callback, remotePath, localPath, recursive));
+}
+
Networking::Request *DropboxStorage::syncSaves(BoolCallback callback) {
//this is not the real syncSaves() implementation
//"" is root in Dropbox, not "/"
//this must create all these directories:
- return download("/remote/test.jpg", "local/a/b/c/d/test.jpg", 0);
+ //return download("/remote/test.jpg", "local/a/b/c/d/test.jpg", 0);
+ return downloadFolder(
+ "/not_flat", "local/not_flat_1_level/",
+ new Common::Callback<DropboxStorage, FileArrayResponse>(this, &DropboxStorage::printFiles),
+ false
+ );
}
Networking::Request *DropboxStorage::info(StorageInfoCallback outerCallback) {
diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h
index f95d0c9812..19f2f9cdd4 100644
--- a/backends/cloud/dropbox/dropboxstorage.h
+++ b/backends/cloud/dropbox/dropboxstorage.h
@@ -43,7 +43,7 @@ class DropboxStorage: public Cloud::Storage {
/** Constructs StorageInfo based on JSON response from cloud. */
void infoInnerCallback(StorageInfoCallback outerCallback, Networking::JsonResponse json);
- void printFiles(Common::Array<StorageFile> files);
+ void printFiles(FileArrayResponse pair);
public:
virtual ~DropboxStorage();
@@ -76,6 +76,9 @@ public:
/** Calls the callback when finished. */
virtual Networking::Request *download(Common::String remotePath, Common::String localPath, BoolCallback callback);
+ /** Returns Common::Array<StorageFile> with list of files, which were not downloaded. */
+ Networking::Request *downloadFolder(Common::String remotePath, Common::String localPath, FileArrayCallback callback, bool recursive = false);
+
/** Calls the callback when finished. */
virtual Networking::Request *remove(Common::String path, BoolCallback callback) { return nullptr; } //TODO
diff --git a/backends/cloud/folderdownloadrequest.cpp b/backends/cloud/folderdownloadrequest.cpp
new file mode 100644
index 0000000000..f60c9f6d69
--- /dev/null
+++ b/backends/cloud/folderdownloadrequest.cpp
@@ -0,0 +1,111 @@
+/* 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/folderdownloadrequest.h"
+#include "common/debug.h"
+
+namespace Cloud {
+
+FolderDownloadRequest::FolderDownloadRequest(Storage *storage, Storage::FileArrayCallback callback, Common::String remoteDirectoryPath, Common::String localDirectoryPath, bool recursive):
+ Request(nullptr), _storage(storage), _fileArrayCallback(callback),
+ _remoteDirectoryPath(remoteDirectoryPath), _localDirectoryPath(localDirectoryPath), _recursive(recursive),
+ _workingRequest(nullptr), _ignoreCallback(false) {
+ start();
+}
+
+void FolderDownloadRequest::start() {
+ //cleanup
+ _ignoreCallback = true;
+ if (_workingRequest) _workingRequest->finish();
+ _currentFile = StorageFile();
+ _files.clear();
+ _failedFiles.clear();
+ _ignoreCallback = false;
+
+ //list directory first
+ _workingRequest = _storage->listDirectory(
+ _remoteDirectoryPath,
+ new Common::Callback<FolderDownloadRequest, Storage::FileArrayResponse>(this, &FolderDownloadRequest::directoryListedCallback),
+ _recursive
+ );
+}
+
+void FolderDownloadRequest::directoryListedCallback(Storage::FileArrayResponse pair) {
+ if (_ignoreCallback) return;
+ //TODO: somehow ListDirectory requests must indicate that file array is incomplete
+ _files = pair.value;
+ downloadNextFile();
+}
+
+void FolderDownloadRequest::fileDownloadedCallback(Storage::BoolResponse pair) {
+ if (_ignoreCallback) return;
+ if (!pair.value) _failedFiles.push_back(_currentFile);
+ downloadNextFile();
+}
+
+void FolderDownloadRequest::downloadNextFile() {
+ do {
+ if (_files.empty()) {
+ finishFiles(_failedFiles);
+ return;
+ }
+
+ _currentFile = _files.back();
+ _files.pop_back();
+ } while (_currentFile.isDirectory()); //TODO: may be create these directories (in case those are empty)
+
+ Common::String remotePath = _currentFile.path();
+ Common::String localPath = remotePath;
+ if (_remoteDirectoryPath == "" || remotePath.hasPrefix(_remoteDirectoryPath)) {
+ localPath.erase(0, _remoteDirectoryPath.size());
+ if (_remoteDirectoryPath != "" && (_remoteDirectoryPath.lastChar() != '/' && _remoteDirectoryPath.lastChar() != '\\'))
+ localPath.erase(0, 1);
+ } else {
+ warning("Can't process the following paths:");
+ warning("remote directory: %s", _remoteDirectoryPath.c_str());
+ warning("remote file under that directory: %s", remotePath.c_str());
+ }
+ if (_localDirectoryPath != "") {
+ if (_localDirectoryPath.lastChar() == '/' || _localDirectoryPath.lastChar() == '\\')
+ localPath = _localDirectoryPath + localPath;
+ else
+ localPath = _localDirectoryPath + "/" + localPath;
+ }
+ debug("%s -> %s", remotePath.c_str(), localPath.c_str());
+ _workingRequest = _storage->download(
+ remotePath, localPath,
+ new Common::Callback<FolderDownloadRequest, Storage::BoolResponse>(this, &FolderDownloadRequest::fileDownloadedCallback)
+ );
+}
+
+void FolderDownloadRequest::finish() {
+ //TODO: somehow indicate that request was interrupted
+ Common::Array<StorageFile> files;
+ finishFiles(files);
+}
+
+void FolderDownloadRequest::finishFiles(Common::Array<StorageFile> &files) {
+ Request::finish();
+ if (_fileArrayCallback) (*_fileArrayCallback)(Storage::FileArrayResponse(this, files));
+}
+
+} //end of namespace Cloud
diff --git a/backends/cloud/folderdownloadrequest.h b/backends/cloud/folderdownloadrequest.h
new file mode 100644
index 0000000000..038dc642ef
--- /dev/null
+++ b/backends/cloud/folderdownloadrequest.h
@@ -0,0 +1,59 @@
+/* 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_FOLDERDOWNLOADREQUEST_H
+#define BACKENDS_CLOUD_FOLDERDOWNLOADREQUEST_H
+
+#include "backends/networking/curl/request.h"
+#include "backends/networking/curl/networkreadstream.h"
+#include "backends/cloud/storage.h"
+#include "common/file.h"
+
+namespace Cloud {
+
+class FolderDownloadRequest: public Networking::Request {
+ Storage *_storage;
+ Storage::FileArrayCallback _fileArrayCallback;
+ Common::String _remoteDirectoryPath, _localDirectoryPath;
+ bool _recursive;
+ Common::Array<StorageFile> _files, _failedFiles;
+ StorageFile _currentFile;
+ Request *_workingRequest;
+ bool _ignoreCallback;
+
+ void start();
+ void directoryListedCallback(Storage::FileArrayResponse pair);
+ void fileDownloadedCallback(Storage::BoolResponse pair);
+ void downloadNextFile();
+ void finishFiles(Common::Array<StorageFile> &files);
+public:
+ FolderDownloadRequest(Storage *storage, Storage::FileArrayCallback callback, Common::String remoteDirectoryPath, Common::String localDirectoryPath, bool recursive);
+ virtual ~FolderDownloadRequest() {}
+
+ virtual void handle() {}
+ virtual void restart() { start(); }
+ virtual void finish();
+};
+
+} //end of namespace Cloud
+
+#endif
diff --git a/backends/cloud/storagefile.cpp b/backends/cloud/storagefile.cpp
index 02c9cae3cf..c0f8d3a9bc 100644
--- a/backends/cloud/storagefile.cpp
+++ b/backends/cloud/storagefile.cpp
@@ -24,6 +24,14 @@
namespace Cloud {
+StorageFile::StorageFile() {
+ _path = "";
+ _name = "";
+ _size = 0;
+ _timestamp = 0;
+ _isDirectory = false;
+}
+
StorageFile::StorageFile(Common::String pth, uint32 sz, uint32 ts, bool dir) {
_path = pth;
diff --git a/backends/cloud/storagefile.h b/backends/cloud/storagefile.h
index 8706ba18e9..ced99fae30 100644
--- a/backends/cloud/storagefile.h
+++ b/backends/cloud/storagefile.h
@@ -39,6 +39,7 @@ class StorageFile {
bool _isDirectory;
public:
+ StorageFile(); //invalid empty file
StorageFile(Common::String pth, uint32 sz, uint32 ts, bool dir);
Common::String path() const { return _path; }
diff --git a/backends/module.mk b/backends/module.mk
index 5ec34190e9..54e3817c56 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -25,6 +25,7 @@ MODULE_OBJS += \
cloud/manager.o \
cloud/storagefile.o \
cloud/downloadrequest.o \
+ cloud/folderdownloadrequest.o \
cloud/dropbox/dropboxstorage.o \
cloud/dropbox/dropboxlistdirectoryrequest.o \
cloud/onedrive/onedrivestorage.o \