From b9e3730ccd9a76101ef0cb8812f41c371a24d0d6 Mon Sep 17 00:00:00 2001 From: Alexander Tkachev Date: Mon, 30 May 2016 13:35:53 +0600 Subject: CLOUD: Add UploadStatus struct It contains not just "success" flag, but also "file" struct, so the caller can find out some information about uploaded file - like timestamp. --- .../cloud/dropbox/dropboxlistdirectoryrequest.cpp | 4 +- backends/cloud/dropbox/dropboxstorage.cpp | 50 ++++++++++++++++------ backends/cloud/dropbox/dropboxstorage.h | 4 +- backends/cloud/dropbox/dropboxuploadrequest.cpp | 49 +++++++++++++++------ backends/cloud/dropbox/dropboxuploadrequest.h | 6 +-- 5 files changed, 82 insertions(+), 31 deletions(-) (limited to 'backends/cloud/dropbox') diff --git a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp index 6ea90c150d..89e92facb8 100644 --- a/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp +++ b/backends/cloud/dropbox/dropboxlistdirectoryrequest.cpp @@ -76,11 +76,11 @@ void DropboxListDirectoryRequest::responseCallback(Networking::JsonResponse pair Common::JSONArray items = response.getVal("entries")->asArray(); for (uint32 i = 0; i < items.size(); ++i) { Common::JSONObject item = items[i]->asObject(); - Common::String path = item.getVal("path_lower")->asString(); + Common::String path = item.getVal("path_lower")->asString(); bool isDirectory = (item.getVal(".tag")->asString() == "folder"); uint32 size = 0, timestamp = 0; if (!isDirectory) { - size = item.getVal("size")->asNumber(); + size = item.getVal("size")->asIntegerNumber(); timestamp = ISO8601::convertToTimestamp(item.getVal("server_modified")->asString()); } _files.push_back(StorageFile(path, size, timestamp, isDirectory)); diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp index 1220a99035..1f983cec67 100644 --- a/backends/cloud/dropbox/dropboxstorage.cpp +++ b/backends/cloud/dropbox/dropboxstorage.cpp @@ -104,14 +104,46 @@ void DropboxStorage::printBool(BoolResponse pair) { debug("bool: %s", (pair.value?"true":"false")); } +void DropboxStorage::printUploadStatus(UploadResponse pair) { + UploadStatus status = pair.value; + if (status.interrupted) { + debug("upload interrupted by user"); + return; + } + if (status.failed) { + debug("upload failed with following response:"); + debug("%s", status.response.c_str()); + return; + } + debug("upload HTTP response code = %ld", status.httpResponseCode); + if (!status.failed) { + debug("uploaded file info:"); + debug("path: %s", status.file.path().c_str()); + debug("size: %u", status.file.size()); + debug("timestamp: %u", status.file.timestamp()); + } +} + Networking::Request *DropboxStorage::listDirectory(Common::String path, FileArrayCallback outerCallback, bool recursive) { return ConnMan.addRequest(new DropboxListDirectoryRequest(_token, path, outerCallback, recursive)); } -Networking::Request *DropboxStorage::upload(Common::String path, Common::SeekableReadStream *contents, BoolCallback callback) { +Networking::Request *DropboxStorage::upload(Common::String path, Common::SeekableReadStream *contents, UploadCallback callback) { return ConnMan.addRequest(new DropboxUploadRequest(_token, path, contents, callback)); } +Networking::Request *DropboxStorage::upload(Common::String remotePath, Common::String localPath, UploadCallback callback) { + Common::File *f = new Common::File(); + if (!f->open(localPath)) { + warning("DropboxStorage: unable to open file to upload from"); + UploadStatus status(false, true, StorageFile(), "", -1); + if (callback) (*callback)(UploadResponse(nullptr, status)); + delete f; + return nullptr; + } + return upload(remotePath, f, callback); +} + Networking::Request *DropboxStorage::streamFile(Common::String path, Networking::NetworkReadStreamCallback callback) { Common::JSONObject jsonRequestParameters; jsonRequestParameters.setVal("path", new Common::JSONValue(path)); @@ -155,13 +187,7 @@ Networking::Request *DropboxStorage::syncSaves(BoolCallback callback) { false ); */ - Common::File *file = new Common::File(); - if (!file->open("final.bmp")) { - warning("no such file"); - delete file; - return nullptr; - } - return upload("/remote/test3.bmp", file, new Common::Callback(this, &DropboxStorage::printBool)); + return upload("/remote/test4.bmp", "final.bmp", new Common::Callback(this, &DropboxStorage::printUploadStatus)); } Networking::Request *DropboxStorage::info(StorageInfoCallback outerCallback) { @@ -186,13 +212,13 @@ void DropboxStorage::infoInnerCallback(StorageInfoCallback outerCallback, Networ if (outerCallback) { //Dropbox documentation states there is no errors for this API method Common::JSONObject info = json->asObject(); - Common::String uid = Common::String::format("%d", (int)info.getVal("uid")->asNumber()); + Common::String uid = Common::String::format("%d", (int)info.getVal("uid")->asIntegerNumber()); Common::String name = info.getVal("display_name")->asString(); Common::String email = info.getVal("email")->asString(); Common::JSONObject quota = info.getVal("quota_info")->asObject(); - uint32 quotaNormal = quota.getVal("normal")->asNumber(); - uint32 quotaShared = quota.getVal("shared")->asNumber(); - uint32 quotaAllocated = quota.getVal("quota")->asNumber(); + uint32 quotaNormal = quota.getVal("normal")->asIntegerNumber(); + uint32 quotaShared = quota.getVal("shared")->asIntegerNumber(); + uint32 quotaAllocated = quota.getVal("quota")->asIntegerNumber(); (*outerCallback)(StorageInfoResponse(nullptr, StorageInfo(uid, name, email, quotaNormal+quotaShared, quotaAllocated))); delete outerCallback; } diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h index cc515fef41..ca285802a4 100644 --- a/backends/cloud/dropbox/dropboxstorage.h +++ b/backends/cloud/dropbox/dropboxstorage.h @@ -47,6 +47,7 @@ class DropboxStorage: public Cloud::Storage { void printFiles(FileArrayResponse pair); void printBool(BoolResponse pair); + void printUploadStatus(UploadResponse pair); public: virtual ~DropboxStorage(); @@ -70,7 +71,8 @@ public: 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::SeekableReadStream *contents, BoolCallback 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); /** Returns pointer to Networking::NetworkReadStream. */ virtual Networking::Request *streamFile(Common::String path, Networking::NetworkReadStreamCallback callback); diff --git a/backends/cloud/dropbox/dropboxuploadrequest.cpp b/backends/cloud/dropbox/dropboxuploadrequest.cpp index d068078502..18e1173eef 100644 --- a/backends/cloud/dropbox/dropboxuploadrequest.cpp +++ b/backends/cloud/dropbox/dropboxuploadrequest.cpp @@ -21,17 +21,19 @@ */ #include "backends/cloud/dropbox/dropboxuploadrequest.h" +#include "backends/cloud/iso8601.h" #include "backends/cloud/storage.h" #include "backends/networking/curl/connectionmanager.h" #include "backends/networking/curl/curljsonrequest.h" +#include "backends/networking/curl/networkreadstream.h" #include "common/json.h" #include "common/debug.h" namespace Cloud { namespace Dropbox { -DropboxUploadRequest::DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::BoolCallback callback): - Networking::Request(0), _token(token), _savePath(path), _contentsStream(contents), _boolCallback(callback), +DropboxUploadRequest::DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback): + Networking::Request(0), _token(token), _savePath(path), _contentsStream(contents), _uploadCallback(callback), _workingRequest(nullptr), _ignoreCallback(false) { start(); } @@ -40,7 +42,7 @@ DropboxUploadRequest::~DropboxUploadRequest() { _ignoreCallback = true; if (_workingRequest) _workingRequest->finish(); delete _contentsStream; - delete _boolCallback; + delete _uploadCallback; } @@ -105,6 +107,11 @@ void DropboxUploadRequest::partUploadedCallback(Networking::JsonResponse pair) { if (_ignoreCallback) return; _workingRequest = nullptr; + UploadStatus status; + Networking::CurlJsonRequest *rq = (Networking::CurlJsonRequest *)pair.request; + if (rq && rq->getNetworkReadStream()) + status.httpResponseCode = rq->getNetworkReadStream()->httpResponseCode(); + Common::JSONValue *json = pair.value; if (json) { bool needsFinishRequest = false; @@ -117,13 +124,19 @@ void DropboxUploadRequest::partUploadedCallback(Networking::JsonResponse pair) { if (response.contains("error") || response.contains("error_summary")) { warning("Dropbox returned error: %s", response.getVal("error_summary")->asString().c_str()); delete json; - finish(); + status.failed = true; + status.response = json->stringify(true); + finishUpload(status); return; } if (response.contains("server_modified")) { //finished - finishBool(true); + Common::String path = response.getVal("path_lower")->asString(); + uint32 size = response.getVal("size")->asIntegerNumber(); + uint32 timestamp = ISO8601::convertToTimestamp(response.getVal("server_modified")->asString()); + status.file = StorageFile(path, size, timestamp, false); + finishUpload(status); return; } @@ -136,13 +149,19 @@ void DropboxUploadRequest::partUploadedCallback(Networking::JsonResponse pair) { } } - if (!needsFinishRequest && (_contentsStream->eos() || _contentsStream->pos() >= _contentsStream->size() - 1)) - finishBool(true); - else + if (!needsFinishRequest && (_contentsStream->eos() || _contentsStream->pos() >= _contentsStream->size() - 1)) { + if (status.file.name() == "") { + status.file = StorageFile(_savePath, 0, 0, false); + warning("no file info to put into status"); + } + finishUpload(status); + } else { uploadNextPart(); + } } else { - warning("null, not json"); - finish(); + warning("null, not json"); + status.failed = true; + finishUpload(status); } delete json; @@ -152,11 +171,15 @@ void DropboxUploadRequest::handle() {} void DropboxUploadRequest::restart() { start(); } -void DropboxUploadRequest::finish() { finishBool(false); } +void DropboxUploadRequest::finish() { + UploadStatus status; + status.interrupted = true; + finishUpload(status); +} -void DropboxUploadRequest::finishBool(bool success) { +void DropboxUploadRequest::finishUpload(UploadStatus status) { Request::finish(); - if (_boolCallback) (*_boolCallback)(Storage::BoolResponse(this, success)); + if (_uploadCallback) (*_uploadCallback)(Storage::UploadResponse(this, status)); } } // End of namespace Dropbox diff --git a/backends/cloud/dropbox/dropboxuploadrequest.h b/backends/cloud/dropbox/dropboxuploadrequest.h index a7d7a6c581..9b68995969 100644 --- a/backends/cloud/dropbox/dropboxuploadrequest.h +++ b/backends/cloud/dropbox/dropboxuploadrequest.h @@ -35,7 +35,7 @@ class DropboxUploadRequest: public Networking::Request { Common::String _token; Common::String _savePath; Common::SeekableReadStream *_contentsStream; - Storage::BoolCallback _boolCallback; + Storage::UploadCallback _uploadCallback; Request *_workingRequest; bool _ignoreCallback; Common::String _sessionId; @@ -43,10 +43,10 @@ class DropboxUploadRequest: public Networking::Request { void start(); void uploadNextPart(); void partUploadedCallback(Networking::JsonResponse pair); - void finishBool(bool success); + void finishUpload(UploadStatus status); public: - DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::BoolCallback callback); + DropboxUploadRequest(Common::String token, Common::String path, Common::SeekableReadStream *contents, Storage::UploadCallback callback); virtual ~DropboxUploadRequest(); virtual void handle(); -- cgit v1.2.3