diff options
author | Alexander Tkachev | 2016-05-28 01:08:51 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | 827c7e43da118f12ae614530340a566a23c42746 (patch) | |
tree | d375bdec6ad763695722b8bd8c0c63647c7296f4 /backends | |
parent | 14d60e62f8452dd433fcf275cd87fd9b8c3bd6fd (diff) | |
download | scummvm-rg350-827c7e43da118f12ae614530340a566a23c42746.tar.gz scummvm-rg350-827c7e43da118f12ae614530340a566a23c42746.tar.bz2 scummvm-rg350-827c7e43da118f12ae614530340a566a23c42746.zip |
CLOUD: Add OneDriveListDirectoryRequest
Works as charm.
Diffstat (limited to 'backends')
-rw-r--r-- | backends/cloud/onedrive/onedrivelistdirectoryrequest.cpp | 138 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivelistdirectoryrequest.h | 64 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivestorage.cpp | 15 | ||||
-rw-r--r-- | backends/cloud/onedrive/onedrivestorage.h | 3 | ||||
-rw-r--r-- | backends/module.mk | 3 |
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 |