ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

googledrivelistdirectorybyidrequest.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "backends/cloud/googledrive/googledrivelistdirectorybyidrequest.h"
00024 #include "backends/cloud/googledrive/googledrivestorage.h"
00025 #include "backends/cloud/iso8601.h"
00026 #include "backends/cloud/storage.h"
00027 #include "backends/networking/curl/connectionmanager.h"
00028 #include "backends/networking/curl/curljsonrequest.h"
00029 #include "backends/networking/curl/networkreadstream.h"
00030 #include "common/json.h"
00031 #include "googledrivetokenrefresher.h"
00032 
00033 namespace Cloud {
00034 namespace GoogleDrive {
00035 
00036 #define GOOGLEDRIVE_API_FILES "https://www.googleapis.com/drive/v3/files?spaces=drive&fields=files%28id,mimeType,modifiedTime,name,size%29,nextPageToken&orderBy=folder,name"
00037 //files(id,mimeType,modifiedTime,name,size),nextPageToken
00038 
00039 GoogleDriveListDirectoryByIdRequest::GoogleDriveListDirectoryByIdRequest(GoogleDriveStorage *storage, Common::String id, Storage::ListDirectoryCallback cb, Networking::ErrorCallback ecb):
00040     Networking::Request(nullptr, ecb), _requestedId(id), _storage(storage), _listDirectoryCallback(cb),
00041     _workingRequest(nullptr), _ignoreCallback(false) {
00042     start();
00043 }
00044 
00045 GoogleDriveListDirectoryByIdRequest::~GoogleDriveListDirectoryByIdRequest() {
00046     _ignoreCallback = true;
00047     if (_workingRequest)
00048         _workingRequest->finish();
00049     delete _listDirectoryCallback;
00050 }
00051 
00052 void GoogleDriveListDirectoryByIdRequest::start() {
00053     _ignoreCallback = true;
00054     if (_workingRequest)
00055         _workingRequest->finish();
00056     _files.clear();
00057     _ignoreCallback = false;
00058 
00059     makeRequest("");
00060 }
00061 
00062 void GoogleDriveListDirectoryByIdRequest::makeRequest(Common::String pageToken) {
00063     Common::String url = GOOGLEDRIVE_API_FILES;
00064     if (pageToken != "")
00065         url += "&pageToken=" + pageToken;
00066     url += "&q=%27" + _requestedId + "%27+in+parents";
00067 
00068     Networking::JsonCallback callback = new Common::Callback<GoogleDriveListDirectoryByIdRequest, Networking::JsonResponse>(this, &GoogleDriveListDirectoryByIdRequest::responseCallback);
00069     Networking::ErrorCallback failureCallback = new Common::Callback<GoogleDriveListDirectoryByIdRequest, Networking::ErrorResponse>(this, &GoogleDriveListDirectoryByIdRequest::errorCallback);
00070     Networking::CurlJsonRequest *request = new GoogleDriveTokenRefresher(_storage, callback, failureCallback, url.c_str());
00071     request->addHeader("Authorization: Bearer " + _storage->accessToken());
00072     _workingRequest = ConnMan.addRequest(request);
00073 }
00074 
00075 void GoogleDriveListDirectoryByIdRequest::responseCallback(Networking::JsonResponse response) {
00076     _workingRequest = nullptr;
00077     if (_ignoreCallback) {
00078         delete response.value;
00079         return;
00080     }
00081     if (response.request)
00082         _date = response.request->date();
00083 
00084     Networking::ErrorResponse error(this);
00085     Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)response.request;
00086     if (rq && rq->getNetworkReadStream())
00087         error.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode();
00088 
00089     Common::JSONValue *json = response.value;
00090     if (json) {
00091         Common::JSONObject responseObject = json->asObject();
00092 
00094 
00095         if (responseObject.contains("error") || responseObject.contains("error_summary")) {
00096             warning("GoogleDrive returned error: %s", responseObject.getVal("error_summary")->asString().c_str());
00097             error.failed = true;
00098             error.response = json->stringify();
00099             finishError(error);
00100             delete json;
00101             return;
00102         }
00103 
00104         //TODO: check that ALL keys exist AND HAVE RIGHT TYPE to avoid segfaults
00105 
00106         if (responseObject.contains("files") && responseObject.getVal("files")->isArray()) {
00107             Common::JSONArray items = responseObject.getVal("files")->asArray();
00108             for (uint32 i = 0; i < items.size(); ++i) {
00109                 Common::JSONObject item = items[i]->asObject();
00110                 Common::String id = item.getVal("id")->asString();
00111                 Common::String name = item.getVal("name")->asString();
00112                 bool isDirectory = (item.getVal("mimeType")->asString() == "application/vnd.google-apps.folder");
00113                 uint32 size = 0, timestamp = 0;
00114                 if (item.contains("size") && item.getVal("size")->isString())
00115                     size = item.getVal("size")->asString().asUint64();
00116                 if (item.contains("modifiedTime") && item.getVal("modifiedTime")->isString())
00117                     timestamp = ISO8601::convertToTimestamp(item.getVal("modifiedTime")->asString());
00118 
00119                 //as we list directory by id, we can't determine full path for the file, so we leave it empty
00120                 _files.push_back(StorageFile(id, "", name, size, timestamp, isDirectory));
00121             }
00122         }
00123 
00124         bool hasMore = (responseObject.contains("nextPageToken"));
00125 
00126         if (hasMore) {
00127             Common::String token = responseObject.getVal("nextPageToken")->asString();
00128             makeRequest(token);
00129         } else {
00130             finishListing(_files);
00131         }
00132     } else {
00133         warning("null, not json");
00134         error.failed = true;
00135         finishError(error);
00136     }
00137 
00138     delete json;
00139 }
00140 
00141 void GoogleDriveListDirectoryByIdRequest::errorCallback(Networking::ErrorResponse error) {
00142     _workingRequest = nullptr;
00143     if (_ignoreCallback)
00144         return;
00145     if (error.request)
00146         _date = error.request->date();
00147     finishError(error);
00148 }
00149 
00150 void GoogleDriveListDirectoryByIdRequest::handle() {}
00151 
00152 void GoogleDriveListDirectoryByIdRequest::restart() { start(); }
00153 
00154 Common::String GoogleDriveListDirectoryByIdRequest::date() const { return _date; }
00155 
00156 void GoogleDriveListDirectoryByIdRequest::finishListing(Common::Array<StorageFile> &files) {
00157     Request::finishSuccess();
00158     if (_listDirectoryCallback)
00159         (*_listDirectoryCallback)(Storage::ListDirectoryResponse(this, files));
00160 }
00161 
00162 } // End of namespace GoogleDrive
00163 } // End of namespace Cloud


Generated on Sat Feb 23 2019 05:01:05 for ResidualVM by doxygen 1.7.1
curved edge   curved edge