aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp138
-rw-r--r--backends/cloud/onedrive/onedrivelistdirectoryrequest.h64
-rw-r--r--backends/cloud/onedrive/onedrivestorage.cpp15
-rw-r--r--backends/cloud/onedrive/onedrivestorage.h3
-rw-r--r--backends/module.mk3
5 files changed, 220 insertions, 3 deletions
diff --git a/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp b/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp
new file mode 100644
index 0000000000..2c47852fd1
--- /dev/null
+++ b/backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp
@@ -0,0 +1,138 @@
+/* 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/onedrive/onedrivelistdirectoryrequest.h"
+#include "backends/cloud/onedrive/onedrivestorage.h"
+#include "backends/cloud/onedrive/onedrivetokenrefresher.h"
+#include "backends/cloud/iso8601.h"
+#include "backends/networking/curl/connectionmanager.h"
+#include "common/json.h"
+
+namespace Cloud {
+namespace OneDrive {
+
+OneDriveListDirectoryRequest::OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::FileArrayCallback cb, bool recursive):
+ Networking::Request(0),
+ _requestedPath(path), _requestedRecursive(recursive), _storage(storage), _filesCallback(cb),
+ _workingRequest(nullptr), _ignoreCallback(false) {
+ start();
+}
+
+void OneDriveListDirectoryRequest::start() {
+ //cleanup
+ _ignoreCallback = true;
+ if (_workingRequest) _workingRequest->finish();
+ _workingRequest = nullptr;
+ _files.clear();
+ _directoriesQueue.clear();
+ _currentDirectory = "";
+ _ignoreCallback = false;
+
+ _directoriesQueue.push_back(_requestedPath);
+ listNextDirectory();
+}
+
+void OneDriveListDirectoryRequest::listNextDirectory() {
+ if (_directoriesQueue.empty()) {
+ finishFiles(_files);
+ return;
+ }
+
+ _currentDirectory = _directoriesQueue.back();
+ _directoriesQueue.pop_back();
+
+ if (_currentDirectory != "" && _currentDirectory.lastChar() != '/' && _currentDirectory.lastChar() != '\\')
+ _currentDirectory += '/';
+
+ Common::String url = "https://api.onedrive.com/v1.0/drive/special/approot:/" + _currentDirectory;
+ url.deleteLastChar();
+ url += ":/children";
+ makeRequest(url);
+}
+
+void OneDriveListDirectoryRequest::makeRequest(Common::String url) {
+ Networking::JsonCallback callback = new Common::Callback<OneDriveListDirectoryRequest, Networking::JsonResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryCallback);
+ Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, url.c_str());
+ request->addHeader("Authorization: Bearer " + _storage->accessToken());
+ _workingRequest = ConnMan.addRequest(request);
+}
+
+
+void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonResponse pair) {
+ Common::JSONValue *json = pair.value;
+
+ if (_ignoreCallback) {
+ delete json;
+ return;
+ }
+
+ if (!json) {
+ finish();
+ return;
+ }
+
+ Common::JSONObject response = json->asObject();
+
+ //TODO: check that all keys exist to avoid segfaults
+
+ Common::JSONArray items = response.getVal("value")->asArray();
+ for (uint32 i = 0; i < items.size(); ++i) {
+ Common::JSONObject item = items[i]->asObject();
+
+ Common::String path = _currentDirectory + item.getVal("name")->asString();
+ bool isDirectory = item.contains("folder");
+ uint32 size = 0, timestamp = 0;
+ //if (!isDirectory) {
+ size = item.getVal("size")->asNumber();
+ timestamp = ISO8601::convertToTimestamp(item.getVal("lastModifiedDateTime")->asString());
+ //}
+
+ StorageFile file(path, size, timestamp, isDirectory);
+ _files.push_back(file);
+ if (_requestedRecursive && file.isDirectory()) {
+ _directoriesQueue.push_back(file.path());
+ }
+ }
+
+ bool hasMore = response.contains("@odata.nextLink");
+ if (hasMore) {
+ makeRequest(response.getVal("@odata.nextLink")->asString());
+ } else {
+ listNextDirectory();
+ }
+
+ delete json;
+}
+
+void OneDriveListDirectoryRequest::finish() {
+ //TODO: indicate it's interrupted
+ Common::Array<StorageFile> files;
+ finishFiles(files);
+}
+
+void OneDriveListDirectoryRequest::finishFiles(Common::Array<StorageFile> &files) {
+ Request::finish();
+ if (_filesCallback) (*_filesCallback)(Storage::FileArrayResponse(this, files));
+}
+
+} //end of namespace OneDrive
+} //end of namespace Cloud
diff --git a/backends/cloud/onedrive/onedrivelistdirectoryrequest.h b/backends/cloud/onedrive/onedrivelistdirectoryrequest.h
new file mode 100644
index 0000000000..61eebb2669
--- /dev/null
+++ b/backends/cloud/onedrive/onedrivelistdirectoryrequest.h
@@ -0,0 +1,64 @@
+/* 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_ONEDRIVE_ONEDRIVELISTDIRECTORYREQUEST_H
+#define BACKENDS_CLOUD_ONEDRIVE_ONEDRIVELISTDIRECTORYREQUEST_H
+
+#include "backends/cloud/storage.h"
+#include "backends/networking/curl/curljsonrequest.h"
+#include "backends/networking/curl/request.h"
+#include "common/callback.h"
+
+namespace Cloud {
+namespace OneDrive {
+
+class OneDriveStorage;
+
+class OneDriveListDirectoryRequest: public Networking::Request {
+ Common::String _requestedPath;
+ bool _requestedRecursive;
+ OneDriveStorage *_storage;
+ Storage::FileArrayCallback _filesCallback;
+ Common::Array<StorageFile> _files;
+ Common::Array<Common::String> _directoriesQueue;
+ Common::String _currentDirectory;
+ Request *_workingRequest;
+ bool _ignoreCallback;
+
+ void start();
+ void listNextDirectory();
+ void listedDirectoryCallback(Networking::JsonResponse pair);
+ void makeRequest(Common::String url);
+ void finishFiles(Common::Array<StorageFile> &files);
+public:
+ OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::FileArrayCallback cb, bool recursive = false);
+ virtual ~OneDriveListDirectoryRequest() { delete _filesCallback; }
+
+ virtual void handle() {}
+ virtual void restart() { start(); }
+ virtual void finish();
+};
+
+} //end of namespace OneDrive
+} //end of namespace Cloud
+
+#endif
diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp
index 6f3a283fe6..d14379393b 100644
--- a/backends/cloud/onedrive/onedrivestorage.cpp
+++ b/backends/cloud/onedrive/onedrivestorage.cpp
@@ -23,6 +23,7 @@
#include "backends/cloud/onedrive/onedrivestorage.h"
#include "backends/cloud/onedrive/onedrivetokenrefresher.h"
+#include "backends/cloud/onedrive/onedrivelistdirectoryrequest.h"
#include "backends/cloud/downloadrequest.h"
#include "backends/networking/curl/connectionmanager.h"
#include "backends/networking/curl/curljsonrequest.h"
@@ -161,6 +162,11 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
delete pair.value;
}
+Networking::Request *OneDriveStorage::listDirectory(Common::String path, FileArrayCallback callback, bool recursive) {
+ return ConnMan.addRequest(new OneDriveListDirectoryRequest(this, path, callback, recursive));
+}
+
+
Networking::Request *OneDriveStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback outerCallback) {
Common::String url = "https://api.onedrive.com/v1.0/drive/special/approot:/" + path;
Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &OneDriveStorage::fileInfoCallback, outerCallback);
@@ -186,6 +192,13 @@ void OneDriveStorage::fileDownloaded(BoolResponse pair) {
else debug("download failed!");
}
+void OneDriveStorage::printFiles(FileArrayResponse pair) {
+ debug("files:");
+ Common::Array<StorageFile> &files = pair.value;
+ for (uint32 i = 0; i < files.size(); ++i)
+ debug("\t%s", files[i].path().c_str());
+}
+
Networking::Request *OneDriveStorage::syncSaves(BoolCallback callback) {
//this is not the real syncSaves() implementation
/*
@@ -194,7 +207,7 @@ Networking::Request *OneDriveStorage::syncSaves(BoolCallback callback) {
request->addHeader("Authorization: bearer " + _token);
return ConnMan.addRequest(request);
*/
- return download("pic.jpg", "local/onedrive/2/doom.jpg", new Common::Callback<OneDriveStorage, BoolResponse>(this, &OneDriveStorage::fileDownloaded));
+ return listDirectory("subfolder", new Common::Callback<OneDriveStorage, FileArrayResponse>(this, &OneDriveStorage::printFiles), true);
}
OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) {
diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h
index 290abd7926..c9a32a802f 100644
--- a/backends/cloud/onedrive/onedrivestorage.h
+++ b/backends/cloud/onedrive/onedrivestorage.h
@@ -51,6 +51,7 @@ class OneDriveStorage: public Cloud::Storage {
void printJson(Networking::JsonResponse pair);
void fileDownloaded(BoolResponse pair);
+ void printFiles(FileArrayResponse pair);
void fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse pair);
public:
@@ -73,7 +74,7 @@ public:
/** Public Cloud API comes down there. */
/** Returns Common::Array<StorageFile>. */
- virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false) { return nullptr; } //TODO
+ 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::ReadStream *contents, BoolCallback callback) { return nullptr; } //TODO
diff --git a/backends/module.mk b/backends/module.mk
index 54e3817c56..f5b1aa4ec8 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -29,7 +29,8 @@ MODULE_OBJS += \
cloud/dropbox/dropboxstorage.o \
cloud/dropbox/dropboxlistdirectoryrequest.o \
cloud/onedrive/onedrivestorage.o \
- cloud/onedrive/onedrivetokenrefresher.o
+ cloud/onedrive/onedrivetokenrefresher.o \
+ cloud/onedrive/onedrivelistdirectoryrequest.o
endif
ifdef USE_LIBCURL