diff options
Diffstat (limited to 'backends')
-rw-r--r-- | backends/cloud/dropbox/dropboxstorage.cpp | 15 | ||||
-rw-r--r-- | backends/cloud/dropbox/dropboxstorage.h | 5 | ||||
-rw-r--r-- | backends/cloud/folderdownloadrequest.cpp | 111 | ||||
-rw-r--r-- | backends/cloud/folderdownloadrequest.h | 59 | ||||
-rw-r--r-- | backends/cloud/storagefile.cpp | 8 | ||||
-rw-r--r-- | backends/cloud/storagefile.h | 1 | ||||
-rw-r--r-- | backends/module.mk | 1 |
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 \ |