diff options
author | Alexander Tkachev | 2016-06-08 14:17:35 +0600 |
---|---|---|
committer | Alexander Tkachev | 2016-08-24 16:07:55 +0600 |
commit | e273e3d6e8dcca6f7e70d3e7c4e6dfc836832378 (patch) | |
tree | 887dee489c0ad85cfe7d79ef25f4c93885ca1c46 /backends | |
parent | f0d61084daf7292d157e451c7bfc5485757eac43 (diff) | |
download | scummvm-rg350-e273e3d6e8dcca6f7e70d3e7c4e6dfc836832378.tar.gz scummvm-rg350-e273e3d6e8dcca6f7e70d3e7c4e6dfc836832378.tar.bz2 scummvm-rg350-e273e3d6e8dcca6f7e70d3e7c4e6dfc836832378.zip |
CLOUD: Add GoogleDrive download-related requests
GoogleDriveDownloadRequest, which resolves file id and then downloads it
with GoogleDriveStorage::downloadById().
GoogleDriveStreamFileRequest, which resolves file id and then returns
file stream with GoogleDriveStorage::streamFileById().
This commit also adds GoogleDriveStorage::streamFileById() itself.
A minor GoogleDriveResolveIdRequest fix added.
With these one can download files from Google Drive.
Diffstat (limited to 'backends')
-rw-r--r-- | backends/cloud/googledrive/googledrivedownloadrequest.cpp | 91 | ||||
-rw-r--r-- | backends/cloud/googledrive/googledrivedownloadrequest.h | 59 | ||||
-rw-r--r-- | backends/cloud/googledrive/googledriveresolveidrequest.cpp | 12 | ||||
-rw-r--r-- | backends/cloud/googledrive/googledrivestorage.cpp | 53 | ||||
-rw-r--r-- | backends/cloud/googledrive/googledrivestorage.h | 2 | ||||
-rw-r--r-- | backends/cloud/googledrive/googledrivestreamfilerequest.cpp | 91 | ||||
-rw-r--r-- | backends/cloud/googledrive/googledrivestreamfilerequest.h | 59 | ||||
-rw-r--r-- | backends/module.mk | 2 |
8 files changed, 324 insertions, 45 deletions
diff --git a/backends/cloud/googledrive/googledrivedownloadrequest.cpp b/backends/cloud/googledrive/googledrivedownloadrequest.cpp new file mode 100644 index 0000000000..c885352fae --- /dev/null +++ b/backends/cloud/googledrive/googledrivedownloadrequest.cpp @@ -0,0 +1,91 @@ +/* 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/googledrive/googledrivedownloadrequest.h" +#include "backends/cloud/googledrive/googledrivestorage.h" + +namespace Cloud { +namespace GoogleDrive { + +GoogleDriveDownloadRequest::GoogleDriveDownloadRequest(GoogleDriveStorage *storage, Common::String remotePath, Common::String localPath, Storage::BoolCallback cb, Networking::ErrorCallback ecb): + Networking::Request(nullptr, ecb), _requestedFile(remotePath), _requestedLocalFile(localPath), _storage(storage), _boolCallback(cb), + _workingRequest(nullptr), _ignoreCallback(false) { + start(); +} + +GoogleDriveDownloadRequest::~GoogleDriveDownloadRequest() { + _ignoreCallback = true; + if (_workingRequest) _workingRequest->finish(); + delete _boolCallback; +} + +void GoogleDriveDownloadRequest::start() { + //cleanup + _ignoreCallback = true; + if (_workingRequest) _workingRequest->finish(); + _workingRequest = nullptr; + _ignoreCallback = false; + + //find file's id + Storage::UploadCallback innerCallback = new Common::Callback<GoogleDriveDownloadRequest, Storage::UploadResponse>(this, &GoogleDriveDownloadRequest::idResolvedCallback); + Networking::ErrorCallback innerErrorCallback = new Common::Callback<GoogleDriveDownloadRequest, Networking::ErrorResponse>(this, &GoogleDriveDownloadRequest::idResolveFailedCallback); + _workingRequest = _storage->resolveFileId(_requestedFile, innerCallback, innerErrorCallback); +} + +void GoogleDriveDownloadRequest::idResolvedCallback(Storage::UploadResponse response) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + + Storage::BoolCallback innerCallback = new Common::Callback<GoogleDriveDownloadRequest, Storage::BoolResponse>(this, &GoogleDriveDownloadRequest::downloadCallback); + Networking::ErrorCallback innerErrorCallback = new Common::Callback<GoogleDriveDownloadRequest, Networking::ErrorResponse>(this, &GoogleDriveDownloadRequest::downloadErrorCallback); + _workingRequest = _storage->downloadById(response.value.id(), _requestedLocalFile, innerCallback, innerErrorCallback); +} + +void GoogleDriveDownloadRequest::idResolveFailedCallback(Networking::ErrorResponse error) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishError(error); +} + +void GoogleDriveDownloadRequest::downloadCallback(Storage::BoolResponse response) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishSuccess(response.value); +} + +void GoogleDriveDownloadRequest::downloadErrorCallback(Networking::ErrorResponse error) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishError(error); +} + +void GoogleDriveDownloadRequest::handle() {} + +void GoogleDriveDownloadRequest::restart() { start(); } + +void GoogleDriveDownloadRequest::finishSuccess(bool success) { + Request::finishSuccess(); + if (_boolCallback) (*_boolCallback)(Storage::BoolResponse(this, success)); +} + +} // End of namespace GoogleDrive +} // End of namespace Cloud diff --git a/backends/cloud/googledrive/googledrivedownloadrequest.h b/backends/cloud/googledrive/googledrivedownloadrequest.h new file mode 100644 index 0000000000..89bd313467 --- /dev/null +++ b/backends/cloud/googledrive/googledrivedownloadrequest.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_GOOGLEDRIVE_GOOGLEDRIVEDOWNLOADREQUEST_H +#define BACKENDS_CLOUD_GOOGLEDRIVE_GOOGLEDRIVEDOWNLOADREQUEST_H + +#include "backends/cloud/storage.h" +#include "backends/networking/curl/request.h" +#include "common/callback.h" + +namespace Cloud { +namespace GoogleDrive { + +class GoogleDriveStorage; + +class GoogleDriveDownloadRequest: public Networking::Request { + Common::String _requestedFile, _requestedLocalFile; + GoogleDriveStorage *_storage; + Storage::BoolCallback _boolCallback; + Request *_workingRequest; + bool _ignoreCallback; + + void start(); + void idResolvedCallback(Storage::UploadResponse response); + void idResolveFailedCallback(Networking::ErrorResponse error); + void downloadCallback(Storage::BoolResponse response); + void downloadErrorCallback(Networking::ErrorResponse error); + void finishSuccess(bool success); +public: + GoogleDriveDownloadRequest(GoogleDriveStorage *storage, Common::String remotePath, Common::String localPath, Storage::BoolCallback cb, Networking::ErrorCallback ecb); + virtual ~GoogleDriveDownloadRequest(); + + virtual void handle(); + virtual void restart(); +}; + +} // End of namespace GoogleDrive +} // End of namespace Cloud + +#endif diff --git a/backends/cloud/googledrive/googledriveresolveidrequest.cpp b/backends/cloud/googledrive/googledriveresolveidrequest.cpp index e3ab97ea6c..6d8da8383d 100644 --- a/backends/cloud/googledrive/googledriveresolveidrequest.cpp +++ b/backends/cloud/googledrive/googledriveresolveidrequest.cpp @@ -84,12 +84,17 @@ void GoogleDriveResolveIdRequest::listedDirectoryCallback(Storage::FileArrayResp } } + Common::String path = _currentDirectory; + if (path != "") path += "/"; + path += currentLevelName; + bool lastLevel = (path.equalsIgnoreCase(_requestedPath)); + ///debug("so, searching for '%s' in '%s'", currentLevelName.c_str(), _currentDirectory.c_str()); Common::Array<StorageFile> &files = response.value; bool found = false; for (uint32 i = 0; i < files.size(); ++i) { - if (files[i].isDirectory() && files[i].name().equalsIgnoreCase(currentLevelName)) { + if ((files[i].isDirectory() || lastLevel) && files[i].name().equalsIgnoreCase(currentLevelName)) { if (_currentDirectory != "") _currentDirectory += "/"; _currentDirectory += files[i].name(); _currentDirectoryId = files[i].id(); @@ -101,10 +106,7 @@ void GoogleDriveResolveIdRequest::listedDirectoryCallback(Storage::FileArrayResp } if (!found) { - Common::String path = _currentDirectory; - if (path != "") path += "/"; - path += currentLevelName; - if (path.equalsIgnoreCase(_requestedPath)) finishError(Networking::ErrorResponse(this, false, true, Common::String("no such file found in its parent directory\n")+_currentDirectoryId, 404)); + if (lastLevel) finishError(Networking::ErrorResponse(this, false, true, Common::String("no such file found in its parent directory\n")+_currentDirectoryId, 404)); else finishError(Networking::ErrorResponse(this, false, true, "subdirectory not found", 400)); } } diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp index c6e423e00d..d9db4f7dd8 100644 --- a/backends/cloud/googledrive/googledrivestorage.cpp +++ b/backends/cloud/googledrive/googledrivestorage.cpp @@ -35,6 +35,8 @@ #include "googledriveresolveidrequest.h" #include "googledrivecreatedirectoryrequest.h" #include "googledrivelistdirectoryrequest.h" +#include "googledrivestreamfilerequest.h" +#include "googledrivedownloadrequest.h" namespace Cloud { namespace GoogleDrive { @@ -209,29 +211,6 @@ void GoogleDriveStorage::printJson(Networking::JsonResponse response) { delete json; } -void GoogleDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response) { - if (!response.value) { - warning("fileInfoCallback: NULL"); - if (outerCallback) (*outerCallback)(Networking::NetworkReadStreamResponse(response.request, 0)); - return; - } - - Common::JSONObject result = response.value->asObject(); - if (result.contains("@content.downloadUrl")) { - const char *url = result.getVal("@content.downloadUrl")->asString().c_str(); - if (outerCallback) - (*outerCallback)(Networking::NetworkReadStreamResponse( - response.request, - new Networking::NetworkReadStream(url, 0, "") - )); - } else { - warning("downloadUrl not found in passed JSON"); - debug("%s", response.value->stringify().c_str()); - if (outerCallback) (*outerCallback)(Networking::NetworkReadStreamResponse(response.request, 0)); - } - delete response.value; -} - Networking::Request *GoogleDriveStorage::resolveFileId(Common::String path, UploadCallback callback, Networking::ErrorCallback errorCallback) { if (!errorCallback) errorCallback = getErrorPrintingCallback(); if (!callback) callback = new Common::Callback<GoogleDriveStorage, UploadResponse>(this, &GoogleDriveStorage::printFile); @@ -255,27 +234,25 @@ Networking::Request *GoogleDriveStorage::upload(Common::String path, Common::See return nullptr; //TODO } -Networking::Request *GoogleDriveStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) { - /* - Common::String url = "https://api.onedrive.com/v1.0/drive/special/approot:/" + path; - Networking::JsonCallback innerCallback = new Common::CallbackBridge<GoogleDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &GoogleDriveStorage::fileInfoCallback, outerCallback); - Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str()); - request->addHeader("Authorization: Bearer " + _token); - return addRequest(request); - */ - //TODO: resolve id - //TODO: then call streamFileById() - return nullptr; //TODO +Networking::Request *GoogleDriveStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) { + return addRequest(new GoogleDriveStreamFileRequest(this, path, outerCallback, errorCallback)); } Networking::Request *GoogleDriveStorage::streamFileById(Common::String id, Networking::NetworkReadStreamCallback callback, Networking::ErrorCallback errorCallback) { - return nullptr; //TODO + if (callback) { + Common::String url = "https://www.googleapis.com/drive/v3/files/" + id + "?alt=media"; + Common::String header = "Authorization: Bearer " + _token; + curl_slist *headersList = curl_slist_append(nullptr, header.c_str()); + Networking::NetworkReadStream *stream = new Networking::NetworkReadStream(url.c_str(), headersList, ""); + (*callback)(Networking::NetworkReadStreamResponse(nullptr, stream)); + } + delete callback; + delete errorCallback; + return nullptr; } Networking::Request *GoogleDriveStorage::download(Common::String remotePath, Common::String localPath, BoolCallback callback, Networking::ErrorCallback errorCallback) { - //TODO: resolve id - //TODO: then call downloadById() - return nullptr; //TODO + return addRequest(new GoogleDriveDownloadRequest(this, remotePath, localPath, callback, errorCallback)); } void GoogleDriveStorage::fileDownloaded(BoolResponse response) { diff --git a/backends/cloud/googledrive/googledrivestorage.h b/backends/cloud/googledrive/googledrivestorage.h index a456030369..2af1edea3c 100644 --- a/backends/cloud/googledrive/googledrivestorage.h +++ b/backends/cloud/googledrive/googledrivestorage.h @@ -61,8 +61,6 @@ class GoogleDriveStorage: public Cloud::Storage { void printBool(BoolResponse response); void printFile(UploadResponse response); void printInfo(StorageInfoResponse response); - - void fileInfoCallback(Networking::NetworkReadStreamCallback outerCallback, Networking::JsonResponse response); public: virtual ~GoogleDriveStorage(); diff --git a/backends/cloud/googledrive/googledrivestreamfilerequest.cpp b/backends/cloud/googledrive/googledrivestreamfilerequest.cpp new file mode 100644 index 0000000000..424e52c6cb --- /dev/null +++ b/backends/cloud/googledrive/googledrivestreamfilerequest.cpp @@ -0,0 +1,91 @@ +/* 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/googledrive/googledrivestreamfilerequest.h" +#include "backends/cloud/googledrive/googledrivestorage.h" + +namespace Cloud { +namespace GoogleDrive { + +GoogleDriveStreamFileRequest::GoogleDriveStreamFileRequest(GoogleDriveStorage *storage, Common::String path, Networking::NetworkReadStreamCallback cb, Networking::ErrorCallback ecb): + Networking::Request(nullptr, ecb), _requestedFile(path), _storage(storage), _streamCallback(cb), + _workingRequest(nullptr), _ignoreCallback(false) { + start(); +} + +GoogleDriveStreamFileRequest::~GoogleDriveStreamFileRequest() { + _ignoreCallback = true; + if (_workingRequest) _workingRequest->finish(); + delete _streamCallback; +} + +void GoogleDriveStreamFileRequest::start() { + //cleanup + _ignoreCallback = true; + if (_workingRequest) _workingRequest->finish(); + _workingRequest = nullptr; + _ignoreCallback = false; + + //find file's id + Storage::UploadCallback innerCallback = new Common::Callback<GoogleDriveStreamFileRequest, Storage::UploadResponse>(this, &GoogleDriveStreamFileRequest::idResolvedCallback); + Networking::ErrorCallback innerErrorCallback = new Common::Callback<GoogleDriveStreamFileRequest, Networking::ErrorResponse>(this, &GoogleDriveStreamFileRequest::idResolveFailedCallback); + _workingRequest = _storage->resolveFileId(_requestedFile, innerCallback, innerErrorCallback); +} + +void GoogleDriveStreamFileRequest::idResolvedCallback(Storage::UploadResponse response) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + + Networking::NetworkReadStreamCallback innerCallback = new Common::Callback<GoogleDriveStreamFileRequest, Networking::NetworkReadStreamResponse>(this, &GoogleDriveStreamFileRequest::streamFileCallback); + Networking::ErrorCallback innerErrorCallback = new Common::Callback<GoogleDriveStreamFileRequest, Networking::ErrorResponse>(this, &GoogleDriveStreamFileRequest::streamFileErrorCallback); + _workingRequest = _storage->streamFileById(response.value.id(), innerCallback, innerErrorCallback); +} + +void GoogleDriveStreamFileRequest::idResolveFailedCallback(Networking::ErrorResponse error) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishError(error); +} + +void GoogleDriveStreamFileRequest::streamFileCallback(Networking::NetworkReadStreamResponse response) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishStream(response.value); +} + +void GoogleDriveStreamFileRequest::streamFileErrorCallback(Networking::ErrorResponse error) { + _workingRequest = nullptr; + if (_ignoreCallback) return; + finishError(error); +} + +void GoogleDriveStreamFileRequest::handle() {} + +void GoogleDriveStreamFileRequest::restart() { start(); } + +void GoogleDriveStreamFileRequest::finishStream(Networking::NetworkReadStream *stream) { + Request::finishSuccess(); + if (_streamCallback) (*_streamCallback)(Networking::NetworkReadStreamResponse(this, stream)); +} + +} // End of namespace GoogleDrive +} // End of namespace Cloud diff --git a/backends/cloud/googledrive/googledrivestreamfilerequest.h b/backends/cloud/googledrive/googledrivestreamfilerequest.h new file mode 100644 index 0000000000..aa5596154e --- /dev/null +++ b/backends/cloud/googledrive/googledrivestreamfilerequest.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_GOOGLEDRIVE_GOOGLEDRIVESTREAMFILEREQUEST_H +#define BACKENDS_CLOUD_GOOGLEDRIVE_GOOGLEDRIVESTREAMFILEREQUEST_H + +#include "backends/cloud/storage.h" +#include "backends/networking/curl/request.h" +#include "common/callback.h" + +namespace Cloud { +namespace GoogleDrive { + +class GoogleDriveStorage; + +class GoogleDriveStreamFileRequest: public Networking::Request { + Common::String _requestedFile; + GoogleDriveStorage *_storage; + Networking::NetworkReadStreamCallback _streamCallback; + Request *_workingRequest; + bool _ignoreCallback; + + void start(); + void idResolvedCallback(Storage::UploadResponse response); + void idResolveFailedCallback(Networking::ErrorResponse error); + void streamFileCallback(Networking::NetworkReadStreamResponse response); + void streamFileErrorCallback(Networking::ErrorResponse error); + void finishStream(Networking::NetworkReadStream *stream); +public: + GoogleDriveStreamFileRequest(GoogleDriveStorage *storage, Common::String path, Networking::NetworkReadStreamCallback cb, Networking::ErrorCallback ecb); + virtual ~GoogleDriveStreamFileRequest(); + + virtual void handle(); + virtual void restart(); +}; + +} // End of namespace GoogleDrive +} // End of namespace Cloud + +#endif diff --git a/backends/module.mk b/backends/module.mk index c4a8ae40b5..817c82970c 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -33,10 +33,12 @@ MODULE_OBJS += \ cloud/dropbox/dropboxlistdirectoryrequest.o \ cloud/dropbox/dropboxuploadrequest.o \ cloud/googledrive/googledrivecreatedirectoryrequest.o \ + cloud/googledrive/googledrivedownloadrequest.o \ cloud/googledrive/googledrivelistdirectorybyidrequest.o \ cloud/googledrive/googledrivelistdirectoryrequest.o \ cloud/googledrive/googledriveresolveidrequest.o \ cloud/googledrive/googledrivestorage.o \ + cloud/googledrive/googledrivestreamfilerequest.o \ cloud/googledrive/googledrivetokenrefresher.o \ cloud/onedrive/onedrivestorage.o \ cloud/onedrive/onedrivecreatedirectoryrequest.o \ |