CLOUD: Add ListDirectoryStatus struct
It contains flags to indicate whether Request was interrupted or failed, so dependent Requests may see that list is incomplete.
This commit is contained in:
parent
a19fc52c32
commit
aa987e5c52
14 changed files with 155 additions and 101 deletions
|
@ -22,23 +22,32 @@
|
||||||
|
|
||||||
#include "backends/cloud/dropbox/dropboxlistdirectoryrequest.h"
|
#include "backends/cloud/dropbox/dropboxlistdirectoryrequest.h"
|
||||||
#include "backends/cloud/iso8601.h"
|
#include "backends/cloud/iso8601.h"
|
||||||
|
#include "backends/cloud/storage.h"
|
||||||
#include "backends/networking/curl/connectionmanager.h"
|
#include "backends/networking/curl/connectionmanager.h"
|
||||||
#include "backends/networking/curl/curljsonrequest.h"
|
#include "backends/networking/curl/curljsonrequest.h"
|
||||||
|
#include "backends/networking/curl/networkreadstream.h"
|
||||||
#include "common/json.h"
|
#include "common/json.h"
|
||||||
#include "backends/cloud/storage.h"
|
|
||||||
|
|
||||||
namespace Cloud {
|
namespace Cloud {
|
||||||
namespace Dropbox {
|
namespace Dropbox {
|
||||||
|
|
||||||
DropboxListDirectoryRequest::DropboxListDirectoryRequest(Common::String token, Common::String path, Storage::FileArrayCallback cb, bool recursive):
|
DropboxListDirectoryRequest::DropboxListDirectoryRequest(Common::String token, Common::String path, Storage::ListDirectoryCallback cb, bool recursive):
|
||||||
Networking::Request(0), _requestedPath(path), _requestedRecursive(recursive), _filesCallback(cb),
|
Networking::Request(0), _requestedPath(path), _requestedRecursive(recursive), _listDirectoryCallback(cb),
|
||||||
_token(token), _complete(false), _innerRequest(nullptr) {
|
_token(token), _workingRequest(nullptr), _ignoreCallback(false) {
|
||||||
startupWork();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropboxListDirectoryRequest::startupWork() {
|
DropboxListDirectoryRequest::~DropboxListDirectoryRequest() {
|
||||||
|
_ignoreCallback = true;
|
||||||
|
if (_workingRequest) _workingRequest->finish();
|
||||||
|
delete _listDirectoryCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DropboxListDirectoryRequest::start() {
|
||||||
|
_ignoreCallback = true;
|
||||||
|
if (_workingRequest) _workingRequest->finish();
|
||||||
_files.clear();
|
_files.clear();
|
||||||
_complete = false;
|
_ignoreCallback = false;
|
||||||
|
|
||||||
Networking::JsonCallback innerCallback = new Common::Callback<DropboxListDirectoryRequest, Networking::JsonResponse>(this, &DropboxListDirectoryRequest::responseCallback);
|
Networking::JsonCallback innerCallback = new Common::Callback<DropboxListDirectoryRequest, Networking::JsonResponse>(this, &DropboxListDirectoryRequest::responseCallback);
|
||||||
Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, "https://api.dropboxapi.com/2/files/list_folder");
|
Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, "https://api.dropboxapi.com/2/files/list_folder");
|
||||||
|
@ -54,39 +63,50 @@ void DropboxListDirectoryRequest::startupWork() {
|
||||||
Common::JSONValue value(jsonRequestParameters);
|
Common::JSONValue value(jsonRequestParameters);
|
||||||
request->addPostField(Common::JSON::stringify(&value));
|
request->addPostField(Common::JSON::stringify(&value));
|
||||||
|
|
||||||
_innerRequest = ConnMan.addRequest(request);
|
_workingRequest = ConnMan.addRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DropboxListDirectoryRequest::responseCallback(Networking::JsonResponse pair) {
|
void DropboxListDirectoryRequest::responseCallback(Networking::JsonResponse pair) {
|
||||||
|
_workingRequest = nullptr;
|
||||||
|
if (_ignoreCallback) return;
|
||||||
|
|
||||||
|
ListDirectoryStatus status(_files);
|
||||||
|
Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)pair.request;
|
||||||
|
if (rq && rq->getNetworkReadStream())
|
||||||
|
status.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode();
|
||||||
|
|
||||||
Common::JSONValue *json = pair.value;
|
Common::JSONValue *json = pair.value;
|
||||||
if (json) {
|
if (json) {
|
||||||
Common::JSONObject response = json->asObject();
|
Common::JSONObject response = json->asObject();
|
||||||
|
|
||||||
if (response.contains("error") || response.contains("error_summary")) {
|
if (response.contains("error") || response.contains("error_summary")) {
|
||||||
warning("Dropbox returned error: %s", response.getVal("error_summary")->asString().c_str());
|
warning("Dropbox returned error: %s", response.getVal("error_summary")->asString().c_str());
|
||||||
_complete = true;
|
status.failed = true;
|
||||||
|
status.response = json->stringify();
|
||||||
|
finishStatus(status);
|
||||||
delete json;
|
delete json;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: check that all keys exist to avoid segfaults
|
//TODO: check that ALL keys exist AND HAVE RIGHT TYPE to avoid segfaults
|
||||||
//TODO: get more files in the folder to check "has_more" case
|
|
||||||
|
|
||||||
Common::JSONArray items = response.getVal("entries")->asArray();
|
if (response.contains("entries")) {
|
||||||
for (uint32 i = 0; i < items.size(); ++i) {
|
Common::JSONArray items = response.getVal("entries")->asArray();
|
||||||
Common::JSONObject item = items[i]->asObject();
|
for (uint32 i = 0; i < items.size(); ++i) {
|
||||||
Common::String path = item.getVal("path_lower")->asString();
|
Common::JSONObject item = items[i]->asObject();
|
||||||
bool isDirectory = (item.getVal(".tag")->asString() == "folder");
|
Common::String path = item.getVal("path_lower")->asString();
|
||||||
uint32 size = 0, timestamp = 0;
|
bool isDirectory = (item.getVal(".tag")->asString() == "folder");
|
||||||
if (!isDirectory) {
|
uint32 size = 0, timestamp = 0;
|
||||||
size = item.getVal("size")->asIntegerNumber();
|
if (!isDirectory) {
|
||||||
timestamp = ISO8601::convertToTimestamp(item.getVal("server_modified")->asString());
|
size = item.getVal("size")->asIntegerNumber();
|
||||||
|
timestamp = ISO8601::convertToTimestamp(item.getVal("server_modified")->asString());
|
||||||
|
}
|
||||||
|
_files.push_back(StorageFile(path, size, timestamp, isDirectory));
|
||||||
}
|
}
|
||||||
_files.push_back(StorageFile(path, size, timestamp, isDirectory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasMore = response.getVal("has_more")->asBool();
|
bool hasMore = (response.contains("has_more") && response.getVal("has_more")->asBool());
|
||||||
|
|
||||||
if (hasMore) {
|
if (hasMore) {
|
||||||
Networking::JsonCallback innerCallback = new Common::Callback<DropboxListDirectoryRequest, Networking::JsonResponse>(this, &DropboxListDirectoryRequest::responseCallback);
|
Networking::JsonCallback innerCallback = new Common::Callback<DropboxListDirectoryRequest, Networking::JsonResponse>(this, &DropboxListDirectoryRequest::responseCallback);
|
||||||
|
@ -100,40 +120,33 @@ void DropboxListDirectoryRequest::responseCallback(Networking::JsonResponse pair
|
||||||
Common::JSONValue value(jsonRequestParameters);
|
Common::JSONValue value(jsonRequestParameters);
|
||||||
request->addPostField(Common::JSON::stringify(&value));
|
request->addPostField(Common::JSON::stringify(&value));
|
||||||
|
|
||||||
ConnMan.addRequest(request);
|
_workingRequest = ConnMan.addRequest(request);
|
||||||
} else {
|
} else {
|
||||||
_complete = true;
|
finishStatus(status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warning("null, not json");
|
warning("null, not json");
|
||||||
_complete = true;
|
status.failed = true;
|
||||||
|
finishStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete json;
|
delete json;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropboxListDirectoryRequest::handle() {
|
void DropboxListDirectoryRequest::handle() {}
|
||||||
if (_complete) finishFiles(_files);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DropboxListDirectoryRequest::restart() {
|
void DropboxListDirectoryRequest::restart() { start(); }
|
||||||
if (_innerRequest) {
|
|
||||||
//TODO: I'm really not sure some CurlRequest would handle this (it must stop corresponding CURL transfer)
|
|
||||||
_innerRequest->finish(); //may be CANCELED or INTERRUPTED or something?
|
|
||||||
_innerRequest = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
startupWork();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DropboxListDirectoryRequest::finish() {
|
void DropboxListDirectoryRequest::finish() {
|
||||||
Common::Array<StorageFile> files;
|
Common::Array<StorageFile> files;
|
||||||
finishFiles(files);
|
ListDirectoryStatus status(files);
|
||||||
|
status.interrupted = true;
|
||||||
|
finishStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropboxListDirectoryRequest::finishFiles(Common::Array<StorageFile> &files) {
|
void DropboxListDirectoryRequest::finishStatus(ListDirectoryStatus status) {
|
||||||
Request::finish();
|
Request::finish();
|
||||||
if (_filesCallback) (*_filesCallback)(Storage::FileArrayResponse(this, files));
|
if (_listDirectoryCallback) (*_listDirectoryCallback)(Storage::ListDirectoryResponse(this, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Dropbox
|
} // End of namespace Dropbox
|
||||||
|
|
|
@ -35,20 +35,18 @@ class DropboxListDirectoryRequest: public Networking::Request {
|
||||||
Common::String _requestedPath;
|
Common::String _requestedPath;
|
||||||
bool _requestedRecursive;
|
bool _requestedRecursive;
|
||||||
|
|
||||||
Storage::FileArrayCallback _filesCallback;
|
Storage::ListDirectoryCallback _listDirectoryCallback;
|
||||||
Common::String _token;
|
Common::String _token;
|
||||||
bool _complete;
|
|
||||||
Common::Array<StorageFile> _files;
|
Common::Array<StorageFile> _files;
|
||||||
Request *_innerRequest;
|
Request *_workingRequest;
|
||||||
|
bool _ignoreCallback;
|
||||||
|
|
||||||
|
void start();
|
||||||
void responseCallback(Networking::JsonResponse pair);
|
void responseCallback(Networking::JsonResponse pair);
|
||||||
void startupWork();
|
void finishStatus(ListDirectoryStatus status);
|
||||||
|
|
||||||
void finishFiles(Common::Array<StorageFile> &files);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DropboxListDirectoryRequest(Common::String token, Common::String path, Storage::FileArrayCallback cb, bool recursive = false);
|
DropboxListDirectoryRequest(Common::String token, Common::String path, Storage::ListDirectoryCallback cb, bool recursive = false);
|
||||||
virtual ~DropboxListDirectoryRequest() { delete _filesCallback; }
|
virtual ~DropboxListDirectoryRequest();
|
||||||
|
|
||||||
virtual void handle();
|
virtual void handle();
|
||||||
virtual void restart();
|
virtual void restart();
|
||||||
|
|
|
@ -125,7 +125,7 @@ void DropboxStorage::printUploadStatus(UploadResponse pair) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Networking::Request *DropboxStorage::listDirectory(Common::String path, FileArrayCallback outerCallback, bool recursive) {
|
Networking::Request *DropboxStorage::listDirectory(Common::String path, ListDirectoryCallback outerCallback, bool recursive) {
|
||||||
return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, recursive));
|
return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, recursive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,10 +67,10 @@ public:
|
||||||
|
|
||||||
/** Public Cloud API comes down there. */
|
/** Public Cloud API comes down there. */
|
||||||
|
|
||||||
/** Returns Common::Array<StorageFile>. */
|
/** Returns ListDirectoryStatus struct with list of files. */
|
||||||
virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false);
|
virtual Networking::Request *listDirectory(Common::String path, ListDirectoryCallback callback, bool recursive = false);
|
||||||
|
|
||||||
/** Calls the callback when finished. */
|
/** Returns UploadStatus struct with info about uploaded file. */
|
||||||
virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback);
|
virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback);
|
||||||
virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback);
|
virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback);
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ DropboxUploadRequest::~DropboxUploadRequest() {
|
||||||
delete _uploadCallback;
|
delete _uploadCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DropboxUploadRequest::start() {
|
void DropboxUploadRequest::start() {
|
||||||
_ignoreCallback = true;
|
_ignoreCallback = true;
|
||||||
if (_workingRequest) _workingRequest->finish();
|
if (_workingRequest) _workingRequest->finish();
|
||||||
|
|
|
@ -50,15 +50,21 @@ void FolderDownloadRequest::start() {
|
||||||
//list directory first
|
//list directory first
|
||||||
_workingRequest = _storage->listDirectory(
|
_workingRequest = _storage->listDirectory(
|
||||||
_remoteDirectoryPath,
|
_remoteDirectoryPath,
|
||||||
new Common::Callback<FolderDownloadRequest, Storage::FileArrayResponse>(this, &FolderDownloadRequest::directoryListedCallback),
|
new Common::Callback<FolderDownloadRequest, Storage::ListDirectoryResponse>(this, &FolderDownloadRequest::directoryListedCallback),
|
||||||
_recursive
|
_recursive
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderDownloadRequest::directoryListedCallback(Storage::FileArrayResponse pair) {
|
void FolderDownloadRequest::directoryListedCallback(Storage::ListDirectoryResponse pair) {
|
||||||
if (_ignoreCallback) return;
|
if (_ignoreCallback) return;
|
||||||
//TODO: somehow ListDirectory requests must indicate that file array is incomplete
|
|
||||||
_files = pair.value;
|
ListDirectoryStatus status = pair.value;
|
||||||
|
if (status.failed || status.interrupted) {
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_files = pair.value.files;
|
||||||
downloadNextFile();
|
downloadNextFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "backends/networking/curl/request.h"
|
#include "backends/networking/curl/request.h"
|
||||||
#include "backends/networking/curl/networkreadstream.h"
|
#include "backends/networking/curl/networkreadstream.h"
|
||||||
#include "backends/cloud/storage.h"
|
#include "backends/cloud/storage.h"
|
||||||
#include "common/file.h"
|
|
||||||
|
|
||||||
namespace Cloud {
|
namespace Cloud {
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ class FolderDownloadRequest: public Networking::Request {
|
||||||
bool _ignoreCallback;
|
bool _ignoreCallback;
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void directoryListedCallback(Storage::FileArrayResponse pair);
|
void directoryListedCallback(Storage::ListDirectoryResponse pair);
|
||||||
void fileDownloadedCallback(Storage::BoolResponse pair);
|
void fileDownloadedCallback(Storage::BoolResponse pair);
|
||||||
void downloadNextFile();
|
void downloadNextFile();
|
||||||
void finishFiles(Common::Array<StorageFile> &files);
|
void finishFiles(Common::Array<StorageFile> &files);
|
||||||
|
|
|
@ -25,18 +25,25 @@
|
||||||
#include "backends/cloud/onedrive/onedrivetokenrefresher.h"
|
#include "backends/cloud/onedrive/onedrivetokenrefresher.h"
|
||||||
#include "backends/cloud/iso8601.h"
|
#include "backends/cloud/iso8601.h"
|
||||||
#include "backends/networking/curl/connectionmanager.h"
|
#include "backends/networking/curl/connectionmanager.h"
|
||||||
|
#include "backends/networking/curl/networkreadstream.h"
|
||||||
#include "common/json.h"
|
#include "common/json.h"
|
||||||
|
|
||||||
namespace Cloud {
|
namespace Cloud {
|
||||||
namespace OneDrive {
|
namespace OneDrive {
|
||||||
|
|
||||||
OneDriveListDirectoryRequest::OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::FileArrayCallback cb, bool recursive):
|
OneDriveListDirectoryRequest::OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::ListDirectoryCallback cb, bool recursive):
|
||||||
Networking::Request(0),
|
Networking::Request(0),
|
||||||
_requestedPath(path), _requestedRecursive(recursive), _storage(storage), _filesCallback(cb),
|
_requestedPath(path), _requestedRecursive(recursive), _storage(storage), _listDirectoryCallback(cb),
|
||||||
_workingRequest(nullptr), _ignoreCallback(false) {
|
_workingRequest(nullptr), _ignoreCallback(false) {
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OneDriveListDirectoryRequest::~OneDriveListDirectoryRequest() {
|
||||||
|
_ignoreCallback = true;
|
||||||
|
if (_workingRequest) _workingRequest->finish();
|
||||||
|
delete _listDirectoryCallback;
|
||||||
|
}
|
||||||
|
|
||||||
void OneDriveListDirectoryRequest::start() {
|
void OneDriveListDirectoryRequest::start() {
|
||||||
//cleanup
|
//cleanup
|
||||||
_ignoreCallback = true;
|
_ignoreCallback = true;
|
||||||
|
@ -48,12 +55,12 @@ void OneDriveListDirectoryRequest::start() {
|
||||||
_ignoreCallback = false;
|
_ignoreCallback = false;
|
||||||
|
|
||||||
_directoriesQueue.push_back(_requestedPath);
|
_directoriesQueue.push_back(_requestedPath);
|
||||||
listNextDirectory();
|
listNextDirectory(_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OneDriveListDirectoryRequest::listNextDirectory() {
|
void OneDriveListDirectoryRequest::listNextDirectory(ListDirectoryStatus status) {
|
||||||
if (_directoriesQueue.empty()) {
|
if (_directoriesQueue.empty()) {
|
||||||
finishFiles(_files);
|
finishStatus(status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +83,8 @@ void OneDriveListDirectoryRequest::makeRequest(Common::String url) {
|
||||||
_workingRequest = ConnMan.addRequest(request);
|
_workingRequest = ConnMan.addRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonResponse pair) {
|
void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonResponse pair) {
|
||||||
|
_workingRequest = nullptr;
|
||||||
Common::JSONValue *json = pair.value;
|
Common::JSONValue *json = pair.value;
|
||||||
|
|
||||||
if (_ignoreCallback) {
|
if (_ignoreCallback) {
|
||||||
|
@ -84,26 +92,29 @@ void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonRespo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListDirectoryStatus status(_files);
|
||||||
|
Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)pair.request;
|
||||||
|
if (rq && rq->getNetworkReadStream())
|
||||||
|
status.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode();
|
||||||
|
|
||||||
if (!json) {
|
if (!json) {
|
||||||
finish();
|
status.failed = true;
|
||||||
|
finishStatus(status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::JSONObject response = json->asObject();
|
Common::JSONObject response = json->asObject();
|
||||||
|
|
||||||
//TODO: check that all keys exist to avoid segfaults
|
//TODO: check that ALL keys exist AND HAVE RIGHT TYPE to avoid segfaults
|
||||||
|
|
||||||
Common::JSONArray items = response.getVal("value")->asArray();
|
Common::JSONArray items = response.getVal("value")->asArray();
|
||||||
for (uint32 i = 0; i < items.size(); ++i) {
|
for (uint32 i = 0; i < items.size(); ++i) {
|
||||||
Common::JSONObject item = items[i]->asObject();
|
Common::JSONObject item = items[i]->asObject();
|
||||||
|
|
||||||
Common::String path = _currentDirectory + item.getVal("name")->asString();
|
Common::String path = _currentDirectory + item.getVal("name")->asString();
|
||||||
bool isDirectory = item.contains("folder");
|
bool isDirectory = item.contains("folder");
|
||||||
uint32 size = 0, timestamp = 0;
|
uint32 size = item.getVal("size")->asIntegerNumber();
|
||||||
//if (!isDirectory) {
|
uint32 timestamp = ISO8601::convertToTimestamp(item.getVal("lastModifiedDateTime")->asString());
|
||||||
size = item.getVal("size")->asNumber();
|
|
||||||
timestamp = ISO8601::convertToTimestamp(item.getVal("lastModifiedDateTime")->asString());
|
|
||||||
//}
|
|
||||||
|
|
||||||
StorageFile file(path, size, timestamp, isDirectory);
|
StorageFile file(path, size, timestamp, isDirectory);
|
||||||
_files.push_back(file);
|
_files.push_back(file);
|
||||||
|
@ -116,21 +127,22 @@ void OneDriveListDirectoryRequest::listedDirectoryCallback(Networking::JsonRespo
|
||||||
if (hasMore) {
|
if (hasMore) {
|
||||||
makeRequest(response.getVal("@odata.nextLink")->asString());
|
makeRequest(response.getVal("@odata.nextLink")->asString());
|
||||||
} else {
|
} else {
|
||||||
listNextDirectory();
|
listNextDirectory(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete json;
|
delete json;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OneDriveListDirectoryRequest::finish() {
|
void OneDriveListDirectoryRequest::finish() {
|
||||||
//TODO: indicate it's interrupted
|
|
||||||
Common::Array<StorageFile> files;
|
Common::Array<StorageFile> files;
|
||||||
finishFiles(files);
|
ListDirectoryStatus status(files);
|
||||||
|
status.interrupted = true;
|
||||||
|
finishStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OneDriveListDirectoryRequest::finishFiles(Common::Array<StorageFile> &files) {
|
void OneDriveListDirectoryRequest::finishStatus(ListDirectoryStatus status) {
|
||||||
Request::finish();
|
Request::finish();
|
||||||
if (_filesCallback) (*_filesCallback)(Storage::FileArrayResponse(this, files));
|
if (_listDirectoryCallback) (*_listDirectoryCallback)(Storage::ListDirectoryResponse(this, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace OneDrive
|
} // End of namespace OneDrive
|
||||||
|
|
|
@ -37,7 +37,7 @@ class OneDriveListDirectoryRequest: public Networking::Request {
|
||||||
Common::String _requestedPath;
|
Common::String _requestedPath;
|
||||||
bool _requestedRecursive;
|
bool _requestedRecursive;
|
||||||
OneDriveStorage *_storage;
|
OneDriveStorage *_storage;
|
||||||
Storage::FileArrayCallback _filesCallback;
|
Storage::ListDirectoryCallback _listDirectoryCallback;
|
||||||
Common::Array<StorageFile> _files;
|
Common::Array<StorageFile> _files;
|
||||||
Common::Array<Common::String> _directoriesQueue;
|
Common::Array<Common::String> _directoriesQueue;
|
||||||
Common::String _currentDirectory;
|
Common::String _currentDirectory;
|
||||||
|
@ -45,13 +45,13 @@ class OneDriveListDirectoryRequest: public Networking::Request {
|
||||||
bool _ignoreCallback;
|
bool _ignoreCallback;
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void listNextDirectory();
|
void listNextDirectory(ListDirectoryStatus status);
|
||||||
void listedDirectoryCallback(Networking::JsonResponse pair);
|
void listedDirectoryCallback(Networking::JsonResponse pair);
|
||||||
void makeRequest(Common::String url);
|
void makeRequest(Common::String url);
|
||||||
void finishFiles(Common::Array<StorageFile> &files);
|
void finishStatus(ListDirectoryStatus status);
|
||||||
public:
|
public:
|
||||||
OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::FileArrayCallback cb, bool recursive = false);
|
OneDriveListDirectoryRequest(OneDriveStorage *storage, Common::String path, Storage::ListDirectoryCallback cb, bool recursive = false);
|
||||||
virtual ~OneDriveListDirectoryRequest() { delete _filesCallback; }
|
virtual ~OneDriveListDirectoryRequest();
|
||||||
|
|
||||||
virtual void handle() {}
|
virtual void handle() {}
|
||||||
virtual void restart() { start(); }
|
virtual void restart() { start(); }
|
||||||
|
|
|
@ -163,7 +163,7 @@ void OneDriveStorage::fileInfoCallback(Networking::NetworkReadStreamCallback out
|
||||||
delete pair.value;
|
delete pair.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Networking::Request *OneDriveStorage::listDirectory(Common::String path, FileArrayCallback callback, bool recursive) {
|
Networking::Request *OneDriveStorage::listDirectory(Common::String path, ListDirectoryCallback callback, bool recursive) {
|
||||||
return ConnMan.addRequest(new OneDriveListDirectoryRequest(this, path, callback, recursive));
|
return ConnMan.addRequest(new OneDriveListDirectoryRequest(this, path, callback, recursive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,10 @@ public:
|
||||||
|
|
||||||
/** Public Cloud API comes down there. */
|
/** Public Cloud API comes down there. */
|
||||||
|
|
||||||
/** Returns Common::Array<StorageFile>. */
|
/** Returns ListDirectoryStatus struct with list of files. */
|
||||||
virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false);
|
virtual Networking::Request *listDirectory(Common::String path, ListDirectoryCallback callback, bool recursive = false);
|
||||||
|
|
||||||
/** Calls the callback when finished. */
|
/** Returns UploadStatus struct with info about uploaded file. */
|
||||||
virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) { return nullptr; } //TODO
|
virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) { return nullptr; } //TODO
|
||||||
virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback) { return nullptr; }
|
virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback) { return nullptr; }
|
||||||
|
|
||||||
|
|
|
@ -55,17 +55,22 @@ void SavesSyncRequest::start() {
|
||||||
loadTimestamps();
|
loadTimestamps();
|
||||||
|
|
||||||
//list saves directory
|
//list saves directory
|
||||||
_workingRequest = _storage->listDirectory("saves", new Common::Callback<SavesSyncRequest, Storage::FileArrayResponse>(this, &SavesSyncRequest::directoryListedCallback));
|
_workingRequest = _storage->listDirectory("saves", new Common::Callback<SavesSyncRequest, Storage::ListDirectoryResponse>(this, &SavesSyncRequest::directoryListedCallback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SavesSyncRequest::directoryListedCallback(Storage::FileArrayResponse pair) {
|
void SavesSyncRequest::directoryListedCallback(Storage::ListDirectoryResponse pair) {
|
||||||
if (_ignoreCallback) return;
|
if (_ignoreCallback) return;
|
||||||
//TODO: somehow ListDirectory requests must indicate that file array is incomplete
|
|
||||||
|
ListDirectoryStatus status = pair.value;
|
||||||
|
if (status.interrupted || status.failed) {
|
||||||
|
finishBool(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const uint32 INVALID_TIMESTAMP = UINT_MAX;
|
const uint32 INVALID_TIMESTAMP = UINT_MAX;
|
||||||
|
|
||||||
//determine which files to download and which files to upload
|
//determine which files to download and which files to upload
|
||||||
Common::Array<StorageFile> &remoteFiles = pair.value;
|
Common::Array<StorageFile> &remoteFiles = status.files;
|
||||||
for (uint32 i = 0; i < remoteFiles.size(); ++i) {
|
for (uint32 i = 0; i < remoteFiles.size(); ++i) {
|
||||||
StorageFile &file = remoteFiles[i];
|
StorageFile &file = remoteFiles[i];
|
||||||
if (file.isDirectory()) continue;
|
if (file.isDirectory()) continue;
|
||||||
|
|
|
@ -42,7 +42,7 @@ class SavesSyncRequest: public Networking::Request {
|
||||||
bool _ignoreCallback;
|
bool _ignoreCallback;
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void directoryListedCallback(Storage::FileArrayResponse pair);
|
void directoryListedCallback(Storage::ListDirectoryResponse pair);
|
||||||
void fileDownloadedCallback(Storage::BoolResponse pair);
|
void fileDownloadedCallback(Storage::BoolResponse pair);
|
||||||
void fileUploadedCallback(Storage::UploadResponse pair);
|
void fileUploadedCallback(Storage::UploadResponse pair);
|
||||||
void downloadNextFile();
|
void downloadNextFile();
|
||||||
|
|
|
@ -54,17 +54,39 @@ struct UploadStatus {
|
||||||
interrupted(interrupt), failed(failure), file(f), response(resp), httpResponseCode(code) {}
|
interrupted(interrupt), failed(failure), file(f), response(resp), httpResponseCode(code) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Struct to represent upload() resulting status. */
|
||||||
|
struct ListDirectoryStatus {
|
||||||
|
/** true if Request was interrupted (finished by user with finish()) */
|
||||||
|
bool interrupted;
|
||||||
|
/** true if Request has failed (bad server response or some other error occurred) */
|
||||||
|
bool failed;
|
||||||
|
/** Contains listed files (might be incomplete if failed or interrupted) */
|
||||||
|
Common::Array<StorageFile> &files;
|
||||||
|
/** Server's original response (empty if not failed) */
|
||||||
|
Common::String response;
|
||||||
|
/** Server's HTTP response code. */
|
||||||
|
long httpResponseCode;
|
||||||
|
|
||||||
|
ListDirectoryStatus(Common::Array<StorageFile> &f) :
|
||||||
|
interrupted(false), failed(false), files(f), response(), httpResponseCode(-1) {}
|
||||||
|
|
||||||
|
ListDirectoryStatus(bool interrupt, bool failure, Common::Array<StorageFile> &f, Common::String resp, long code) :
|
||||||
|
interrupted(interrupt), failed(failure), files(f), response(resp), httpResponseCode(code) {}
|
||||||
|
};
|
||||||
|
|
||||||
class Storage {
|
class Storage {
|
||||||
public:
|
public:
|
||||||
typedef Networking::Response<Common::Array<StorageFile>&> FileArrayResponse;
|
typedef Networking::Response<Common::Array<StorageFile>&> FileArrayResponse;
|
||||||
typedef Networking::Response<StorageInfo> StorageInfoResponse;
|
typedef Networking::Response<StorageInfo> StorageInfoResponse;
|
||||||
typedef Networking::Response<bool> BoolResponse;
|
typedef Networking::Response<bool> BoolResponse;
|
||||||
typedef Networking::Response<UploadStatus> UploadResponse;
|
typedef Networking::Response<UploadStatus> UploadResponse;
|
||||||
|
typedef Networking::Response<ListDirectoryStatus> ListDirectoryResponse;
|
||||||
|
|
||||||
typedef Common::BaseCallback<FileArrayResponse> *FileArrayCallback;
|
typedef Common::BaseCallback<FileArrayResponse> *FileArrayCallback;
|
||||||
typedef Common::BaseCallback<StorageInfoResponse> *StorageInfoCallback;
|
typedef Common::BaseCallback<StorageInfoResponse> *StorageInfoCallback;
|
||||||
typedef Common::BaseCallback<BoolResponse> *BoolCallback;
|
typedef Common::BaseCallback<BoolResponse> *BoolCallback;
|
||||||
typedef Common::BaseCallback<UploadResponse> *UploadCallback;
|
typedef Common::BaseCallback<UploadResponse> *UploadCallback;
|
||||||
|
typedef Common::BaseCallback<ListDirectoryResponse> *ListDirectoryCallback;
|
||||||
|
|
||||||
Storage() {}
|
Storage() {}
|
||||||
virtual ~Storage() {}
|
virtual ~Storage() {}
|
||||||
|
@ -90,10 +112,10 @@ public:
|
||||||
* a callback, which is called, when request is complete.
|
* a callback, which is called, when request is complete.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Returns Common::Array<StorageFile>. */
|
/** Returns ListDirectoryStatus struct with list of files. */
|
||||||
virtual Networking::Request *listDirectory(Common::String path, FileArrayCallback callback, bool recursive = false) = 0;
|
virtual Networking::Request *listDirectory(Common::String path, ListDirectoryCallback callback, bool recursive = false) = 0;
|
||||||
|
|
||||||
/** Calls the callback when finished. */
|
/** Returns UploadStatus struct with info about uploaded file. */
|
||||||
virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) = 0;
|
virtual Networking::Request *upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) = 0;
|
||||||
virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback) = 0;
|
virtual Networking::Request *upload(Common::String remotePath, Common::String localPath, UploadCallback callback) = 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue