mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
CLOUD: Fix OneDriveStorage API interaction
Something changed and old API endpoint "api.onedrive.com" now does not work. The other one, "graph.microsoft.com", does, but there were some other changes in JSON it returns. These changes are also in this commit.
This commit is contained in:
parent
e8669f693c
commit
edbea10c2e
@ -31,7 +31,7 @@
|
||||
namespace Cloud {
|
||||
namespace OneDrive {
|
||||
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT "https://api.onedrive.com/v1.0/drive/special/approot"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot"
|
||||
|
||||
OneDriveCreateDirectoryRequest::OneDriveCreateDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::BoolCallback cb, Networking::ErrorCallback ecb):
|
||||
Networking::Request(nullptr, ecb), _storage(storage), _path(path), _boolCallback(cb),
|
||||
|
@ -31,7 +31,8 @@
|
||||
namespace Cloud {
|
||||
namespace OneDrive {
|
||||
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/children"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/children"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN_ROOT_ITSELF "https://graph.microsoft.com/v1.0/drive/special/approot/children"
|
||||
|
||||
OneDriveListDirectoryRequest::OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::ListDirectoryCallback cb, Networking::ErrorCallback ecb, bool recursive):
|
||||
Networking::Request(nullptr, ecb),
|
||||
@ -77,6 +78,7 @@ void OneDriveListDirectoryRequest::listNextDirectory() {
|
||||
Common::String dir = _currentDirectory;
|
||||
dir.deleteLastChar();
|
||||
Common::String url = Common::String::format(ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN, ConnMan.urlEncode(dir).c_str());
|
||||
if (dir == "") url = Common::String(ONEDRIVE_API_SPECIAL_APPROOT_CHILDREN_ROOT_ITSELF);
|
||||
makeRequest(url);
|
||||
}
|
||||
|
||||
@ -84,7 +86,7 @@ void OneDriveListDirectoryRequest::makeRequest(Common::String url) {
|
||||
Networking::JsonCallback callback = new Common::Callback<OneDriveListDirectoryRequest, Networking::JsonResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryCallback);
|
||||
Networking::ErrorCallback failureCallback = new Common::Callback<OneDriveListDirectoryRequest, Networking::ErrorResponse>(this, &OneDriveListDirectoryRequest::listedDirectoryErrorCallback);
|
||||
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(_storage, callback, failureCallback, url.c_str());
|
||||
request->addHeader("Authorization: Bearer " + _storage->accessToken());
|
||||
request->addHeader("Authorization: bearer " + _storage->accessToken());
|
||||
_workingRequest = ConnMan.addRequest(request);
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@
|
||||
namespace Cloud {
|
||||
namespace OneDrive {
|
||||
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://api.onedrive.com/v1.0/drive/special/approot:/"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT "https://api.onedrive.com/v1.0/drive/special/approot"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_ID "https://graph.microsoft.com/v1.0/drive/special/approot:/"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT "https://graph.microsoft.com/v1.0/drive/special/approot"
|
||||
|
||||
OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken):
|
||||
BaseStorage(token, refreshToken) {}
|
||||
@ -136,7 +136,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
|
||||
}
|
||||
|
||||
Common::JSONObject result = response.value->asObject();
|
||||
if (!Networking::CurlJsonRequest::jsonContainsString(result, "@content.downloadUrl", "OneDriveStorage::fileInfoCallback")) {
|
||||
if (!Networking::CurlJsonRequest::jsonContainsString(result, "@microsoft.graph.downloadUrl", "OneDriveStorage::fileInfoCallback")) {
|
||||
warning("OneDriveStorage: downloadUrl not found in passed JSON");
|
||||
debug(9, "%s", response.value->stringify().c_str());
|
||||
if (outerCallback)
|
||||
@ -146,7 +146,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
|
||||
return;
|
||||
}
|
||||
|
||||
const char *url = result.getVal("@content.downloadUrl")->asString().c_str();
|
||||
const char *url = result.getVal("@microsoft.graph.downloadUrl")->asString().c_str();
|
||||
if (outerCallback)
|
||||
(*outerCallback)(Networking::NetworkReadStreamResponse(
|
||||
response.request,
|
||||
@ -158,28 +158,33 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
|
||||
}
|
||||
|
||||
Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
|
||||
debug(9, "OneDrive: `ls \"%s\"`", path.c_str());
|
||||
return addRequest(new OneDriveListDirectoryRequest(this, path, callback, errorCallback, recursive));
|
||||
}
|
||||
|
||||
Networking::Request *OneDriveStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback, Networking::ErrorCallback errorCallback) {
|
||||
debug(9, "OneDrive: `upload \"%s\"`", path.c_str());
|
||||
return addRequest(new OneDriveUploadRequest(this, path, contents, callback, errorCallback));
|
||||
}
|
||||
|
||||
Networking::Request *OneDriveStorage::streamFileById(Common::String path, Networking::NetworkReadStreamCallback outerCallback, Networking::ErrorCallback errorCallback) {
|
||||
debug(9, "OneDrive: `download \"%s\"`", path.c_str());
|
||||
Common::String url = ONEDRIVE_API_SPECIAL_APPROOT_ID + ConnMan.urlEncode(path);
|
||||
Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, Networking::NetworkReadStreamResponse, Networking::JsonResponse>(this, &OneDriveStorage::fileInfoCallback, outerCallback);
|
||||
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, url.c_str());
|
||||
request->addHeader("Authorization: Bearer " + _token);
|
||||
request->addHeader("Authorization: bearer " + _token);
|
||||
return addRequest(request);
|
||||
}
|
||||
|
||||
Networking::Request *OneDriveStorage::createDirectory(Common::String path, BoolCallback callback, Networking::ErrorCallback errorCallback) {
|
||||
debug(9, "OneDrive: `mkdir \"%s\"`", path.c_str());
|
||||
if (!errorCallback)
|
||||
errorCallback = getErrorPrintingCallback();
|
||||
return addRequest(new OneDriveCreateDirectoryRequest(this, path, callback, errorCallback));
|
||||
}
|
||||
|
||||
Networking::Request *OneDriveStorage::info(StorageInfoCallback callback, Networking::ErrorCallback errorCallback) {
|
||||
debug(9, "OneDrive: `info`");
|
||||
Networking::JsonCallback innerCallback = new Common::CallbackBridge<OneDriveStorage, StorageInfoResponse, Networking::JsonResponse>(this, &OneDriveStorage::infoInnerCallback, callback);
|
||||
Networking::CurlJsonRequest *request = new OneDriveTokenRefresher(this, innerCallback, errorCallback, ONEDRIVE_API_SPECIAL_APPROOT);
|
||||
request->addHeader("Authorization: bearer " + _token);
|
||||
|
@ -94,7 +94,7 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) {
|
||||
irrecoverable = false;
|
||||
}
|
||||
|
||||
if (code == "unauthenticated")
|
||||
if (code == "unauthenticated" || code == "InvalidAuthenticationToken")
|
||||
irrecoverable = false;
|
||||
|
||||
if (irrecoverable) {
|
||||
@ -114,6 +114,30 @@ void OneDriveTokenRefresher::finishJson(Common::JSONValue *json) {
|
||||
CurlJsonRequest::finishJson(json);
|
||||
}
|
||||
|
||||
void OneDriveTokenRefresher::finishError(Networking::ErrorResponse error) {
|
||||
bool irrecoverable = error.interrupted || error.failed;
|
||||
if (error.failed) {
|
||||
Common::JSONValue *value = Common::JSON::parse(error.response.c_str());
|
||||
|
||||
//somehow OneDrive returns JSON with '.' in unexpected places, try fixing it
|
||||
if (!value) {
|
||||
Common::String fixedResponse = error.response;
|
||||
for (uint32 i = 0; i < fixedResponse.size(); ++i) {
|
||||
if (fixedResponse[i] == '.')
|
||||
fixedResponse.replace(i, 1, " ");
|
||||
}
|
||||
value = Common::JSON::parse(fixedResponse.c_str());
|
||||
}
|
||||
|
||||
if (value) {
|
||||
finishJson(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Request::finishError(error); //call closest base class's method
|
||||
}
|
||||
|
||||
void OneDriveTokenRefresher::setHeaders(Common::Array<Common::String> &headers) {
|
||||
_headers = headers;
|
||||
curl_slist_free_all(_headersList);
|
||||
|
@ -38,6 +38,7 @@ class OneDriveTokenRefresher: public Networking::CurlJsonRequest {
|
||||
void tokenRefreshed(Storage::BoolResponse response);
|
||||
|
||||
virtual void finishJson(Common::JSONValue *json);
|
||||
virtual void finishError(Networking::ErrorResponse error);
|
||||
public:
|
||||
OneDriveTokenRefresher(OneDriveStorage *parent, Networking::JsonCallback callback, Networking::ErrorCallback ecb, const char *url);
|
||||
virtual ~OneDriveTokenRefresher();
|
||||
|
@ -33,8 +33,8 @@
|
||||
namespace Cloud {
|
||||
namespace OneDrive {
|
||||
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/upload.createSession"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_CONTENT "https://api.onedrive.com/v1.0/drive/special/approot:/%s:/content"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_UPLOAD "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/upload.createSession"
|
||||
#define ONEDRIVE_API_SPECIAL_APPROOT_CONTENT "https://graph.microsoft.com/v1.0/drive/special/approot:/%s:/content"
|
||||
|
||||
OneDriveUploadRequest::OneDriveUploadRequest(OneDriveStorage *storage, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback, Networking::ErrorCallback ecb):
|
||||
Networking::Request(nullptr, ecb), _storage(storage), _savePath(path), _contentsStream(contents), _uploadCallback(callback),
|
||||
|
@ -126,11 +126,11 @@ void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse re
|
||||
_filesToUpload.push_back(i->_key);
|
||||
}
|
||||
|
||||
debug(9, "\nSavesSyncRequest: download files:");
|
||||
debug(9, (_filesToDownload.size() > 0 ? "\nSavesSyncRequest: download files:" : "\nSavesSyncRequest: nothing to download"));
|
||||
for (uint32 i = 0; i < _filesToDownload.size(); ++i) {
|
||||
debug(9, "%s", _filesToDownload[i].name().c_str());
|
||||
}
|
||||
debug(9, "\nSavesSyncRequest: upload files:");
|
||||
debug(9, (_filesToUpload.size() > 0 ? "\nSavesSyncRequest: upload files:" : "\nSavesSyncRequest: nothing to upload"));
|
||||
for (uint32 i = 0; i < _filesToUpload.size(); ++i) {
|
||||
debug(9, "%s", _filesToUpload[i].c_str());
|
||||
}
|
||||
@ -145,9 +145,22 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er
|
||||
if (_ignoreCallback)
|
||||
return;
|
||||
|
||||
if (error.failed) debug(9, "%s", error.response.c_str());
|
||||
|
||||
bool irrecoverable = error.interrupted || error.failed;
|
||||
if (error.failed) {
|
||||
Common::JSONValue *value = Common::JSON::parse(error.response.c_str());
|
||||
|
||||
// somehow OneDrive returns JSON with '.' in unexpected places, try fixing it
|
||||
if (!value) {
|
||||
Common::String fixedResponse = error.response;
|
||||
for (uint32 i = 0; i < fixedResponse.size(); ++i) {
|
||||
if (fixedResponse[i] == '.')
|
||||
fixedResponse.replace(i, 1, " ");
|
||||
}
|
||||
value = Common::JSON::parse(fixedResponse.c_str());
|
||||
}
|
||||
|
||||
if (value) {
|
||||
if (value->isObject()) {
|
||||
Common::JSONObject object = value->asObject();
|
||||
@ -174,11 +187,13 @@ void SavesSyncRequest::directoryListedErrorCallback(Networking::ErrorResponse er
|
||||
delete value;
|
||||
}
|
||||
|
||||
//Google Drive and Box-related ScummVM-based error
|
||||
//Google Drive, Box and OneDrive-related ScummVM-based error
|
||||
if (error.response.contains("subdirectory not found")) {
|
||||
irrecoverable = false; //base "/ScummVM/" folder not found
|
||||
} else if (error.response.contains("no such file found in its parent directory")) {
|
||||
irrecoverable = false; //"Saves" folder within "/ScummVM/" not found
|
||||
} else if (error.response.contains("itemNotFound") && error.response.contains("Item does not exist")) {
|
||||
irrecoverable = false; //"saves" folder within application folder is not found
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user